From c5f482822567302b5b4329a384dc9b8b523c818b Mon Sep 17 00:00:00 2001 From: Ary Borenszweig <aborenszweig@manas.com.ar> Date: Fri, 24 Jan 2014 11:15:15 -0300 Subject: [PATCH] Better restriction check for generic types --- spec/compiler/codegen/is_a_spec.cr | 10 ++++++++++ spec/compiler/type_inference/def_overload_spec.cr | 13 +++++++++++++ src/compiler/crystal/type_inference/restrictions.cr | 4 ++-- src/compiler/crystal/type_inference/type_merge.cr | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/spec/compiler/codegen/is_a_spec.cr b/spec/compiler/codegen/is_a_spec.cr index f0e1db89c3..0e848c62b5 100755 --- a/spec/compiler/codegen/is_a_spec.cr +++ b/spec/compiler/codegen/is_a_spec.cr @@ -287,4 +287,14 @@ describe "Codegen: is_a?" do 2.is_a?(A) ").to_b.should be_false end + + it "gives false if generic type doesn't match exactly" do + run(" + class Foo(T) + end + + foo = Foo(Int32 | Float64).new + foo.is_a?(Foo(Int32)) ? 1 : 2 + ").to_i.should eq(2) + end end diff --git a/spec/compiler/type_inference/def_overload_spec.cr b/spec/compiler/type_inference/def_overload_spec.cr index bfd154a384..4769b8c71e 100755 --- a/spec/compiler/type_inference/def_overload_spec.cr +++ b/spec/compiler/type_inference/def_overload_spec.cr @@ -519,4 +519,17 @@ describe "Type inference: def overload" do 1 ") { int32 } end + + it "errors if generic type doesn't match" do + assert_error " + class Foo(T) + end + + def foo(x : Foo(Int32)) + end + + foo Foo(Int32 | Float64).new + ", + "no overload matches" + end end diff --git a/src/compiler/crystal/type_inference/restrictions.cr b/src/compiler/crystal/type_inference/restrictions.cr index 7c55d30bef..7f0e7b4358 100644 --- a/src/compiler/crystal/type_inference/restrictions.cr +++ b/src/compiler/crystal/type_inference/restrictions.cr @@ -236,7 +236,7 @@ module Crystal type_vars.each do |name, type_var| other_type_var = other.type_vars[i] restricted = type_var.type.restrict other_type_var, owner, type_lookup, free_vars - return nil unless restricted + return nil unless restricted == type_var.type i += 1 end @@ -249,7 +249,7 @@ module Crystal type_vars.each do |name, type_var| other_type_var = other.type_vars[name] restricted = type_var.type.restrict(other_type_var.type, owner, type_lookup, free_vars) - return nil unless restricted + return nil unless restricted == type_var.type end self diff --git a/src/compiler/crystal/type_inference/type_merge.cr b/src/compiler/crystal/type_inference/type_merge.cr index 1eb3a19272..7138d37dc8 100644 --- a/src/compiler/crystal/type_inference/type_merge.cr +++ b/src/compiler/crystal/type_inference/type_merge.cr @@ -2,7 +2,7 @@ require "../program" module Crystal class Program - def type_merge(types : Array(Type)) + def type_merge(types : Array(Type?)) combined_union_of compact_types(types) end -- GitLab