From 9af4c219efcede2c8421992b8ab87d23d97f799e Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 8 May 2018 06:45:58 -0300 Subject: [PATCH] Fix bug related to types that have all their initialize methods as macro defs --- spec/compiler/semantic/instance_var_spec.cr | 29 +++++++++++++++++++ .../semantic/type_declaration_processor.cr | 4 +-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/spec/compiler/semantic/instance_var_spec.cr b/spec/compiler/semantic/instance_var_spec.cr index 94918ed69765..89dc553ee5d1 100644 --- a/spec/compiler/semantic/instance_var_spec.cr +++ b/spec/compiler/semantic/instance_var_spec.cr @@ -4464,6 +4464,35 @@ describe "Semantic: instance var" do ), inject_primitives: false) { types["Foo"] } end + it "is more permissive with macro def initialize, multiple" do + assert_type(%( + class Foo + @x : Int32 + + def initialize + {% begin %} + {% @type %} + @x = 1 + {% end %} + end + + def initialize(x) + {% begin %} + {% @type %} + @x = x + {% end %} + end + + def x + @x + end + end + + Foo.new + Foo.new(1).x + )) { int32 } + end + it "errors with macro def but another def doesn't initialize all" do assert_error %( class Foo diff --git a/src/compiler/crystal/semantic/type_declaration_processor.cr b/src/compiler/crystal/semantic/type_declaration_processor.cr index 8c4a679e902c..c2c77b051aff 100644 --- a/src/compiler/crystal/semantic/type_declaration_processor.cr +++ b/src/compiler/crystal/semantic/type_declaration_processor.cr @@ -115,7 +115,7 @@ struct Crystal::TypeDeclarationProcessor # removed if an explicit type is found (in remove_error). @errors = {} of Type => Hash(String, Error) - # Types that have a single macro def initialize + # Types whose initialize methods are all macro defs @has_macro_def = Set(Type).new @type_decl_visitor = TypeDeclarationVisitor.new(@program, @explicit_instance_vars) @@ -430,7 +430,7 @@ struct Crystal::TypeDeclarationProcessor infos = find_initialize_infos(owner) if infos - @has_macro_def << owner if infos.size == 1 && infos.first.def.macro_def? + @has_macro_def << owner if infos.all?(&.def.macro_def?) non_nilable = compute_non_nilable_instance_vars_multi(owner, infos) end