#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
+#![feature(drain_filter)]
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(format_args_capture)]
#![feature(iter_zip)]
+#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
+#[macro_use]
+extern crate tracing;
+
pub use rustc_hir::def::{Namespace, PerNS};
use Determinacy::*;
use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId};
+use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::TraitCandidate;
use rustc_index::vec::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::hir::exports::ExportMap;
-use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn};
use rustc_middle::span_bug;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, MainDefinition, ResolverOutputs};
+use rustc_session::cstore::{CrateStore, MetadataLoaderDyn};
use rustc_session::lint;
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
use rustc_session::Session;
/// parameter list.
NameAlreadyUsedInParameterList(Symbol, Span),
/// Error E0407: method is not a member of trait.
- MethodNotMemberOfTrait(Symbol, &'a str),
+ MethodNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0437: type is not a member of trait.
- TypeNotMemberOfTrait(Symbol, &'a str),
+ TypeNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0438: const is not a member of trait.
- ConstNotMemberOfTrait(Symbol, &'a str),
+ ConstNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0408: variable `{}` is not bound in all patterns.
VariableNotBoundInPattern(&'a BindingError),
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
fn same_def(lhs: Self, rhs: Self) -> bool {
match (lhs, rhs) {
(ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => {
- lhs.def_id() == rhs.def_id()
+ ptr::eq(lhs, rhs)
}
(
ModuleOrUniformRoot::CrateRootAndExternPrelude,
/// What kind of module this is, because this may not be a `mod`.
kind: ModuleKind,
- /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
- /// This may be the crate root.
- nearest_parent_mod: DefId,
-
/// Mapping between names and their (possibly in-progress) resolutions in this module.
/// Resolutions in modules from other crates are not populated until accessed.
lazy_resolutions: Resolutions<'a>,
fn new(
parent: Option<Module<'a>>,
kind: ModuleKind,
- nearest_parent_mod: DefId,
expansion: ExpnId,
span: Span,
+ no_implicit_prelude: bool,
) -> Self {
+ let is_foreign = match kind {
+ ModuleKind::Def(_, def_id, _) => !def_id.is_local(),
+ ModuleKind::Block(_) => false,
+ };
ModuleData {
parent,
kind,
- nearest_parent_mod,
lazy_resolutions: Default::default(),
- populate_on_access: Cell::new(!nearest_parent_mod.is_local()),
+ populate_on_access: Cell::new(is_foreign),
unexpanded_invocations: Default::default(),
- no_implicit_prelude: false,
+ no_implicit_prelude,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new(Vec::new()),
traits: RefCell::new(None),
}
}
- fn def_id(&self) -> Option<DefId> {
+ fn def_id(&self) -> DefId {
+ self.opt_def_id().expect("`ModuleData::def_id` is called on a block module")
+ }
+
+ fn opt_def_id(&self) -> Option<DefId> {
match self.kind {
ModuleKind::Def(_, def_id, _) => Some(def_id),
_ => None,
}
}
+ /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
+ /// This may be the crate root.
+ fn nearest_parent_mod(&self) -> DefId {
+ match self.kind {
+ ModuleKind::Def(DefKind::Mod, def_id, _) => def_id,
+ _ => self.parent.expect("non-root module without parent").nearest_parent_mod(),
+ }
+ }
+
fn is_ancestor_of(&self, mut other: &Self) -> bool {
while !ptr::eq(self, other) {
if let Some(parent) = other.parent {
/// `CrateNum` resolutions of `extern crate` items.
extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
- export_map: ExportMap<LocalDefId>,
+ export_map: ExportMap,
trait_map: Option<NodeMap<Vec<TraitCandidate>>>,
/// A map from nodes to anonymous modules.
/// some AST passes can generate identifiers that only resolve to local or
/// language items.
empty_module: Module<'a>,
- module_map: FxHashMap<LocalDefId, Module<'a>>,
- extern_module_map: FxHashMap<DefId, Module<'a>>,
+ module_map: FxHashMap<DefId, Module<'a>>,
binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
underscore_disambiguator: u32,
next_node_id: NodeId,
- def_id_to_span: IndexVec<LocalDefId, Span>,
-
node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
/// A list of proc macro LocalDefIds, written out in the order in which
/// they are declared in the static array generated by proc_macro_harness.
proc_macros: Vec<NodeId>,
+ confused_type_with_std_module: FxHashMap<Span, Span>,
}
/// Nothing really interesting here; it just provides memory for the rest of the crate.
}
impl<'a> ResolverArenas<'a> {
- fn alloc_module(&'a self, module: ModuleData<'a>) -> Module<'a> {
- let module = self.modules.alloc(module);
- if module.def_id().map_or(true, |def_id| def_id.is_local()) {
+ fn new_module(
+ &'a self,
+ parent: Option<Module<'a>>,
+ kind: ModuleKind,
+ expn_id: ExpnId,
+ span: Span,
+ no_implicit_prelude: bool,
+ module_map: &mut FxHashMap<DefId, Module<'a>>,
+ ) -> Module<'a> {
+ let module =
+ self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude));
+ let def_id = module.opt_def_id();
+ if def_id.map_or(true, |def_id| def_id.is_local()) {
self.local_modules.borrow_mut().push(module);
}
+ if let Some(def_id) = def_id {
+ module_map.insert(def_id, module);
+ }
module
}
fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> {
}
}
+ #[inline]
+ fn def_span(&self, id: LocalDefId) -> Span {
+ self.definitions.def_span(id)
+ }
+
fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
if let Some(def_id) = def_id.as_local() {
self.item_generics_num_lifetimes[&def_id]
self.legacy_const_generic_args(expr)
}
- fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
+ fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&id).cloned()
}
disambiguator
};
- let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator);
-
- assert_eq!(self.def_id_to_span.push(span), def_id);
+ let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator, span);
// Some things for which we allocate `LocalDefId`s don't correspond to
// anything in the AST, so they don't have a `NodeId`. For these cases
true
}
+ #[inline]
+ fn def_span(&self, id: LocalDefId) -> Span {
+ self.resolver.def_span(id)
+ }
+
#[inline]
fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
self.resolver.def_path_hash(def_id)
metadata_loader: Box<MetadataLoaderDyn>,
arenas: &'a ResolverArenas<'a>,
) -> Resolver<'a> {
- let root_local_def_id = LocalDefId { local_def_index: CRATE_DEF_INDEX };
- let root_def_id = root_local_def_id.to_def_id();
- let root_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
- let graph_root = arenas.alloc_module(ModuleData {
- no_implicit_prelude: session.contains_name(&krate.attrs, sym::no_implicit_prelude),
- ..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
- });
- let empty_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty);
- let empty_module = arenas.alloc_module(ModuleData {
- no_implicit_prelude: true,
- ..ModuleData::new(
- Some(graph_root),
- empty_module_kind,
- root_def_id,
- ExpnId::root(),
- DUMMY_SP,
- )
- });
+ let root_def_id = CRATE_DEF_ID.to_def_id();
let mut module_map = FxHashMap::default();
- module_map.insert(root_local_def_id, graph_root);
+ let graph_root = arenas.new_module(
+ None,
+ ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+ ExpnId::root(),
+ krate.span,
+ session.contains_name(&krate.attrs, sym::no_implicit_prelude),
+ &mut module_map,
+ );
+ let empty_module = arenas.new_module(
+ None,
+ ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
+ ExpnId::root(),
+ DUMMY_SP,
+ true,
+ &mut FxHashMap::default(),
+ );
- let definitions = Definitions::new(session.local_stable_crate_id());
+ let definitions = Definitions::new(session.local_stable_crate_id(), krate.span);
let root = definitions.get_root_def();
let mut visibilities = FxHashMap::default();
- visibilities.insert(root_local_def_id, ty::Visibility::Public);
+ visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public);
- let mut def_id_to_span = IndexVec::default();
- assert_eq!(def_id_to_span.push(rustc_span::DUMMY_SP), root);
let mut def_id_to_node_id = IndexVec::default();
assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root);
let mut node_id_to_def_id = FxHashMap::default();
empty_module,
module_map,
block_map: Default::default(),
- extern_module_map: FxHashMap::default(),
binding_parent_modules: FxHashMap::default(),
ast_transform_scopes: FxHashMap::default(),
.collect(),
lint_buffer: LintBuffer::default(),
next_node_id: NodeId::from_u32(1),
- def_id_to_span,
node_id_to_def_id,
def_id_to_node_id,
placeholder_field_indices: Default::default(),
main_def: Default::default(),
trait_impls: Default::default(),
proc_macros: Default::default(),
+ confused_type_with_std_module: Default::default(),
};
let root_parent_scope = ParentScope::module(graph_root, &resolver);
resolver
}
+ fn new_module(
+ &mut self,
+ parent: Option<Module<'a>>,
+ kind: ModuleKind,
+ expn_id: ExpnId,
+ span: Span,
+ no_implicit_prelude: bool,
+ ) -> Module<'a> {
+ let module_map = &mut self.module_map;
+ self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map)
+ }
+
fn create_stable_hashing_context(&self) -> ExpandHasher<'_, 'a> {
ExpandHasher {
source_map: CachingSourceMapView::new(self.session.source_map()),
let maybe_unused_extern_crates = self.maybe_unused_extern_crates;
let glob_map = self.glob_map;
let main_def = self.main_def;
+ let confused_type_with_std_module = self.confused_type_with_std_module;
ResolverOutputs {
definitions,
cstore: Box::new(self.crate_loader.into_cstore()),
main_def,
trait_impls: self.trait_impls,
proc_macros,
+ confused_type_with_std_module,
}
}
.iter()
.map(|(ident, entry)| (ident.name, entry.introduced_by_item))
.collect(),
- main_def: self.main_def.clone(),
+ main_def: self.main_def,
trait_impls: self.trait_impls.clone(),
proc_macros,
+ confused_type_with_std_module: self.confused_type_with_std_module.clone(),
}
}
if let Some(module) = current_trait {
if self.trait_may_have_item(Some(module), assoc_item) {
- let def_id = module.def_id().unwrap();
+ let def_id = module.def_id();
found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
}
}
import_ids
}
- fn new_module(
- &self,
- parent: Module<'a>,
- kind: ModuleKind,
- nearest_parent_mod: DefId,
- expn_id: ExpnId,
- span: Span,
- ) -> Module<'a> {
- let module = ModuleData::new(Some(parent), kind, nearest_parent_mod, expn_id, span);
- self.arenas.alloc_module(module)
- }
-
fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
let ident = ident.normalize_to_macros_2_0();
let disambiguator = if ident.name == kw::Underscore {
derive_fallback_lint_id: Option<NodeId>,
) -> Option<(Module<'a>, Option<NodeId>)> {
if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
- return Some((self.macro_def_scope(ctxt.remove_mark()), None));
+ return Some((self.expn_def_scope(ctxt.remove_mark()), None));
}
if let ModuleKind::Block(..) = module.kind {
ModuleOrUniformRoot::Module(m) => {
if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
tmp_parent_scope =
- ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
+ ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
adjusted_parent_scope = &tmp_parent_scope;
}
}
ctxt.adjust(ExpnId::root())
};
let module = match mark {
- Some(def) => self.macro_def_scope(def),
+ Some(def) => self.expn_def_scope(def),
None => {
debug!(
"resolve_crate_root({:?}): found no mark (ident.span = {:?})",
return self.graph_root;
}
};
- let module = self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.nearest_parent_mod });
+ let module = self.expect_module(
+ module.opt_def_id().map_or(LOCAL_CRATE, |def_id| def_id.krate).as_def_id(),
+ );
debug!(
"resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
ident,
}
fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
- let mut module = self.get_module(module.nearest_parent_mod);
+ let mut module = self.expect_module(module.nearest_parent_mod());
while module.span.ctxt().normalize_to_macros_2_0() != *ctxt {
- let parent = module.parent.unwrap_or_else(|| self.macro_def_scope(ctxt.remove_mark()));
- module = self.get_module(parent.nearest_parent_mod);
+ let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark()));
+ module = self.expect_module(parent.nearest_parent_mod());
}
module
}
(format!("use of undeclared type `{}`", ident), suggestion)
} else {
- (format!("use of undeclared crate or module `{}`", ident), None)
+ (
+ format!("use of undeclared crate or module `{}`", ident),
+ 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;
}
fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
- vis.is_accessible_from(module.nearest_parent_mod, self)
+ vis.is_accessible_from(module.nearest_parent_mod(), self)
}
fn set_binding_parent_module(&mut self, binding: &'a NameBinding<'a>, module: Module<'a>) {
self.binding_parent_modules.get(&PtrKey(modularized)),
) {
(Some(macro_rules), Some(modularized)) => {
- macro_rules.nearest_parent_mod == modularized.nearest_parent_mod
+ macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
&& modularized.is_ancestor_of(macro_rules)
}
_ => false,
(None, false)
};
if !candidates.is_empty() {
- diagnostics::show_candidates(&mut err, span, &candidates, instead, found_use);
+ diagnostics::show_candidates(
+ &self.definitions,
+ self.session,
+ &mut err,
+ span,
+ &candidates,
+ instead,
+ found_use,
+ );
} else if let Some((span, msg, sugg, appl)) = suggestion {
err.span_suggestion(span, msg, sugg, appl);
}
}
let container = match parent.kind {
- ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id().unwrap()),
+ ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()),
ModuleKind::Block(..) => "block",
};
} else {
self.crate_loader.maybe_process_path_extern(ident.name)?
};
- let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
+ let crate_root = self.expect_module(crate_id.as_def_id());
Some(
(crate_root, ty::Visibility::Public, DUMMY_SP, LocalExpnId::ROOT)
.to_name_binding(self.arenas),
tokens: None,
}
};
- let module = self.get_module(module_id);
+ let module = self.expect_module(module_id);
let parent_scope = &ParentScope::module(module, self);
let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
Ok((path, res))
/// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
#[inline]
pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
- if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None }
+ def_id.as_local().map(|def_id| self.definitions.def_span(def_id))
}
/// Checks if an expression refers to a function marked with