From 7ad1c62d38294e145aa65425a08b5accac121cd3 Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 1 Jul 2018 17:24:07 +0100 Subject: [PATCH] Fix an ICE using break and continue as array lengths --- src/librustc_driver/driver.rs | 1 + src/librustc_mir/build/scope.rs | 6 +++--- src/librustc_passes/loops.rs | 7 ++++++- src/test/ui/array-break-length.rs | 19 +++++++++++++++++++ src/test/ui/array-break-length.stderr | 15 +++++++++++++++ src/test/ui/closure-array-break-length.rs | 2 ++ src/test/ui/closure-array-break-length.stderr | 16 ++++++++++++++-- 7 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/array-break-length.rs create mode 100644 src/test/ui/array-break-length.stderr diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index feeac9d938b6a..c4e196628915b 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -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); diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index b9d6486d9174a..502091e519201 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -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() diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index c99f1e9da439f..898acf48d3df8 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -40,6 +40,7 @@ enum Context { Loop(LoopKind), Closure, LabeledBlock, + AnonConst, } #[derive(Copy, Clone)] @@ -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, _) => { @@ -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(); diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs new file mode 100644 index 0000000000000..c3cfff0e1f642 --- /dev/null +++ b/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 or the MIT license +// , 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 + } +} diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr new file mode 100644 index 0000000000000..114245b9cc77b --- /dev/null +++ b/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`. diff --git a/src/test/ui/closure-array-break-length.rs b/src/test/ui/closure-array-break-length.rs index 2e99921956ab2..727113e328fef 100644 --- a/src/test/ui/closure-array-break-length.rs +++ b/src/test/ui/closure-array-break-length.rs @@ -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 } diff --git a/src/test/ui/closure-array-break-length.stderr b/src/test/ui/closure-array-break-length.stderr index 139153992e274..a337645fb7e8f 100644 --- a/src/test/ui/closure-array-break-length.stderr +++ b/src/test/ui/closure-array-break-length.stderr @@ -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`.