summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_resolve/src/lib.rs167
1 files changed, 81 insertions, 86 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 62843c651..8aebb7da1 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -4,15 +4,15 @@
//! Paths in macros, imports, expressions, types, patterns are resolved here.
//! Label and lifetime names are resolved here as well.
//!
-//! Type-relative name resolution (methods, fields, associated items) happens in `rustc_typeck`.
+//! Type-relative name resolution (methods, fields, associated items) happens in `rustc_hir_analysis`.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
+#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
-#![feature(let_else)]
#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
@@ -41,12 +41,12 @@ use rustc_hir::TraitCandidate;
use rustc_index::vec::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::metadata::ModChild;
-use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::span_bug;
-use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools, ResolverOutputs};
+use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools};
+use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
use rustc_query_system::ich::StableHashingContext;
-use rustc_session::cstore::{CrateStore, CrateStoreDyn, MetadataLoaderDyn};
+use rustc_session::cstore::{CrateStore, MetadataLoaderDyn};
use rustc_session::lint::LintBuffer;
use rustc_session::Session;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
@@ -57,23 +57,22 @@ use rustc_span::{Span, DUMMY_SP};
use smallvec::{smallvec, SmallVec};
use std::cell::{Cell, RefCell};
use std::collections::BTreeSet;
-use std::{cmp, fmt, ptr};
-use tracing::debug;
+use std::{fmt, ptr};
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use imports::{Import, ImportKind, ImportResolver, NameResolution};
use late::{HasGenericParams, PathSource, PatternSource};
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
-use crate::access_levels::AccessLevelsVisitor;
+use crate::effective_visibilities::EffectiveVisibilitiesVisitor;
type Res = def::Res<NodeId>;
-mod access_levels;
mod build_reduced_graph;
mod check_unused;
mod def_collector;
mod diagnostics;
+mod effective_visibilities;
mod ident;
mod imports;
mod late;
@@ -108,7 +107,6 @@ enum Scope<'a> {
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
// lint if it should be reported.
Module(Module<'a>, Option<NodeId>),
- RegisteredAttrs,
MacroUsePrelude,
BuiltinAttrs,
ExternPrelude,
@@ -165,7 +163,6 @@ enum ImplTraitContext {
Universal(LocalDefId),
}
-#[derive(Eq)]
struct BindingError {
name: Symbol,
origin: BTreeSet<Span>,
@@ -173,24 +170,6 @@ struct BindingError {
could_be_path: bool,
}
-impl PartialOrd for BindingError {
- fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl PartialEq for BindingError {
- fn eq(&self, other: &BindingError) -> bool {
- self.name == other.name
- }
-}
-
-impl Ord for BindingError {
- fn cmp(&self, other: &BindingError) -> cmp::Ordering {
- self.name.cmp(&other.name)
- }
-}
-
enum ResolutionError<'a> {
/// Error E0401: can't use type or const parameters from outer function.
GenericParamsFromOuterFunction(Res, HasGenericParams),
@@ -258,6 +237,8 @@ enum ResolutionError<'a> {
trait_item_span: Span,
code: rustc_errors::DiagnosticId,
},
+ /// Error E0201: multiple impl items for the same trait item.
+ TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
/// Inline asm `sym` operand must refer to a `fn` or `static`.
InvalidAsmSym,
}
@@ -650,7 +631,7 @@ pub struct NameBinding<'a> {
ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>,
expansion: LocalExpnId,
span: Span,
- vis: ty::Visibility,
+ vis: ty::Visibility<DefId>,
}
pub trait ToNameBinding<'a> {
@@ -696,6 +677,8 @@ struct UseError<'a> {
/// Path `Segment`s at the place of use that failed. Used for accurate suggestion after telling
/// the user to import the item directly.
path: Vec<Segment>,
+ /// Whether the expected source is a call
+ is_call: bool,
}
#[derive(Clone, Copy, PartialEq, Debug)]
@@ -847,7 +830,7 @@ impl<'a> NameBinding<'a> {
}
}
-#[derive(Debug, Default, Clone)]
+#[derive(Default, Clone)]
pub struct ExternPreludeEntry<'a> {
extern_crate_item: Option<&'a NameBinding<'a>>,
pub introduced_by_item: bool,
@@ -913,11 +896,6 @@ pub struct Resolver<'a> {
label_res_map: NodeMap<NodeId>,
/// Resolutions for lifetimes.
lifetimes_res_map: NodeMap<LifetimeRes>,
- /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
- /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
- /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
- /// field from the original parameter 'a to the new parameter 'a1.
- generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
/// Lifetime parameters that lowering will have to introduce.
extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
@@ -976,7 +954,6 @@ pub struct Resolver<'a> {
/// A small map keeping true kinds of built-in macros that appear to be fn-like on
/// the surface (`macro` items in libcore), but are actually attributes or derives.
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
- registered_attrs: FxHashSet<Ident>,
registered_tools: RegisteredTools,
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
macro_map: FxHashMap<DefId, MacroData>,
@@ -1020,7 +997,7 @@ pub struct Resolver<'a> {
/// Table for mapping struct IDs into struct constructor IDs,
/// it's not used during normal resolution, only for better error reporting.
/// Also includes of list of each fields visibility
- struct_constructors: DefIdMap<(Res, ty::Visibility, Vec<ty::Visibility>)>,
+ struct_constructors: DefIdMap<(Res, ty::Visibility<DefId>, Vec<ty::Visibility<DefId>>)>,
/// Features enabled for this crate.
active_features: FxHashSet<Symbol>,
@@ -1054,7 +1031,7 @@ pub struct Resolver<'a> {
proc_macros: Vec<NodeId>,
confused_type_with_std_module: FxHashMap<Span, Span>,
- access_levels: AccessLevels,
+ effective_visibilities: EffectiveVisibilities,
}
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1253,8 +1230,7 @@ impl<'a> Resolver<'a> {
}
}
- let (registered_attrs, registered_tools) =
- macros::registered_attrs_and_tools(session, &krate.attrs);
+ let registered_tools = macros::registered_tools(session, &krate.attrs);
let features = session.features_untracked();
@@ -1282,7 +1258,6 @@ impl<'a> Resolver<'a> {
import_res_map: Default::default(),
label_res_map: Default::default(),
lifetimes_res_map: Default::default(),
- generics_def_id_map: Vec::new(),
extra_lifetime_params_map: Default::default(),
extern_crate_map: Default::default(),
reexport_map: FxHashMap::default(),
@@ -1319,7 +1294,6 @@ impl<'a> Resolver<'a> {
macro_names: FxHashSet::default(),
builtin_macros: Default::default(),
builtin_macro_kinds: Default::default(),
- registered_attrs,
registered_tools,
macro_use_prelude: FxHashMap::default(),
macro_map: FxHashMap::default(),
@@ -1361,7 +1335,7 @@ impl<'a> Resolver<'a> {
trait_impls: Default::default(),
proc_macros: Default::default(),
confused_type_with_std_module: Default::default(),
- access_levels: Default::default(),
+ effective_visibilities: Default::default(),
};
let root_parent_scope = ParentScope::module(graph_root, &resolver);
@@ -1404,9 +1378,7 @@ impl<'a> Resolver<'a> {
Default::default()
}
- pub fn into_outputs(
- self,
- ) -> (Definitions, Box<CrateStoreDyn>, ResolverOutputs, ty::ResolverAstLowering) {
+ pub fn into_outputs(self) -> ResolverOutputs {
let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
let definitions = self.definitions;
let cstore = Box::new(self.crate_loader.into_cstore());
@@ -1421,13 +1393,14 @@ impl<'a> Resolver<'a> {
let glob_map = self.glob_map;
let main_def = self.main_def;
let confused_type_with_std_module = self.confused_type_with_std_module;
- let access_levels = self.access_levels;
- let resolutions = ResolverOutputs {
+ let effective_visibilities = self.effective_visibilities;
+ let global_ctxt = ResolverGlobalCtxt {
+ cstore,
source_span,
expn_that_defined,
visibilities,
has_pub_restricted,
- access_levels,
+ effective_visibilities,
extern_crate_map,
reexport_map,
glob_map,
@@ -1444,13 +1417,12 @@ impl<'a> Resolver<'a> {
confused_type_with_std_module,
registered_tools: self.registered_tools,
};
- let resolutions_lowering = ty::ResolverAstLowering {
+ let ast_lowering = ty::ResolverAstLowering {
legacy_const_generic_args: self.legacy_const_generic_args,
partial_res_map: self.partial_res_map,
import_res_map: self.import_res_map,
label_res_map: self.label_res_map,
lifetimes_res_map: self.lifetimes_res_map,
- generics_def_id_map: self.generics_def_id_map,
extra_lifetime_params_map: self.extra_lifetime_params_map,
next_node_id: self.next_node_id,
node_id_to_def_id: self.node_id_to_def_id,
@@ -1458,16 +1430,15 @@ impl<'a> Resolver<'a> {
trait_map: self.trait_map,
builtin_macro_kinds: self.builtin_macro_kinds,
};
- (definitions, cstore, resolutions, resolutions_lowering)
+ ResolverOutputs { definitions, global_ctxt, ast_lowering }
}
- pub fn clone_outputs(
- &self,
- ) -> (Definitions, Box<CrateStoreDyn>, ResolverOutputs, ty::ResolverAstLowering) {
+ pub fn clone_outputs(&self) -> ResolverOutputs {
let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect();
let definitions = self.definitions.clone();
let cstore = Box::new(self.cstore().clone());
- let resolutions = ResolverOutputs {
+ let global_ctxt = ResolverGlobalCtxt {
+ cstore,
source_span: self.source_span.clone(),
expn_that_defined: self.expn_that_defined.clone(),
visibilities: self.visibilities.clone(),
@@ -1487,15 +1458,14 @@ impl<'a> Resolver<'a> {
proc_macros,
confused_type_with_std_module: self.confused_type_with_std_module.clone(),
registered_tools: self.registered_tools.clone(),
- access_levels: self.access_levels.clone(),
+ effective_visibilities: self.effective_visibilities.clone(),
};
- let resolutions_lowering = ty::ResolverAstLowering {
+ let ast_lowering = ty::ResolverAstLowering {
legacy_const_generic_args: self.legacy_const_generic_args.clone(),
partial_res_map: self.partial_res_map.clone(),
import_res_map: self.import_res_map.clone(),
label_res_map: self.label_res_map.clone(),
lifetimes_res_map: self.lifetimes_res_map.clone(),
- generics_def_id_map: self.generics_def_id_map.clone(),
extra_lifetime_params_map: self.extra_lifetime_params_map.clone(),
next_node_id: self.next_node_id.clone(),
node_id_to_def_id: self.node_id_to_def_id.clone(),
@@ -1503,7 +1473,7 @@ impl<'a> Resolver<'a> {
trait_map: self.trait_map.clone(),
builtin_macro_kinds: self.builtin_macro_kinds.clone(),
};
- (definitions, cstore, resolutions, resolutions_lowering)
+ ResolverOutputs { definitions, global_ctxt, ast_lowering }
}
fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
@@ -1551,8 +1521,8 @@ impl<'a> Resolver<'a> {
pub fn resolve_crate(&mut self, krate: &Crate) {
self.session.time("resolve_crate", || {
self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
- self.session.time("resolve_access_levels", || {
- AccessLevelsVisitor::compute_access_levels(self, krate)
+ self.session.time("compute_effective_visibilities", || {
+ EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate)
});
self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
@@ -1821,7 +1791,11 @@ impl<'a> Resolver<'a> {
self.pat_span_map.insert(node, span);
}
- fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
+ fn is_accessible_from(
+ &self,
+ vis: ty::Visibility<impl Into<DefId>>,
+ module: Module<'a>,
+ ) -> bool {
vis.is_accessible_from(module.nearest_parent_mod(), self)
}
@@ -1875,10 +1849,8 @@ impl<'a> Resolver<'a> {
self.crate_loader.maybe_process_path_extern(ident.name)?
};
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),
- )
+ let vis = ty::Visibility::<LocalDefId>::Public;
+ Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas))
}
})
}
@@ -1911,12 +1883,10 @@ impl<'a> Resolver<'a> {
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
- PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
- Some(path_res.base_res())
+ PathResult::NonModule(path_res) => path_res.full_res(),
+ PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => {
+ None
}
- PathResult::Module(ModuleOrUniformRoot::ExternPrelude)
- | PathResult::NonModule(..)
- | PathResult::Failed { .. } => None,
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
}
}
@@ -1940,12 +1910,27 @@ impl<'a> Resolver<'a> {
}
}
+ /// For rustdoc.
+ pub fn get_partial_res(&self, node_id: NodeId) -> Option<PartialRes> {
+ self.partial_res_map.get(&node_id).copied()
+ }
+
/// 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> {
def_id.as_local().map(|def_id| self.source_span[def_id])
}
+ /// Retrieves the name of the given `DefId`.
+ #[inline]
+ pub fn opt_name(&self, def_id: DefId) -> Option<Symbol> {
+ let def_key = match def_id.as_local() {
+ Some(def_id) => self.definitions.def_key(def_id),
+ None => self.cstore().def_key(def_id),
+ };
+ def_key.get_opt_name()
+ }
+
/// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute.
@@ -1957,12 +1942,8 @@ impl<'a> Resolver<'a> {
return None;
}
- let partial_res = self.partial_res_map.get(&expr.id)?;
- if partial_res.unresolved_segments() != 0 {
- return None;
- }
-
- if let Res::Def(def::DefKind::Fn, def_id) = partial_res.base_res() {
+ let res = self.partial_res_map.get(&expr.id)?.full_res()?;
+ if let Res::Def(def::DefKind::Fn, def_id) = res {
// We only support cross-crate argument rewriting. Uses
// within the same crate should be updated to use the new
// const generics style.
@@ -1985,7 +1966,7 @@ impl<'a> Resolver<'a> {
_ => panic!("invalid arg index"),
}
}
- // Cache the lookup to avoid parsing attributes for an iterm multiple times.
+ // Cache the lookup to avoid parsing attributes for an item multiple times.
self.legacy_const_generic_args.insert(def_id, Some(ret.clone()));
return Some(ret);
}
@@ -2015,6 +1996,24 @@ impl<'a> Resolver<'a> {
}
self.main_def = Some(MainDefinition { res, is_import, span });
}
+
+ // Items that go to reexport table encoded to metadata and visible through it to other crates.
+ fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
+ // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
+ // into the crate root to actual `NameBindingKind::Import`.
+ if binding.is_import()
+ || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
+ {
+ let res = binding.res().expect_non_local();
+ // Ambiguous imports are treated as errors at this point and are
+ // not exposed to other crates (see #36837 for more details).
+ if res != def::Res::Err && !binding.is_ambiguity() {
+ return Some(res);
+ }
+ }
+
+ return None;
+ }
}
fn names_to_string(names: &[Symbol]) -> String {
@@ -2066,7 +2065,7 @@ struct Finalize {
/// Span of the whole path or some its characteristic fragment.
/// E.g. span of `b` in `foo::{a, b, c}`, or full span for regular paths.
path_span: Span,
- /// Span of the path start, suitable for prepending something to to it.
+ /// Span of the path start, suitable for prepending something to it.
/// E.g. span of `foo` in `foo::{a, b, c}`, or full span for regular paths.
root_span: Span,
/// Whether to report privacy errors or silently return "no resolution" for them,
@@ -2083,7 +2082,3 @@ impl Finalize {
Finalize { node_id, path_span, root_span, report_private: true }
}
}
-
-pub fn provide(providers: &mut Providers) {
- late::lifetimes::provide(providers);
-}