assert mproperty isa MMethod
- if is_toplevel_context and recv_is_self and not mproperty.is_toplevel and name != "sys" and name != "exit" and name != "args" then
+ if is_toplevel_context and recv_is_self and not mproperty.is_toplevel and name != "sys" and name != "exit" then
# FIXME named methods are here as a workaround
error(node, "Error: '{name}' is not a top-level method, thus need a receiver.")
end
var erasure_cast = false
var rettype = mpropdef.msignature.return_mtype
if not recv_is_self and rettype != null then
- if rettype isa MNullableType then rettype = rettype.mtype
+ rettype = rettype.as_notnullable
if rettype isa MParameterType then
var erased_rettype = msignature.return_mtype
assert erased_rettype != null
# anchor formal and virtual types
if mtype.need_anchor then mtype = v.anchor_to(mtype)
- if mtype isa MNullableType then mtype = mtype.mtype
+ mtype = mtype.as_notnullable
self.coltype = mtype.as(MClassType)
# get methods is_ok, next, item
return # Skip error
end
- if t1 isa MNullableType then
- t1 = t1.mtype
- end
+ t1 = t1.as_notnullable
var t = v.merge_types(self, [t1, t2])
if t == null then
redef fun accept_typing(v)
do
var mtype = v.visit_expr(self.n_expr)
+ if mtype == null then return # Forward error
+
if mtype isa MNullType then
v.error(self, "Type error: as(not null) on null")
return
self.mtype = mtype.mtype
return
end
- # TODO: warn on useless as not null
self.mtype = mtype
+
+ if mtype isa MClassType then
+ v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}`.")
+ return
+ end
+ assert mtype.need_anchor
+ var u = v.anchor_to(mtype)
+ if not u isa MNullableType then
+ v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}: {u}`.")
+ return
+ end
end
end