model: Make the `anchor` parameter of `MType::anchor_to` nullable
[nit.git] / src / semantize / typing.nit
index 7c1adf4..d5cbb46 100644 (file)
@@ -81,11 +81,6 @@ private class TypeVisitor
 
        fun anchor_to(mtype: MType): MType
        do
-               var anchor = anchor
-               if anchor == null then
-                       assert not mtype.need_anchor
-                       return mtype
-               end
                return mtype.anchor_to(mmodule, anchor)
        end
 
@@ -580,7 +575,16 @@ private class TypeVisitor
                                return mtypes.first
                        else
                                var res = merge_types(node,mtypes)
-                               if res == null then res = variable.declared_type
+                               if res == null then
+                                       res = variable.declared_type
+                                       # Try to fallback to a non-null version
+                                       if res != null and can_be_null(res) then do
+                                               for t in mtypes do
+                                                       if t != null and can_be_null(t) then break label
+                                               end
+                                               res = res.as_notnull
+                                       end label
+                               end
                                return res
                        end
                end
@@ -1788,9 +1792,16 @@ redef class AIsaExpr
                        #var to = if mtype != null then mtype.to_s else "invalid"
                        #debug("adapt {variable}: {from} -> {to}")
 
-                       # Do not adapt if there is no information gain (i.e. adapt to a supertype)
-                       if mtype == null or orig == null or not v.is_subtype(orig, mtype) then
-                               self.after_flow_context.when_true.set_var(v, variable, mtype)
+                       var thentype = v.intersect_types(self, orig, mtype)
+                       if thentype != orig then
+                               self.after_flow_context.when_true.set_var(v, variable, thentype)
+                               #debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> then {thentype or else "?"}"
+                       end
+
+                       var elsetype = v.diff_types(self, orig, mtype)
+                       if elsetype != orig then
+                               self.after_flow_context.when_false.set_var(v, variable, elsetype)
+                               #debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> else {elsetype or else "?"}"
                        end
                end