diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index d031694d85308..12db699894eaa 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -218,12 +218,16 @@ E0590: r##" Example of erroneous code: ```compile_fail -while break {} +loop { + while break {} +} ``` To fix this, add a label specifying which loop is being broken out of: ``` -'foo: while break 'foo {} +'foo: loop { + while break 'foo {} +} ``` "##, diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 2368b1aca6948..68b144939bbb0 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -215,6 +215,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { } return false; } + fn emit_unlabled_cf_in_while_condition(&mut self, span: Span, cf_type: &str) { struct_span_err!(self.sess, span, E0590, "`break` or `continue` with no label in the condition of a `while` loop") diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 232a32deb864e..71260a4838335 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1097,7 +1097,7 @@ loop { } ``` -Please verify you spelt or declare the label correctly. Example: +Please verify you spelt and declared the label correctly. Example: ``` 'a: loop { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 5a5f5ce2e3862..fc3e3c863baa3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2112,11 +2112,9 @@ impl<'a> Resolver<'a> { } } - /// Searches the current set of local scopes for labels. Returns the first non-None label that - /// is returned by the given predicate function - /// - /// Stops after meeting a closure. - fn search_label(&self, mut ident: Ident, pred: P) -> Option + /// Searches the current set of local scopes for labels. Returns the first non-`None` label + /// that is returned by the given predicate function. Stops after meeting a closure. + fn search_label(&self, mut ident: Ident, pred: P) -> Option where P: Fn(&Rib, Ident) -> Option { for rib in self.label_ribs.iter().rev() { @@ -2130,7 +2128,7 @@ impl<'a> Resolver<'a> { } } _ => { - // Do not resolve labels across function boundary + // Do not resolve labels across function boundary. return None; } } @@ -3731,8 +3729,8 @@ impl<'a> Resolver<'a> { match self.search_label(label.ident, |rib, id| rib.bindings.get(&id).cloned()) { None => { // Search again for close matches... - // Picks the first label that is "close enough", which is not necessarily - // the closest match + // Picks the first label that is "close enough", which is not + // necessarily the closest match. let close_match = self.search_label(label.ident, |rib, ident| { let names = rib.bindings.iter().map(|(id, _)| &id.name); find_best_match_for_name(names, &*ident.name.as_str(), None) @@ -3775,15 +3773,15 @@ impl<'a> Resolver<'a> { ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block), ExprKind::While(ref subexpression, ref block, label) => { + self.visit_expr(subexpression); self.with_resolved_label(label, expr.id, |this| { - this.visit_expr(subexpression); this.visit_block(block); }); } ExprKind::WhileLet(ref pats, ref subexpression, ref block, label) => { + self.visit_expr(subexpression); self.with_resolved_label(label, expr.id, |this| { - this.visit_expr(subexpression); this.ribs[ValueNS].push(Rib::new(NormalRibKind)); let mut bindings_list = FxHashMap(); for pat in pats { diff --git a/src/test/ui/while-label-break-condition.rs b/src/test/ui/while-label-break-condition.rs new file mode 100644 index 0000000000000..0da63054318fd --- /dev/null +++ b/src/test/ui/while-label-break-condition.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(unreachable_code)] + +fn main() { + 'a: while break 'a {} //~ ERROR: use of undeclared label + 'b: while break 'b {}; //~ ERROR: use of undeclared label +} diff --git a/src/test/ui/while-label-break-condition.stderr b/src/test/ui/while-label-break-condition.stderr new file mode 100644 index 0000000000000..c93f33d8eb0de --- /dev/null +++ b/src/test/ui/while-label-break-condition.stderr @@ -0,0 +1,15 @@ +error[E0426]: use of undeclared label `'a` + --> $DIR/while-label-break-condition.rs:14:21 + | +LL | 'a: while break 'a {} //~ ERROR: use of undeclared label + | ^^ undeclared label `'a` + +error[E0426]: use of undeclared label `'b` + --> $DIR/while-label-break-condition.rs:15:21 + | +LL | 'b: while break 'b {}; //~ ERROR: use of undeclared label + | ^^ undeclared label `'b` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0426`.