Change:
Having the following main function results in an illigal instruction on stable, beta and nighlty. It should be noted that when is not used after the loop, the illigal instruction does not occur Interestingly putting the same while-loop in a function works fine:
Update: A more simple version that also results in an illigal instruction: after some more trying, it can be shortened to this (and works for functions other than in main, as shown here: ) : adding a statement at the end of main seems to 'fix' the problem
Checking with godbolt, 1.25 and above: results in undefined instruction (this issue) 1.18 to 1.24: ICE with broken MIR 1.17: becomes no-op 1.16 and below: Error "use of undeclared label "
Err the last example is even featured in (introduced in ), but why this seems not tested at all . Edit: It generates an at MIR level. <details<summaryThe initial MIR already contains an unreachable.</summary</details<details<summary-Zunpretty=hir,typed</summary</details
It's because in the example that is tested, there's no semicolon: Why that makes a difference, I haven't determined yet.
The problem is, for some reason, the type checker inferred to have type , and thus the rest of the block is . However, without the the inferred type is just as expected.
Maybe slightly off-topic, but why are references to the label even allowed in the condition, rather than solely the body? You don't achieve extra expressiveness, as it's equivalent to returning false in the condition, and it makes things more complicated.
having code like this results in an ICE:
Because it is consistent with the desugaring of the while loop to a which is a valid and fairly sensible code.
I think the bug in in the type-checker then: it should not be giving the type of , clear. — you interested in fixing? I can give a few tips...
Marking as P-medium: technically a regression, but a very old one, and kind of a corner case. Still, I'll try to leave some notes on how to fix.
yeah, I can have a look into this. Might be a little delayed, but definitely within the next couple of weeks.

Discussion:
let ctxt = BreakableCtxt { // cannot use break with a value from a while loop coerce: None, <del> may_break: true, </del> <ins> may_break: false,  // Will get updated if/when we find a `break`. </ins> }; <del> self.with_breakable_ctxt(expr.id, ctxt, || { </del> <ins> let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || { </ins> self.check_expr_has_type_or_error(&cond, tcx.types.bool); let cond_diverging = self.diverges.get(); self.check_block_no_value(&body);

self.diverges.set(cond_diverging); }); <ins> if ctxt.may_break { // No way to know whether it's diverging because // of a `break` or an outer `break` or `return`. self.diverges.set(Diverges::Maybe); } </ins> self.tcx.mk_nil() } hir::ExprLoop(ref body, _, source) => {

let ctxt = BreakableCtxt { coerce, <del> may_break: false, // will get updated if/when we find a `break` </del> <ins> may_break: false, // Will get updated if/when we find a `break`. </ins> }; let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {

if ctxt.may_break { // No way to know whether it's diverging because <del> // of a `break` or an outer `break` or `return. </del> <ins> // of a `break` or an outer `break` or `return`. </ins> self.diverges.set(Diverges::Maybe); }

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(never_type)] fn main() { // The `if false` expressions are simply to // make sure we don't avoid checking everything // simply because a few expressions are unreachable. if false { let _: ! = { //~ ERROR mismatched types 'a: while break 'a {}; }; } if false { let _: ! = { while false { //~ ERROR mismatched types break } }; } if false { let _: ! = { while false { //~ ERROR mismatched types return } }; } } </ins>

<ins> error[E0308]: mismatched types --> $DIR/break-while-condition.rs:19:20 | LL |           let _: ! = { //~ ERROR mismatched types |  ____________________^ LL | |             'a: while break 'a {}; LL | |         }; | |_________^ expected !, found () | = note: expected type `!` found type `()` error[E0308]: mismatched types --> $DIR/break-while-condition.rs:26:13 | LL |   fn main() { |             - expected `()` because of default return type ... LL | /             while false { //~ ERROR mismatched types LL | |                 break LL | |             } | |_____________^ expected !, found () | = note: expected type `!` found type `()` error[E0308]: mismatched types --> $DIR/break-while-condition.rs:34:13 | LL |   fn main() { |             - expected `()` because of default return type ... LL | /             while false { //~ ERROR mismatched types LL | |                 return LL | |             } | |_____________^ expected !, found () | = note: expected type `!` found type `()` error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. </ins>