1
Fork 0

Simplify error reporting.

This commit is contained in:
Camille GILLOT 2022-04-08 22:52:07 +02:00
parent d1c1bbe5f3
commit 944d852afe
2 changed files with 76 additions and 85 deletions

View file

@ -1385,14 +1385,12 @@ impl<'a> Resolver<'a> {
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'a>,
finalize_full: Finalize,
ribs: Option<&PerNS<Vec<Rib<'a>>>>, ribs: Option<&PerNS<Vec<Rib<'a>>>>,
unusable_binding: Option<&'a NameBinding<'a>>, unusable_binding: Option<&'a NameBinding<'a>>,
module: Option<ModuleOrUniformRoot<'a>>, module: Option<ModuleOrUniformRoot<'a>>,
i: usize, i: usize,
ident: Ident, ident: Ident,
) -> (String, Option<Suggestion>) { ) -> (String, Option<Suggestion>) {
let finalize = finalize_full.path_span();
let is_last = i == path.len() - 1; let is_last = i == path.len() - 1;
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
let module_res = match module { let module_res = match module {
@ -1418,81 +1416,7 @@ impl<'a> Resolver<'a> {
} else { } else {
(format!("could not find `{}` in the crate root", ident), None) (format!("could not find `{}` in the crate root", ident), None)
} }
} else if i == 0 { } else if i > 0 {
if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
// Check whether the name refers to an item in the value namespace.
let suggestion = if ribs.is_some() {
let match_span = match self.resolve_ident_in_lexical_scope(
ident,
ValueNS,
parent_scope,
Finalize::No,
&ribs.unwrap()[ValueNS],
unusable_binding,
) {
// Name matches a local variable. For example:
// ```
// fn f() {
// let Foo: &str = "";
// println!("{}", Foo::Bar); // Name refers to local
// // variable `Foo`.
// }
// ```
Some(LexicalScopeBinding::Res(Res::Local(id))) => {
Some(*self.pat_span_map.get(&id).unwrap())
}
// Name matches item from a local name binding
// created by `use` declaration. For example:
// ```
// pub Foo: &str = "";
//
// mod submod {
// use super::Foo;
// println!("{}", Foo::Bar); // Name refers to local
// // binding `Foo`.
// }
// ```
Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
_ => None,
};
if let Some(span) = match_span {
Some((
vec![(span, String::from(""))],
format!("`{}` is defined here, but is not a type", ident),
Applicability::MaybeIncorrect,
))
} else {
None
}
} else {
None
};
(format!("use of undeclared type `{}`", ident), suggestion)
} else {
(
format!("use of undeclared crate or module `{}`", ident),
if ident.name == sym::alloc {
Some((
vec![],
String::from("add `extern crate alloc` to use the `alloc` crate"),
Applicability::MaybeIncorrect,
))
} else {
self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module)
.map(|sugg| {
(
vec![(ident.span, sugg.to_string())],
String::from("there is a crate or module with a similar name"),
Applicability::MaybeIncorrect,
)
})
},
)
}
} else {
let parent = path[i - 1].ident.name; let parent = path[i - 1].ident.name;
let parent = match parent { let parent = match parent {
// ::foo is mounted at the crate root for 2015, and is the extern // ::foo is mounted at the crate root for 2015, and is the extern
@ -1501,9 +1425,7 @@ impl<'a> Resolver<'a> {
"the list of imported crates".to_owned() "the list of imported crates".to_owned()
} }
kw::PathRoot | kw::Crate => "the crate root".to_owned(), kw::PathRoot | kw::Crate => "the crate root".to_owned(),
_ => { _ => format!("`{}`", parent),
format!("`{}`", parent)
}
}; };
let mut msg = format!("could not find `{}` in {}", ident, parent); let mut msg = format!("could not find `{}` in {}", ident, parent);
@ -1515,7 +1437,7 @@ impl<'a> Resolver<'a> {
ident, ident,
ns_to_try, ns_to_try,
parent_scope, parent_scope,
finalize, None,
false, false,
unusable_binding, unusable_binding,
).ok() ).ok()
@ -1526,7 +1448,7 @@ impl<'a> Resolver<'a> {
ident, ident,
ns_to_try, ns_to_try,
parent_scope, parent_scope,
finalize_full, Finalize::No,
&ribs[ns_to_try], &ribs[ns_to_try],
unusable_binding, unusable_binding,
) { ) {
@ -1540,8 +1462,8 @@ impl<'a> Resolver<'a> {
ident, ident,
scopes, scopes,
parent_scope, parent_scope,
finalize, None,
finalize.is_some(), false,
false, false,
unusable_binding, unusable_binding,
).ok() ).ok()
@ -1567,6 +1489,76 @@ impl<'a> Resolver<'a> {
}; };
} }
(msg, None) (msg, None)
} else if ident.name.as_str().chars().next().map_or(false, |c| c.is_ascii_uppercase()) {
// Check whether the name refers to an item in the value namespace.
let binding = if let Some(ribs) = ribs {
self.resolve_ident_in_lexical_scope(
ident,
ValueNS,
parent_scope,
Finalize::No,
&ribs[ValueNS],
unusable_binding,
)
} else {
None
};
let match_span = match binding {
// Name matches a local variable. For example:
// ```
// fn f() {
// let Foo: &str = "";
// println!("{}", Foo::Bar); // Name refers to local
// // variable `Foo`.
// }
// ```
Some(LexicalScopeBinding::Res(Res::Local(id))) => {
Some(*self.pat_span_map.get(&id).unwrap())
}
// Name matches item from a local name binding
// created by `use` declaration. For example:
// ```
// pub Foo: &str = "";
//
// mod submod {
// use super::Foo;
// println!("{}", Foo::Bar); // Name refers to local
// // binding `Foo`.
// }
// ```
Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span),
_ => None,
};
let suggestion = if let Some(span) = match_span {
Some((
vec![(span, String::from(""))],
format!("`{}` is defined here, but is not a type", ident),
Applicability::MaybeIncorrect,
))
} else {
None
};
(format!("use of undeclared type `{}`", ident), suggestion)
} else {
let suggestion = if ident.name == sym::alloc {
Some((
vec![],
String::from("add `extern crate alloc` to use the `alloc` crate"),
Applicability::MaybeIncorrect,
))
} else {
self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map(
|sugg| {
(
vec![(ident.span, sugg.to_string())],
String::from("there is a crate or module with a similar name"),
Applicability::MaybeIncorrect,
)
},
)
};
(format!("use of undeclared crate or module `{}`", ident), suggestion)
} }
} }
} }

View file

@ -1568,7 +1568,6 @@ impl<'a> Resolver<'a> {
path, path,
opt_ns, opt_ns,
parent_scope, parent_scope,
finalize_full,
ribs, ribs,
unusable_binding, unusable_binding,
module, module,