diff --git a/lib/typeprof/core/ast/sig_type.rb b/lib/typeprof/core/ast/sig_type.rb index 083bc74c..cca910ac 100644 --- a/lib/typeprof/core/ast/sig_type.rb +++ b/lib/typeprof/core/ast/sig_type.rb @@ -884,6 +884,16 @@ def contravariant_vertex0(genv, changes, vtx, subst) end def typecheck(genv, changes, vtx, subst) + # For optional type T?, check if all non-nil types match T. + # nil is always acceptable. + changes.add_edge(genv, vtx, changes.target) + has_non_nil = false + vtx.each_type do |ty| + next if ty.is_a?(Type::Bot) + next if ty == genv.nil_type + has_non_nil = true + end + return true unless has_non_nil @type.typecheck(genv, changes, vtx, subst) end diff --git a/scenario/rbs/optional_nil_typecheck.rb b/scenario/rbs/optional_nil_typecheck.rb new file mode 100644 index 00000000..4d561bf0 --- /dev/null +++ b/scenario/rbs/optional_nil_typecheck.rb @@ -0,0 +1,21 @@ +## update: test.rbs +class Object + def bar: (Binding?) -> void +end + +## update: test.rb +eval("hello", nil, "test") + +def bar_nil + bar(nil) +end + +def bar_binding + bar(binding) +end + +## assert +class Object + def bar_nil: -> Object + def bar_binding: -> Object +end