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`.