Skip to content

Commit

Permalink
Showing 4 changed files with 53 additions and 0 deletions.
11 changes: 11 additions & 0 deletions spec/compiler/codegen/named_tuple_spec.cr
Original file line number Diff line number Diff line change
@@ -277,4 +277,15 @@ describe "Code gen: named tuple" do
end
)).to_i.should eq(42)
end

it "provides T as a named tuple literal" do
run(%(
struct NamedTuple
def self.foo
{{ T.class_name }}
end
end
NamedTuple(x: Nil, y: Int32).foo
)).to_string.should eq("NamedTupleLiteral")
end
end
11 changes: 11 additions & 0 deletions spec/compiler/codegen/tuple_spec.cr
Original file line number Diff line number Diff line change
@@ -294,4 +294,15 @@ describe "Code gen: tuple" do
end
)).to_i.should eq(42)
end

it "provides T as a tuple literal" do
run(%(
struct Tuple
def self.foo
{{ T.class_name }}
end
end
Tuple(Nil, Int32).foo
)).to_string.should eq("TupleLiteral")
end
end
11 changes: 11 additions & 0 deletions spec/compiler/codegen/union_type_spec.cr
Original file line number Diff line number Diff line change
@@ -192,4 +192,15 @@ describe "Code gen: union type" do
)).to_string
(str == "(Int32 | Float64)" || str == "(Float64 | Int32)").should be_true
end

it "provides T as a tuple literal" do
run(%(
struct Union
def self.foo
{{ T.class_name }}
end
end
Union(Nil, Int32).foo
)).to_string.should eq("TupleLiteral")
end
end
20 changes: 20 additions & 0 deletions src/compiler/crystal/macros/macros.cr
Original file line number Diff line number Diff line change
@@ -505,6 +505,26 @@ module Crystal
when Const
matched_type.value
when Type
# The T of a tuple, named tuple or union produce tuple literals
# or named tuple literals. The compiler has them as a type
# (a tuple type, or a named tuple type) but the user should see
# them as literals, and having them as a type doesn't add
# any useful information.
if node.single?("T")
instance_type = @type_lookup.instance_type
case instance_type
when TupleInstanceType
return TupleLiteral.map(instance_type.tuple_types) { |t| TypeNode.new(t) }
when NamedTupleInstanceType
entries = instance_type.entries.map do |entry|
NamedTupleLiteral::Entry.new(entry.name, TypeNode.new(entry.type))
end
return NamedTupleLiteral.new(entries)
when UnionType
return TupleLiteral.map(instance_type.union_types) { |t| TypeNode.new(t) }
end
end

TypeNode.new(matched_type)
when ASTNode
matched_type

0 comments on commit c983908

Please sign in to comment.