Skip to content

Commit 5089ebc

Browse files
authored
Rollup merge of rust-lang#51070 - est31:fix_break_const_ice, r=estebank
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
2 parents 239e3d2 + 5724dad commit 5089ebc

File tree

6 files changed

+66
-2
lines changed

6 files changed

+66
-2
lines changed

src/librustc_typeck/check/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3764,6 +3764,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37643764
}
37653765

37663766
ctxt.may_break = true;
3767+
3768+
// the type of a `break` is always `!`, since it diverges
3769+
tcx.types.never
37673770
} else {
37683771
// Otherwise, we failed to find the enclosing loop;
37693772
// this can only happen if the `break` was not
@@ -3784,10 +3787,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
37843787
}
37853788
}
37863789
}
3790+
// There was an error, make typecheck fail
3791+
tcx.types.err
37873792
}
37883793

3789-
// the type of a `break` is always `!`, since it diverges
3790-
tcx.types.never
37913794
}
37923795
hir::ExprAgain(_) => { tcx.types.never }
37933796
hir::ExprRet(ref expr_opt) => {

src/test/compile-fail/issue-43162.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
fn foo() -> bool {
12+
//~^ ERROR E0308
1213
break true; //~ ERROR E0268
1314
}
1415

src/test/ui/issue-50576.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
|bool: [u8; break 'L]| 0;
13+
//~^ ERROR [E0426]
14+
//~| ERROR [E0268]
15+
Vec::<[u8; break]>::new(); //~ ERROR [E0268]
16+
}

src/test/ui/issue-50576.stderr

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0426]: use of undeclared label `'L`
2+
--> $DIR/issue-50576.rs:12:23
3+
|
4+
LL | |bool: [u8; break 'L]| 0;
5+
| ^^ undeclared label `'L`
6+
7+
error[E0268]: `break` outside of loop
8+
--> $DIR/issue-50576.rs:12:17
9+
|
10+
LL | |bool: [u8; break 'L]| 0;
11+
| ^^^^^^^^ cannot break outside of a loop
12+
13+
error[E0268]: `break` outside of loop
14+
--> $DIR/issue-50576.rs:15:16
15+
|
16+
LL | Vec::<[u8; break]>::new(); //~ ERROR [E0268]
17+
| ^^^^^ cannot break outside of a loop
18+
19+
error: aborting due to 3 previous errors
20+
21+
Some errors occurred: E0268, E0426.
22+
For more information about an error, try `rustc --explain E0268`.

src/test/ui/issue-50581.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
|_: [u8; break]| (); //~ ERROR [E0268]
13+
}

src/test/ui/issue-50581.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0268]: `break` outside of loop
2+
--> $DIR/issue-50581.rs:12:14
3+
|
4+
LL | |_: [u8; break]| (); //~ ERROR [E0268]
5+
| ^^^^^ cannot break outside of a loop
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0268`.

0 commit comments

Comments
 (0)