typing: do not rely on `MModule.object_type` that will fatal error
[nit.git] / src / semantize / typing.nit
index ae697d4..8e9e3ac 100644 (file)
@@ -246,10 +246,7 @@ private class TypeVisitor
 
        fun get_mclass(node: ANode, name: String): nullable MClass
        do
-               var mclass = modelbuilder.try_get_mclass_by_name(node, mmodule, name)
-               if mclass == null then
-                       self.modelbuilder.error(node, "Type Error: missing primitive class `{name}'.")
-               end
+               var mclass = modelbuilder.get_mclass_by_name(node, mmodule, name)
                return mclass
        end
 
@@ -268,7 +265,9 @@ private class TypeVisitor
                if recvtype isa MNullType then
                        # `null` only accepts some methods of object.
                        if name == "==" or name == "!=" or name == "is_same_instance" then
-                               unsafe_type = mmodule.object_type.as_nullable
+                               var objclass = get_mclass(node, "Object")
+                               if objclass == null then return null # Forward error
+                               unsafe_type = objclass.mclass_type
                        else
                                self.error(node, "Error: Method '{name}' call on 'null'.")
                                return null
@@ -328,7 +327,8 @@ private class TypeVisitor
                end
 
 
-               var msignature = mpropdef.new_msignature or else mpropdef.msignature.as(not null)
+               var msignature = mpropdef.new_msignature or else mpropdef.msignature
+               if msignature == null then return null # skip error
                msignature = resolve_for(msignature, recvtype, recv_is_self).as(MSignature)
 
                var erasure_cast = false
@@ -569,14 +569,18 @@ redef class AMethPropdef
                var nblock = self.n_block
                if nblock == null then return
 
-               var mpropdef = self.mpropdef.as(not null)
+               var mpropdef = self.mpropdef
+               if mpropdef == null then return # skip error
+
                var v = new TypeVisitor(modelbuilder, mpropdef.mclassdef.mmodule, mpropdef)
                self.selfvariable = v.selfvariable
 
                var mmethoddef = self.mpropdef.as(not null)
-               for i in [0..mmethoddef.msignature.arity[ do
-                       var mtype = mmethoddef.msignature.mparameters[i].mtype
-                       if mmethoddef.msignature.vararg_rank == i then
+               var msignature = mmethoddef.msignature
+               if msignature == null then return # skip error
+               for i in [0..msignature.arity[ do
+                       var mtype = msignature.mparameters[i].mtype
+                       if msignature.vararg_rank == i then
                                var arrayclass = v.get_mclass(self.n_signature.n_params[i], "Array")
                                if arrayclass == null then return # Skip error
                                mtype = arrayclass.get_mtype([mtype])
@@ -587,7 +591,7 @@ redef class AMethPropdef
                end
                v.visit_stmt(nblock)
 
-               if not nblock.after_flow_context.is_unreachable and mmethoddef.msignature.return_mtype != null then
+               if not nblock.after_flow_context.is_unreachable and msignature.return_mtype != null then
                        # We reach the end of the function without having a return, it is bad
                        v.error(self, "Control error: Reached end of function (a 'return' with a value was expected).")
                end
@@ -597,7 +601,11 @@ end
 redef class AAttrPropdef
        redef fun do_typing(modelbuilder: ModelBuilder)
        do
-               var mpropdef = self.mpropdef.as(not null)
+               if not has_value then return
+
+               var mpropdef = self.mpropdef
+               if mpropdef == null then return # skip error
+
                var v = new TypeVisitor(modelbuilder, mpropdef.mclassdef.mmodule, mpropdef)
                self.selfvariable = v.selfvariable
 
@@ -609,6 +617,10 @@ redef class AAttrPropdef
                var nblock = self.n_block
                if nblock != null then
                        v.visit_stmt(nblock)
+                       if not nblock.after_flow_context.is_unreachable then
+                               # We reach the end of the init without having a return, it is bad
+                               v.error(self, "Control error: Reached end of block (a 'return' with a value was expected).")
+                       end
                end
        end
 end
@@ -692,7 +704,9 @@ redef class AVardeclExpr
 
                var decltype = mtype
                if mtype == null or mtype isa MNullType then
-                       decltype = v.get_mclass(self, "Object").mclass_type.as_nullable
+                       var objclass = v.get_mclass(self, "Object")
+                       if objclass == null then return # skip error
+                       decltype = objclass.mclass_type.as_nullable
                        if mtype == null then mtype = decltype
                end
 
@@ -975,7 +989,7 @@ redef class AForExpr
                        is_col = true
                end
 
-               if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type, objcla.mclass_type.as_nullable])) then
+               if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then
                        # Map Iterator
                        var coltype = ittype.supertype_to(v.mmodule, v.anchor, mapit_cla)
                        var variables = self.variables
@@ -1119,7 +1133,9 @@ redef class AOrElseExpr
 
                var t = v.merge_types(self, [t1, t2])
                if t == null then
-                       t = v.mmodule.object_type
+                       var c = v.get_mclass(self, "Object")
+                       if c == null then return # forward error
+                       t = c.mclass_type
                        if t2 isa MNullableType then
                                t = t.as_nullable
                        end
@@ -1185,8 +1201,11 @@ redef class ASuperstringExpr
                var mclass = v.get_mclass(self, "String")
                if mclass == null then return # Forward error
                self.mtype = mclass.mclass_type
+               var objclass = v.get_mclass(self, "Object")
+               if objclass == null then return # Forward error
+               var objtype = objclass.mclass_type
                for nexpr in self.n_exprs do
-                       v.visit_expr_subtype(nexpr, v.mmodule.object_type)
+                       v.visit_expr_subtype(nexpr, objtype)
                end
        end
 end
@@ -1811,7 +1830,8 @@ redef class AAttrFormExpr
                var mpropdefs = mproperty.lookup_definitions(v.mmodule, unsafe_type)
                assert mpropdefs.length == 1
                var mpropdef = mpropdefs.first
-               var attr_type = mpropdef.static_mtype.as(not null)
+               var attr_type = mpropdef.static_mtype
+               if attr_type == null then return # skip error
                attr_type = v.resolve_for(attr_type, recvtype, self.n_expr isa ASelfExpr)
                self.attr_type = attr_type
        end