#node.debug("Unsafe typing: expected {sup}, got {sub}")
return sup
end
+ if sup isa MBottomType then return null # Skip error
if sub.need_anchor then
var u = anchor_to(sub)
self.modelbuilder.error(node, "Type Error: expected `{sup}`, got `{sub}: {u}`.")
var paramtype = msignature.mparameters[vararg_rank].mtype
var first = args[vararg_rank]
if vararg_decl == 0 then
- var mclass = get_mclass(node, "Array")
- if mclass == null then return null # Forward error
- var array_mtype = mclass.get_mtype([paramtype])
- if first isa AVarargExpr then
- self.visit_expr_subtype(first.n_expr, array_mtype)
- first.mtype = first.n_expr.mtype
- else
- # only one vararg, maybe `...` was forgot, so be gentle!
- var t = visit_expr(first)
- if t == null then return null # Forward error
- if not is_subtype(t, paramtype) and is_subtype(t, array_mtype) then
- # Not acceptable but could be a `...`
- error(first, "Type Error: expected `{paramtype}`, got `{t}`. Is an ellipsis `...` missing on the argument?")
- return null
- end
- # Standard valid vararg, finish the job
- map.vararg_decl = 1
- self.visit_expr_subtype(first, paramtype)
- end
+ if not check_one_vararg(first, msignature.mparameters[vararg_rank]) then return null
else
- map.vararg_decl = vararg_decl + 1
+ first.vararg_decl = vararg_decl + 1
for i in [vararg_rank..vararg_rank+vararg_decl] do
self.visit_expr_subtype(args[i], paramtype)
end
return map
end
+ # Check an expression as a single vararg.
+ # The main point of the method if to handle the case of reversed vararg (see `AVarargExpr`)
+ fun check_one_vararg(arg: AExpr, param: MParameter): Bool
+ do
+ var paramtype = param.mtype
+ var mclass = get_mclass(arg, "Array")
+ if mclass == null then return false # Forward error
+ var array_mtype = mclass.get_mtype([paramtype])
+ if arg isa AVarargExpr then
+ self.visit_expr_subtype(arg.n_expr, array_mtype)
+ arg.mtype = arg.n_expr.mtype
+ else
+ # only one vararg, maybe `...` was forgot, so be gentle!
+ var t = visit_expr(arg)
+ if t == null then return false # Forward error
+ if not is_subtype(t, paramtype) and is_subtype(t, array_mtype) then
+ # Not acceptable but could be a `...`
+ error(arg, "Type Error: expected `{paramtype}`, got `{t}`. Is an ellipsis `...` missing on the argument?")
+ return false
+ end
+ # Standard valid vararg, finish the job
+ arg.vararg_decl = 1
+ self.visit_expr_subtype(arg, paramtype)
+ end
+ return true
+ end
+
fun error(node: ANode, message: String)
do
self.modelbuilder.error(node, message)
class SignatureMap
# Associate a parameter to an argument
var map = new ArrayMap[Int, Int]
-
- # The length of the vararg sequence
- # 0 if no vararg or if reverse vararg (cf `AVarargExpr`)
- var vararg_decl: Int = 0
end
# A specific method call site with its associated informations.
# The result of the evaluation of `self` must be
# stored inside the designated array (there is an implicit `push`)
var comprehension: nullable AArrayExpr = null
+
+ # It indicates the number of arguments collected as a vararg.
+ #
+ # When 0, the argument is used as is, without transformation.
+ # When 1, the argument is transformed into an singleton array.
+ # Above 1, the arguments and the next ones are transformed into a common array.
+ #
+ # This attribute is meaning less on expressions not used as attributes.
+ var vararg_decl: Int = 0
end
redef class ABlockExpr
end
redef class AForExpr
+ redef fun accept_typing(v)
+ do
+ v.has_loop = true
+
+ for g in n_groups do
+ var mtype = v.visit_expr(g.n_expr)
+ if mtype == null then return
+ g.do_type_iterator(v, mtype)
+ if g.is_broken then is_broken = true
+ end
+
+ v.visit_stmt(n_block)
+
+ self.mtype = n_block.mtype
+ self.is_typed = true
+ end
+end
+
+redef class AForGroup
var coltype: nullable MClassType
var method_iterator: nullable CallSite
self.method_successor = v.get_method(self, vtype, "successor", false)
end
end
-
- redef fun accept_typing(v)
- do
- v.has_loop = true
- var mtype = v.visit_expr(n_expr)
- if mtype == null then return
-
- self.do_type_iterator(v, mtype)
-
- v.visit_stmt(n_block)
-
- self.mtype = n_block.mtype
- self.is_typed = true
- end
end
redef class AWithExpr