Skip to content

Commit

Permalink
Rollup merge of rust-lang#51070 - est31:fix_break_const_ice, r=estebank
Browse files Browse the repository at this point in the history
Fail typecheck if we encounter a bogus break

Lone breaks outside of loops create errors in the
loop check pass but as they are not fatal,
compilation continues.

MIR building code assumes all HIR break statements
to point to valid locations and fires ICEs if this
assumption is violated. In normal compilation,
this causes no issues, as code apparently prevents
MIR from being built if errors are present.

However, before that, typecheck runs and with it
MIR const eval. Here we operate differently
from normal compilation: it doesn't check for any
errors except for type checker ones and then
directly builds the MIR.

This constellation causes an ICE-on-error if
bogus break statements are being put into array
length expressions.

This commit fixes this ICE by letting typecheck
fail if bogus break statements are encountered.
This way, MIR const eval fails cleanly with a
type check error.

Fixes rust-lang#50576
Fixes rust-lang#50581
  • Loading branch information
kennytm authored May 26, 2018
2 parents 239e3d2 + 5724dad commit 5089ebc
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3764,6 +3764,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}

ctxt.may_break = true;

// the type of a `break` is always `!`, since it diverges
tcx.types.never
} else {
// Otherwise, we failed to find the enclosing loop;
// this can only happen if the `break` was not
Expand All @@ -3784,10 +3787,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}
}
// There was an error, make typecheck fail
tcx.types.err
}

// the type of a `break` is always `!`, since it diverges
tcx.types.never
}
hir::ExprAgain(_) => { tcx.types.never }
hir::ExprRet(ref expr_opt) => {
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/issue-43162.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// except according to those terms.

fn foo() -> bool {
//~^ ERROR E0308
break true; //~ ERROR E0268
}

Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/issue-50576.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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.

fn main() {
|bool: [u8; break 'L]| 0;
//~^ ERROR [E0426]
//~| ERROR [E0268]
Vec::<[u8; break]>::new(); //~ ERROR [E0268]
}
22 changes: 22 additions & 0 deletions src/test/ui/issue-50576.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0426]: use of undeclared label `'L`
--> $DIR/issue-50576.rs:12:23
|
LL | |bool: [u8; break 'L]| 0;
| ^^ undeclared label `'L`

error[E0268]: `break` outside of loop
--> $DIR/issue-50576.rs:12:17
|
LL | |bool: [u8; break 'L]| 0;
| ^^^^^^^^ cannot break outside of a loop

error[E0268]: `break` outside of loop
--> $DIR/issue-50576.rs:15:16
|
LL | Vec::<[u8; break]>::new(); //~ ERROR [E0268]
| ^^^^^ cannot break outside of a loop

error: aborting due to 3 previous errors

Some errors occurred: E0268, E0426.
For more information about an error, try `rustc --explain E0268`.
13 changes: 13 additions & 0 deletions src/test/ui/issue-50581.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.

fn main() {
|_: [u8; break]| (); //~ ERROR [E0268]
}
9 changes: 9 additions & 0 deletions src/test/ui/issue-50581.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0268]: `break` outside of loop
--> $DIR/issue-50581.rs:12:14
|
LL | |_: [u8; break]| (); //~ ERROR [E0268]
| ^^^^^ cannot break outside of a loop

error: aborting due to previous error

For more information about this error, try `rustc --explain E0268`.

0 comments on commit 5089ebc

Please sign in to comment.