Report special messages for path segment keywords in wrong positions
This commit is contained in:
parent
2e9b89ddc5
commit
90f5cfdfbd
8 changed files with 47 additions and 18 deletions
|
|
@ -2865,12 +2865,13 @@ impl<'a> Resolver<'a> {
|
|||
debug!("resolve_path ident {} {:?}", i, ident);
|
||||
let is_last = i == path.len() - 1;
|
||||
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
|
||||
let name = ident.node.name;
|
||||
|
||||
if i == 0 && ns == TypeNS && ident.node.name == keywords::SelfValue.name() {
|
||||
if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() {
|
||||
let mut ctxt = ident.node.ctxt.modern();
|
||||
module = Some(self.resolve_self(&mut ctxt, self.current_module));
|
||||
continue
|
||||
} else if allow_super && ns == TypeNS && ident.node.name == keywords::Super.name() {
|
||||
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
|
||||
let mut ctxt = ident.node.ctxt.modern();
|
||||
let self_module = match i {
|
||||
0 => self.resolve_self(&mut ctxt, self.current_module),
|
||||
|
|
@ -2887,19 +2888,42 @@ impl<'a> Resolver<'a> {
|
|||
allow_super = false;
|
||||
|
||||
if ns == TypeNS {
|
||||
if (i == 0 && ident.node.name == keywords::CrateRoot.name()) ||
|
||||
(i == 1 && ident.node.name == keywords::Crate.name() &&
|
||||
if (i == 0 && name == keywords::CrateRoot.name()) ||
|
||||
(i == 1 && name == keywords::Crate.name() &&
|
||||
path[0].node.name == keywords::CrateRoot.name()) {
|
||||
// `::a::b` or `::crate::a::b`
|
||||
module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
|
||||
continue
|
||||
} else if i == 0 && ident.node.name == keywords::DollarCrate.name() {
|
||||
} else if i == 0 && name == keywords::DollarCrate.name() {
|
||||
// `$crate::a::b`
|
||||
module = Some(self.resolve_crate_root(ident.node.ctxt));
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Report special messages for path segment keywords in wrong positions.
|
||||
if name == keywords::CrateRoot.name() && i != 0 ||
|
||||
name == keywords::DollarCrate.name() && i != 0 ||
|
||||
name == keywords::SelfValue.name() && i != 0 ||
|
||||
name == keywords::SelfType.name() && i != 0 ||
|
||||
name == keywords::Super.name() && i != 0 ||
|
||||
name == keywords::Crate.name() && i != 1 &&
|
||||
path[0].node.name != keywords::CrateRoot.name() {
|
||||
let name_str = if name == keywords::CrateRoot.name() {
|
||||
format!("crate root")
|
||||
} else {
|
||||
format!("`{}`", name)
|
||||
};
|
||||
let msg = if i == 1 && path[0].node.name == keywords::CrateRoot.name() {
|
||||
format!("global paths cannot start with {}", name_str)
|
||||
} else if i == 0 && name == keywords::Crate.name() {
|
||||
format!("{} can only be used in absolute paths", name_str)
|
||||
} else {
|
||||
format!("{} in paths can only be used in start position", name_str)
|
||||
};
|
||||
return PathResult::Failed(ident.span, msg, false);
|
||||
}
|
||||
|
||||
let binding = if let Some(module) = module {
|
||||
self.resolve_ident_in_module(module, ident.node, ns, false, record_used, path_span)
|
||||
} else if opt_ns == Some(MacroNS) {
|
||||
|
|
@ -2948,7 +2972,7 @@ impl<'a> Resolver<'a> {
|
|||
let msg = if module.and_then(ModuleData::def) == self.graph_root.def() {
|
||||
let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
|
||||
let mut candidates =
|
||||
self.lookup_import_candidates(ident.node.name, TypeNS, is_mod);
|
||||
self.lookup_import_candidates(name, TypeNS, is_mod);
|
||||
candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string()));
|
||||
if let Some(candidate) = candidates.get(0) {
|
||||
format!("Did you mean `{}`?", candidate.path)
|
||||
|
|
|
|||
|
|
@ -606,10 +606,16 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
|
|||
let module_result = self.resolve_path(&module_path, None, true, span);
|
||||
let module = match module_result {
|
||||
PathResult::Module(module) => module,
|
||||
PathResult::Failed(span, msg, _) => {
|
||||
PathResult::Failed(span, msg, false) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||
return None;
|
||||
}
|
||||
PathResult::Failed(span, msg, true) => {
|
||||
let (mut self_path, mut self_result) = (module_path.clone(), None);
|
||||
if !self_path.is_empty() &&
|
||||
!token::Ident(self_path[0].node).is_path_segment_keyword()
|
||||
!token::Ident(self_path[0].node).is_path_segment_keyword() &&
|
||||
!(self_path.len() > 1 &&
|
||||
token::Ident(self_path[1].node).is_path_segment_keyword())
|
||||
{
|
||||
self_path[0].node.name = keywords::SelfValue.name();
|
||||
self_result = Some(self.resolve_path(&self_path, None, false, span));
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ mod a {}
|
|||
macro_rules! m {
|
||||
() => {
|
||||
use a::$crate; //~ ERROR unresolved import `a::$crate`
|
||||
use a::$crate::b; //~ ERROR unresolved import `a::$crate`
|
||||
type A = a::$crate; //~ ERROR cannot find type `$crate` in module `a`
|
||||
use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position
|
||||
type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ struct S;
|
|||
|
||||
mod m {
|
||||
fn f() {
|
||||
let s = crate::S; //~ ERROR undeclared type or module `crate`
|
||||
let s = crate::S; //~ ERROR `crate` can only be used in absolute paths
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ mod m {
|
|||
pub struct Z;
|
||||
pub struct S1(crate (::m::Z)); // OK
|
||||
pub struct S2(::crate ::m::Z); // OK
|
||||
pub struct S3(crate ::m::Z); //~ ERROR undeclared type or module `crate`
|
||||
pub struct S3(crate ::m::Z); //~ ERROR `crate` can only be used in absolute paths
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@
|
|||
#![feature(crate_in_paths)]
|
||||
|
||||
fn main() {
|
||||
let crate = 0; //~ ERROR cannot find unit struct/variant or constant `crate` in this scope
|
||||
let crate = 0; //~ ERROR `crate` can only be used in absolute paths
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use super::f; //~ ERROR unresolved import `super` [E0432]
|
||||
//~^ There are too many initial `super`s.
|
||||
use super::f; //~ ERROR There are too many initial `super`s
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ struct S;
|
|||
struct Z;
|
||||
|
||||
mod foo {
|
||||
use ::super::{S, Z}; //~ ERROR unresolved import `super`
|
||||
use ::super::{S, Z}; //~ ERROR global paths cannot start with `super`
|
||||
|
||||
pub fn g() {
|
||||
use ::super::main; //~ ERROR unresolved import `super`
|
||||
main();
|
||||
use ::super::main; //~ ERROR global paths cannot start with `super`
|
||||
main(); //~ ERROR cannot find function `main` in this scope
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue