Skip to content

Commit b5dd948

Browse files
asteritematiasgarciaisaia
authored andcommittedAug 5, 2017
Fix #4639: Macro lookup from included module broken
1 parent 0906a88 commit b5dd948

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed
 

Diff for: ‎spec/compiler/semantic/macro_spec.cr

+38
Original file line numberDiff line numberDiff line change
@@ -1084,4 +1084,42 @@ describe "Semantic: macro" do
10841084
Foo.new.main
10851085
)) { tuple_of [int32, char] }
10861086
end
1087+
1088+
it "finds macro in included module at class level (#4639)" do
1089+
assert_type(%(
1090+
module Moo
1091+
macro foo
1092+
def self.bar
1093+
2
1094+
end
1095+
end
1096+
end
1097+
1098+
class Foo
1099+
include Moo
1100+
1101+
foo
1102+
end
1103+
1104+
Foo.bar
1105+
), inject_primitives: false) { int32 }
1106+
end
1107+
1108+
it "finds macro in module in Object" do
1109+
assert_type(%(
1110+
class Object
1111+
macro foo
1112+
def self.bar
1113+
2
1114+
end
1115+
end
1116+
end
1117+
1118+
module Moo
1119+
foo
1120+
end
1121+
1122+
Moo.bar
1123+
), inject_primitives: false) { int32 }
1124+
end
10871125
end

Diff for: ‎src/compiler/crystal/semantic/call.cr

+4-1
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,10 @@ class Crystal::Call
665665
node_scope = node_scope.base_type if node_scope.is_a?(VirtualType)
666666

667667
macros = yield node_scope
668-
if !macros && node_scope.module?
668+
669+
# If the scope is a module (through its instance type), lookup in Object too
670+
# (so macros like `property` and others, defined in Object, work at the module level)
671+
if !macros && node_scope.instance_type.module?
669672
macros = yield program.object
670673
end
671674

Diff for: ‎src/compiler/crystal/types.cr

+6-2
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,9 @@ module Crystal
407407
return DefInMacroLookup.new
408408
end
409409

410-
parents.try &.each do |parent|
410+
# We need to go through the instance type because of module
411+
# inclusion and inheritance.
412+
instance_type.parents.try &.each do |parent|
411413
parent_macro = parent.lookup_macro(name, args, named_args)
412414
return parent_macro if parent_macro
413415
end
@@ -431,7 +433,9 @@ module Crystal
431433
return DefInMacroLookup.new
432434
end
433435

434-
parents.try &.each do |parent|
436+
# We need to go through the instance type because of module
437+
# inclusion and inheritance.
438+
instance_type.parents.try &.each do |parent|
435439
parent_macros = parent.lookup_macros(name)
436440
return parent_macros if parent_macros
437441
end

0 commit comments

Comments
 (0)
Please sign in to comment.