diff --git a/spec/compiler/type_inference/def_overload_spec.cr b/spec/compiler/type_inference/def_overload_spec.cr index 973e37ec9c5b2ac5c2a25a71f32960f397fc2ffe..5c6b3d417b52552e9a36290d8f353263975a08bc 100755 --- a/spec/compiler/type_inference/def_overload_spec.cr +++ b/spec/compiler/type_inference/def_overload_spec.cr @@ -543,6 +543,16 @@ describe "Type inference: def overload" do ") { int32.metaclass } end + it "gets free variable from union restriction (2)" do + assert_type(" + def foo(x : Nil | U) + U + end + + foo(nil || 1) + ") { int32.metaclass } + end + it "gets free variable from union restriction without a union" do assert_type(" def foo(x : Nil | U) diff --git a/src/compiler/crystal/type_inference/restrictions.cr b/src/compiler/crystal/type_inference/restrictions.cr index 17f50ef183c007f3a91f39344dfe47637ae9431f..e257e5a199442acae68096132a4cb15d5380d9b5 100644 --- a/src/compiler/crystal/type_inference/restrictions.cr +++ b/src/compiler/crystal/type_inference/restrictions.cr @@ -203,11 +203,15 @@ module Crystal def restrict(other : Union, owner, type_lookup, free_vars) types = [] of Type + discarded = [] of Type other.types.each do |other_type| self.union_types.each do |type| + next if discarded.includes?(type) + restricted = type.restrict(other_type, owner, type_lookup, free_vars) if restricted types << restricted + discarded << type break end end