Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix an ICE using break and continue as array lengths
  • Loading branch information
varkor committed Jul 2, 2018
1 parent c6bbee8 commit 7ad1c62
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/librustc_driver/driver.rs
Expand Up @@ -1211,6 +1211,7 @@ where
.set(derive_registrar::find(&hir_map));

time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
sess.abort_if_errors();

let mut local_providers = ty::query::Providers::default();
default_provide(&mut local_providers);
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_mir/build/scope.rs
Expand Up @@ -541,9 +541,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
/// Finds the breakable scope for a given label. This is used for
/// resolving `break` and `continue`.
pub fn find_breakable_scope(&self,
span: Span,
label: region::Scope)
-> &BreakableScope<'tcx> {
span: Span,
label: region::Scope)
-> &BreakableScope<'tcx> {
// find the loop-scope with the correct id
self.breakable_scopes.iter()
.rev()
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_passes/loops.rs
Expand Up @@ -40,6 +40,7 @@ enum Context {
Loop(LoopKind),
Closure,
LabeledBlock,
AnonConst,
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -71,6 +72,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
self.with_context(Normal, |v| intravisit::walk_impl_item(v, i));
}

fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) {
self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c));
}

fn visit_expr(&mut self, e: &'hir hir::Expr) {
match e.node {
hir::ExprWhile(ref e, ref b, _) => {
Expand Down Expand Up @@ -194,7 +199,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
.span_label(span, "cannot break inside of a closure")
.emit();
}
Normal => {
Normal | AnonConst => {
struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
.span_label(span, "cannot break outside of a loop")
.emit();
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/array-break-length.rs
@@ -0,0 +1,19 @@
// 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() {
loop {
|_: [_; break]| {} //~ ERROR: `break` outside of loop
}

loop {
|_: [_; continue]| {} //~ ERROR: `continue` outside of loop
}
}
15 changes: 15 additions & 0 deletions src/test/ui/array-break-length.stderr
@@ -0,0 +1,15 @@
error[E0268]: `break` outside of loop
--> $DIR/array-break-length.rs:13:17
|
LL | |_: [_; break]| {} //~ ERROR: `break` outside of loop
| ^^^^^ cannot break outside of a loop

error[E0268]: `continue` outside of loop
--> $DIR/array-break-length.rs:17:17
|
LL | |_: [_; continue]| {} //~ ERROR: `continue` outside of loop
| ^^^^^^^^ cannot break outside of a loop

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0268`.
2 changes: 2 additions & 0 deletions src/test/ui/closure-array-break-length.rs
Expand Up @@ -12,6 +12,8 @@ fn main() {
|_: [_; continue]| {}; //~ ERROR: `continue` outside of loop

while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
//~^ ERROR: `continue` outside of loop

while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
//~^ ERROR: `break` outside of loop
}
16 changes: 14 additions & 2 deletions src/test/ui/closure-array-break-length.stderr
Expand Up @@ -10,13 +10,25 @@ error[E0590]: `break` or `continue` with no label in the condition of a `while`
LL | while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
| ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop

error[E0268]: `continue` outside of loop
--> $DIR/closure-array-break-length.rs:14:19
|
LL | while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
| ^^^^^^^^ cannot break outside of a loop

error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
--> $DIR/closure-array-break-length.rs:16:19
--> $DIR/closure-array-break-length.rs:17:19
|
LL | while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
| ^^^^^ unlabeled `break` in the condition of a `while` loop

error: aborting due to 3 previous errors
error[E0268]: `break` outside of loop
--> $DIR/closure-array-break-length.rs:17:19
|
LL | while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
| ^^^^^ cannot break outside of a loop

error: aborting due to 5 previous errors

Some errors occurred: E0268, E0590.
For more information about an error, try `rustc --explain E0268`.

0 comments on commit 7ad1c62

Please sign in to comment.