Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix global Path lookup inside macro when def has free variables
Browse files Browse the repository at this point in the history
HertzDevil committed Dec 8, 2023
1 parent 4925cad commit b8c9f95
Showing 3 changed files with 18 additions and 1 deletion.
15 changes: 15 additions & 0 deletions spec/compiler/semantic/macro_spec.cr
Original file line number Diff line number Diff line change
@@ -1104,6 +1104,21 @@ describe "Semantic: macro" do
CRYSTAL
end

it "finds type for global path shared with free var" do
assert_type(<<-CRYSTAL) { int32 }
module T
end
module Foo
def self.foo(foo : T) forall T
{{ ::T.module? ? 1 : 'a' }}
end
end
Foo.foo("")
CRYSTAL
end

it "gets named arguments in double splat" do
assert_type(<<-CRYSTAL) { named_tuple_of({"x": string, "y": bool}) }
macro foo(**options)
2 changes: 1 addition & 1 deletion src/compiler/crystal/macros/interpreter.cr
Original file line number Diff line number Diff line change
@@ -418,7 +418,7 @@ module Crystal
end

def resolve?(node : Path)
if node.names.size == 1 && (match = @free_vars.try &.[node.names.first]?)
if (single_name = node.single_name?) && (match = @free_vars.try &.[single_name]?)
matched_type = match
else
matched_type = @path_lookup.lookup_path(node)
2 changes: 2 additions & 0 deletions src/compiler/crystal/macros/types.cr
Original file line number Diff line number Diff line change
@@ -129,6 +129,8 @@ module Crystal

# Returns the macro type named by a given AST node in the macro language.
def lookup_macro_type(name : Path)
# NOTE: `name.global?` doesn't matter since there are no namespaces for
# the AST node types
if name.names.size == 1
macro_type = @macro_types[name.names.first]?
end

0 comments on commit b8c9f95

Please sign in to comment.