+redef class AClosureCallExpr
+special AAbsAbsSendExpr
+ redef meth after_typing(v)
+ do
+ var va = variable
+ if va.closure.is_break then v.variable_ctx.unreash = true
+ var sig = va.closure.signature
+ var args = process_signature(v, sig, n_id.to_symbol, n_args.to_a)
+ if not n_closure_defs.is_empty then
+ process_closures(v, sig, n_id.to_symbol, n_closure_defs.to_a)
+ end
+ if args == null then return
+ _prop_signature = sig
+ _arguments = args
+ _stype = sig.return_type
+ _is_typed = true
+ end
+end
+
+redef class PClosureDef
+ # The corresponding escapable object
+ readable attr _escapable: EscapableBlock
+
+ attr _accept_typing2: Bool
+ redef meth accept_typing(v)
+ do
+ # Typing is deferred, wait accept_typing2(v)
+ if _accept_typing2 then super
+ end
+
+ private meth accept_typing2(v: TypingVisitor, esc: EscapableClosure) is abstract
+end
+
+redef class AClosureDef
+ redef meth accept_typing2(v, esc)
+ do
+ _escapable = esc
+
+ var sig = esc.closure.signature
+ if sig.arity != n_id.length then
+ v.error(self, "Error: {sig.arity} automatic variable names expected, {n_id.length} found.")
+ return
+ end
+
+ closure = esc.closure
+
+ var old_var_ctx = v.variable_ctx
+ v.variable_ctx = v.variable_ctx.sub(self)
+ variables = new Array[AutoVariable]
+ for i in [0..n_id.length[ do
+ var va = new AutoVariable(n_id[i].to_symbol, self)
+ variables.add(va)
+ va.stype = sig[i]
+ v.variable_ctx.add(va)
+ end
+
+ _accept_typing2 = true
+ accept_typing(v)
+
+ if v.variable_ctx.unreash == false then
+ if closure.signature.return_type != null then
+ v.error(self, "Control error: Reached end of block (a 'continue' with a value was expected).")
+ else if closure.is_break then
+ v.error(self, "Control error: Reached end of break block (a 'break' was expected).")
+ end
+ end
+ v.variable_ctx = old_var_ctx
+ end
+end
+
+class ATypeCheckExpr
+special PExpr
+ private meth check_expr_cast(v: TypingVisitor, n_expr: PExpr, n_type: PType)
+ do
+ if not v.check_expr(n_expr) then return
+ var etype = n_expr.stype
+ var ttype = n_type.stype
+ if etype == ttype then
+ v.warning(self, "Warning: Expression is already a {ttype}.")
+ else if etype < ttype then
+ v.warning(self, "Warning: Expression is already a {ttype} since it is a {etype}.")
+ end
+ end
+end
+