use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
use macros::{InvocationData, LegacyBinding, ParentScope};
-// NB: This module needs to be declared first so diagnostics are
+// N.B., this module needs to be declared first so diagnostics are
// registered before they are used.
mod diagnostics;
mod error_reporting;
// A minimal representation of a path segment. We use this in resolve because
// we synthesize 'path segments' which don't have the rest of an AST or HIR
-// PathSegment.
+// `PathSegment`.
#[derive(Clone, Copy, Debug)]
pub struct Segment {
ident: Ident,
self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
}
TyKind::ImplicitSelf => {
- let self_ty = keywords::SelfType.ident();
+ let self_ty = keywords::SelfUpper.ident();
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
.map_or(Def::Err, |d| d.def());
self.record_def(ty.id, PathResolution::new(def));
/// The current self item if inside an ADT (used for better errors).
current_self_item: Option<NodeId>,
- /// FIXME: Refactor things so that this is passed through arguments and not resolver.
+ /// FIXME: Refactor things so that these fields are passed through arguments and not resolver.
+ /// We are resolving a last import segment during import validation.
last_import_segment: bool,
+ /// This binding should be ignored during in-module resolution, so that we don't get
+ /// "self-confirming" import resolutions during import validation.
+ blacklisted_binding: Option<&'a NameBinding<'a>>,
/// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
macro_defs: FxHashMap<Mark, DefId>,
local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
- pub whitelisted_legacy_custom_derives: Vec<Name>,
pub found_unresolved_macro: bool,
/// List of crate local macros that we need to warn about as being unused.
components: &[&str],
is_value: bool
) -> hir::Path {
- let segments = iter::once(keywords::CrateRoot.ident())
+ let segments = iter::once(keywords::PathRoot.ident())
.chain(
crate_root.into_iter()
.chain(components.iter().cloned())
let path = if path_str.starts_with("::") {
ast::Path {
span,
- segments: iter::once(keywords::CrateRoot.ident())
+ segments: iter::once(keywords::PathRoot.ident())
.chain({
path_str.split("::").skip(1).map(Ident::from_str)
})
current_self_type: None,
current_self_item: None,
last_import_segment: false,
+ blacklisted_binding: None,
primitive_type_table: PrimitiveTypeTable::new(),
macro_defs,
local_macro_def_scopes: FxHashMap::default(),
name_already_seen: FxHashMap::default(),
- whitelisted_legacy_custom_derives: Vec::new(),
potentially_unused_imports: Vec::new(),
struct_constructors: Default::default(),
found_unresolved_macro: false,
let record_used = record_used_id.is_some();
assert!(ns == TypeNS || ns == ValueNS);
if ns == TypeNS {
- ident.span = if ident.name == keywords::SelfType.name() {
+ ident.span = if ident.name == keywords::SelfUpper.name() {
// FIXME(jseyfried) improve `Self` hygiene
ident.span.with_ctxt(SyntaxContext::empty())
} else {
result
}
- /// This is called to resolve a trait reference from an `impl` (i.e. `impl Trait for Foo`)
+ /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`)
fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
where F: FnOnce(&mut Resolver, Option<DefId>) -> T
{
let mut self_type_rib = Rib::new(NormalRibKind);
// plain insert (no renaming, types are not currently hygienic....)
- self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
+ self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
self.ribs[TypeNS].push(self_type_rib);
f(self);
self.ribs[TypeNS].pop();
{
let self_def = Def::SelfCtor(impl_id);
let mut self_type_rib = Rib::new(NormalRibKind);
- self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
+ self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def);
self.ribs[ValueNS].push(self_type_rib);
f(self);
self.ribs[ValueNS].pop();
self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
}
- // This has to happen *after* we determine which pat_idents are variants
+ // This has to happen *after* we determine which pat_idents are variants.
self.check_consistent_bindings(&arm.pats);
if let Some(ast::Guard::If(ref expr)) = arm.guard {
Def::StructCtor(..) | Def::VariantCtor(..) |
Def::Const(..) | Def::Static(..) => {
// This is unambiguously a fresh binding, either syntactically
- // (e.g. `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
- // to something unusable as a pattern (e.g. constructor function),
+ // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
+ // to something unusable as a pattern (e.g., constructor function),
// but we still conservatively report an error, see
// issues/33118#issuecomment-233962221 for one reason why.
resolve_error(
let item_span = path.last().unwrap().ident.span;
let (mod_prefix, mod_str) = if path.len() == 1 {
(String::new(), "this scope".to_string())
- } else if path.len() == 2 && path[0].ident.name == keywords::CrateRoot.name() {
+ } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() {
(String::new(), "the crate root".to_string())
} else {
let mod_path = &path[..path.len() - 1];
for (sp, variant_path, enum_path) in enum_candidates {
if sp.is_dummy() {
let msg = format!("there is an enum variant `{}`, \
- try using `{}`?",
- variant_path,
- enum_path);
+ try using `{}`?",
+ variant_path,
+ enum_path);
err.help(&msg);
} else {
err.span_suggestion_with_applicability(
let mut levenshtein_worked = false;
- // Try Levenshtein.
+ // Try Levenshtein algorithm.
if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected, span) {
err.span_label(ident_span, format!("did you mean `{}`?", candidate));
levenshtein_worked = true;
}
fn self_type_is_available(&mut self, span: Span) -> bool {
- let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
+ let binding = self.resolve_ident_in_lexical_scope(keywords::SelfUpper.ident(),
TypeNS, None, span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
}
fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool {
- let ident = Ident::new(keywords::SelfValue.name(), self_span);
+ let ident = Ident::new(keywords::SelfLower.name(), self_span);
let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span);
if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
}
let res = self.smart_resolve_path_fragment(
id,
None,
- &path[..qself.position + 1],
+ &path[..=qself.position],
span,
PathSource::TraitItem(ns),
CrateLint::QPathTrait {
};
if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
- path[0].ident.name != keywords::CrateRoot.name() &&
+ path[0].ident.name != keywords::PathRoot.name() &&
path[0].ident.name != keywords::DollarCrate.name() {
let unqualified_result = {
match self.resolve_path_without_parent_scope(
let name = ident.name;
allow_super &= ns == TypeNS &&
- (name == keywords::SelfValue.name() ||
+ (name == keywords::SelfLower.name() ||
name == keywords::Super.name());
if ns == TypeNS {
return PathResult::Failed(ident.span, msg, false);
}
if i == 0 {
- if name == keywords::SelfValue.name() {
+ if name == keywords::SelfLower.name() {
let mut ctxt = ident.span.ctxt().modern();
module = Some(ModuleOrUniformRoot::Module(
self.resolve_self(&mut ctxt, self.current_module)));
continue;
}
if name == keywords::Extern.name() ||
- name == keywords::CrateRoot.name() && ident.span.rust_2018() {
+ name == keywords::PathRoot.name() && ident.span.rust_2018() {
module = Some(ModuleOrUniformRoot::ExternPrelude);
continue;
}
- if name == keywords::CrateRoot.name() &&
+ if name == keywords::PathRoot.name() &&
ident.span.rust_2015() && self.session.rust_2018() {
// `::a::b` from 2015 macro on 2018 global edition
module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
continue;
}
- if name == keywords::CrateRoot.name() ||
+ if name == keywords::PathRoot.name() ||
name == keywords::Crate.name() ||
name == keywords::DollarCrate.name() {
// `::a::b`, `crate::a::b` or `$crate::a::b`
// Report special messages for path segment keywords in wrong positions.
if ident.is_path_segment_keyword() && i != 0 {
- let name_str = if name == keywords::CrateRoot.name() {
+ let name_str = if name == keywords::PathRoot.name() {
"crate root".to_string()
} else {
format!("`{}`", name)
};
- let msg = if i == 1 && path[0].ident.name == keywords::CrateRoot.name() {
+ let msg = if i == 1 && path[0].ident.name == keywords::PathRoot.name() {
format!("global paths cannot start with {}", name_str)
} else {
format!("{} in paths can only be used in start position", name_str)
// We're only interested in `use` paths which should start with
// `{{root}}` or `extern` currently.
- if first_name != keywords::Extern.name() && first_name != keywords::CrateRoot.name() {
+ if first_name != keywords::Extern.name() && first_name != keywords::PathRoot.name() {
return
}
Some(Segment { ident, .. }) if ident.name == keywords::Crate.name() => return,
// Otherwise go below to see if it's an extern crate
Some(_) => {}
- // If the path has length one (and it's `CrateRoot` most likely)
+ // If the path has length one (and it's `PathRoot` most likely)
// then we don't know whether we're gonna be importing a crate or an
// item in our crate. Defer this lint to elsewhere
None => return,
for pat in pats {
this.resolve_pattern(pat, PatternSource::WhileLet, &mut bindings_list);
}
- // This has to happen *after* we determine which pat_idents are variants
+ // This has to happen *after* we determine which pat_idents are variants.
this.check_consistent_bindings(pats);
this.visit_block(block);
this.ribs[ValueNS].pop();
/// When name resolution fails, this method can be used to look up candidate
/// entities with the expected name. It allows filtering them using the
/// supplied predicate (which should be used to only accept the types of
- /// definitions expected e.g. traits). The lookup spans across all crates.
+ /// definitions expected e.g., traits). The lookup spans across all crates.
///
/// NOTE: The method does not look into imports, but this is not a problem,
/// since we report the definitions (thus, the de-aliased imports).
} else {
let ctxt = ident.span.ctxt();
Some(Segment::from_ident(Ident::new(
- keywords::CrateRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt)
+ keywords::PathRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt)
)))
};
}
fn is_self_type(path: &[Segment], namespace: Namespace) -> bool {
- namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfType.name()
+ namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfUpper.name()
}
fn is_self_value(path: &[Segment], namespace: Namespace) -> bool {
- namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfValue.name()
+ namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfLower.name()
}
fn names_to_string(idents: &[Ident]) -> String {
let mut result = String::new();
for (i, ident) in idents.iter()
- .filter(|ident| ident.name != keywords::CrateRoot.name())
+ .filter(|ident| ident.name != keywords::PathRoot.name())
.enumerate() {
if i > 0 {
result.push_str("::");