提交 843dc604 编写于 作者: T Thomas Jespersen

Add suggestions for misspelled labels

Another part of #30197
上级 5f578dfa
......@@ -137,7 +137,7 @@ enum ResolutionError<'a> {
/// error E0416: identifier is bound more than once in the same pattern
IdentifierBoundMoreThanOnceInSamePattern(&'a str),
/// error E0426: use of undeclared label
UndeclaredLabel(&'a str),
UndeclaredLabel(&'a str, Option<Name>),
/// error E0429: `self` imports are only allowed within a { } list
SelfImportsOnlyAllowedWithin,
/// error E0430: `self` import can only appear once in the list
......@@ -263,13 +263,17 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
err.span_label(span, "used in a pattern more than once");
err
}
ResolutionError::UndeclaredLabel(name) => {
ResolutionError::UndeclaredLabel(name, lev_candidate) => {
let mut err = struct_span_err!(resolver.session,
span,
E0426,
"use of undeclared label `{}`",
name);
err.span_label(span, format!("undeclared label `{}`", name));
if let Some(lev_candidate) = lev_candidate {
err.span_label(span, format!("did you mean `{}`?", lev_candidate));
} else {
err.span_label(span, format!("undeclared label `{}`", name));
}
err
}
ResolutionError::SelfImportsOnlyAllowedWithin => {
......@@ -1790,9 +1794,13 @@ fn with_scope<F>(&mut self, id: NodeId, f: F)
}
}
/// Searches the current set of local scopes for labels.
/// 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) -> Option<Def> {
fn search_label<P, R>(&self, mut ident: Ident, pred: P) -> Option<R>
where P: Fn(&Rib, Ident) -> Option<R>
{
for rib in self.label_ribs.iter().rev() {
match rib.kind {
NormalRibKind => {}
......@@ -1808,9 +1816,9 @@ fn search_label(&self, mut ident: Ident) -> Option<Def> {
return None;
}
}
let result = rib.bindings.get(&ident).cloned();
if result.is_some() {
return result;
let r = pred(rib, ident);
if r.is_some() {
return r;
}
}
None
......@@ -3202,12 +3210,20 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
}
ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
match self.search_label(label.node) {
match self.search_label(label.node, |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
let close_match = self.search_label(label.node, |rib, ident| {
let names = rib.bindings.iter().map(|(id, _)| &id.name);
find_best_match_for_name(names, &*ident.name.as_str(), None)
});
self.record_def(expr.id, err_path_resolution());
resolve_error(self,
label.span,
ResolutionError::UndeclaredLabel(&label.node.name.as_str()));
ResolutionError::UndeclaredLabel(&label.node.name.as_str(),
close_match));
}
Some(def @ Def::Label(_)) => {
// Since this def is a label, it is never read.
......
// Copyright 2017 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.
#[allow(unreachable_code)]
fn main() {
'foo: loop {
break 'fo;
}
'bar: loop {
continue 'bor;
}
'longlabel: loop {
'longlabel1: loop {
break 'longlable;
}
}
}
error[E0426]: use of undeclared label `'fo`
--> $DIR/suggest-labels.rs:14:15
|
14 | break 'fo;
| ^^^ did you mean `'foo`?
error[E0426]: use of undeclared label `'bor`
--> $DIR/suggest-labels.rs:18:18
|
18 | continue 'bor;
| ^^^^ did you mean `'bar`?
error[E0426]: use of undeclared label `'longlable`
--> $DIR/suggest-labels.rs:23:19
|
23 | break 'longlable;
| ^^^^^^^^^^ did you mean `'longlabel1`?
error: aborting due to 3 previous errors
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册