syntax: warn on 'while true do' and suggests 'loop'
[nit.git] / src / syntax / typing.nit
index c3a5ffc..f9fb4a6 100644 (file)
@@ -274,7 +274,10 @@ redef class AClosureDecl
                v.base_variable_ctx = v.variable_ctx
                v.variable_ctx = v.variable_ctx.sub(self)
 
-               var escapable = new EscapableClosure(self, variable.closure, null)
+               var blist: nullable Array[AExpr] = null
+               var t = v.local_property.signature.return_type
+               if t != null then blist = new Array[AExpr]
+               var escapable = new EscapableClosure(self, variable.closure, blist)
                _escapable = escapable
                v.escapable_ctx.push(escapable, null)
 
@@ -284,11 +287,14 @@ redef class AClosureDecl
                        if v.variable_ctx.unreash == false then
                                if variable.closure.signature.return_type != null then
                                        v.error(self, "Control error: Reached end of block (a 'continue' with a value was expected).")
-                               else if variable.closure.is_break then
-                                       v.error(self, "Control error: Reached end of break block (an 'abort' was expected).")
+                               else if variable.closure.is_break and escapable.break_list != null then
+                                       v.error(self, "Control error: Reached end of break block (a 'break' with a value was expected).")
                                end
                        end
                end
+               if blist != null then for x in blist do
+                       v.check_conform_expr(x, t)
+               end
 
                old_var_ctx.merge(v.variable_ctx)
                v.variable_ctx = old_var_ctx
@@ -534,6 +540,10 @@ redef class AWhileExpr
                v.enter_visit(n_expr)
                v.check_conform_expr(n_expr, v.type_bool)
 
+               if n_expr isa ATrueExpr then
+                       v.warning(self, "Warning: use 'loop' instead of 'while true do'.")
+               end
+
                # Prepare inside context (assert cond)
                v.use_if_true_variable_ctx(n_expr)
 
@@ -1677,8 +1687,8 @@ redef class AClosureDef
                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).")
+                       else if closure.is_break and esc.break_list != null then
+                               v.error(self, "Control error: Reached end of break block (a 'break' with a value was expected).")
                        end
                end
                v.variable_ctx = old_var_ctx