Skip to content

Commit

Permalink
Showing 2 changed files with 34 additions and 7 deletions.
17 changes: 17 additions & 0 deletions spec/compiler/type_inference/tuple_spec.cr
Original file line number Diff line number Diff line change
@@ -191,4 +191,21 @@ describe "Type inference: tuples" do
a[0]
)) { tuple_of [types["Foo"].virtual_type!, types["Foo"].virtual_type!] }
end

it "can iterate T" do
assert_type(%(
struct Tuple
def self.types
{% begin %}
{
{% for type in T %}
{{type}},
{% end %}
}
{% end %}
end
end
Tuple(Int32, String).types
)) { tuple_of([int32.metaclass, string.metaclass]) }
end
end
24 changes: 17 additions & 7 deletions src/compiler/crystal/macros/macros.cr
Original file line number Diff line number Diff line change
@@ -318,12 +318,18 @@ module Crystal
@vars.delete index_var.name if index_var
when TypeNode
type = exp.type
unless type.is_a?(NamedTupleInstanceType)
exp.raise "can't interate TypeNode of type #{type}, only named tuple types"
end

visit_macro_for_hash_like(node, exp, type.entries) do |entry|
{MacroId.new(entry.name), TypeNode.new(entry.type)}
case type
when TupleInstanceType
visit_macro_for_array_like(node, exp, type.tuple_types) do |type|
TypeNode.new(type)
end
when NamedTupleInstanceType
visit_macro_for_hash_like(node, exp, type.entries) do |entry|
{MacroId.new(entry.name), TypeNode.new(entry.type)}
end
else
exp.raise "can't interate TypeNode of type #{type}, only tuple or named tuple types"
end
else
node.exp.raise "for expression must be an array, hash or tuple literal, not #{exp.class_desc}:\n\n#{exp}"
@@ -333,11 +339,15 @@ module Crystal
end

def visit_macro_for_array_like(node, exp)
visit_macro_for_array_like node, exp, exp.elements, &.itself
end

def visit_macro_for_array_like(node, exp, entries)
element_var = node.vars[0]
index_var = node.vars[1]?

exp.elements.each_with_index do |element, index|
@vars[element_var.name] = element
entries.each_with_index do |element, index|
@vars[element_var.name] = yield element
if index_var
@vars[index_var.name] = NumberLiteral.new(index)
end

0 comments on commit 86a90e1

Please sign in to comment.