]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_resolve/src/lib.rs
Add more self-profile info to rustc_resolve
[rust.git] / compiler / rustc_resolve / src / lib.rs
index ebfe5301b6918ee3720fcb002378e948eb723a1a..2b4a1d9e3fa0a45a0ed676d9892a38e794bbcd9d 100644 (file)
@@ -33,7 +33,7 @@
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
-use rustc_expand::base::SyntaxExtension;
+use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_hir::def::Namespace::*;
 use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
 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, ResolverOutputs};
-use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
 use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
 use rustc_session::Session;
+use rustc_span::edition::Edition;
 use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -210,7 +211,11 @@ enum ResolutionError<'a> {
     /// Error E0434: can't capture dynamic environment in a fn item.
     CannotCaptureDynamicEnvironmentInFnItem,
     /// Error E0435: attempt to use a non-constant value in a constant.
-    AttemptToUseNonConstantValueInConstant(Ident, String),
+    AttemptToUseNonConstantValueInConstant(
+        Ident,
+        /* suggestion */ &'static str,
+        /* current */ &'static str,
+    ),
     /// Error E0530: `X` bindings cannot shadow `Y`s.
     BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
     /// Error E0128: type parameters with a default cannot use forward-declared identifiers.
@@ -422,7 +427,9 @@ enum ModuleKind {
     ///
     /// This could be:
     ///
-    /// * A normal module ‒ either `mod from_file;` or `mod from_block { }`.
+    /// * A normal module – either `mod from_file;` or `mod from_block { }` –
+    ///   or the crate root (which is conceptually a top-level module).
+    ///   Note that the crate root's [name][Self::name] will be [`kw::Empty`].
     /// * A trait or an enum (it implicitly contains associated types, methods and variant
     ///   constructors).
     Def(DefKind, DefId, Symbol),
@@ -456,28 +463,42 @@ struct BindingKey {
 type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
 
 /// One node in the tree of modules.
+///
+/// Note that a "module" in resolve is broader than a `mod` that you declare in Rust code. It may be one of these:
+///
+/// * `mod`
+/// * crate root (aka, top-level anonymous module)
+/// * `enum`
+/// * `trait`
+/// * curly-braced block with statements
+///
+/// You can use [`ModuleData::kind`] to determine the kind of module this is.
 pub struct ModuleData<'a> {
+    /// The direct parent module (it may not be a `mod`, however).
     parent: Option<Module<'a>>,
+    /// What kind of module this is, because this may not be a `mod`.
     kind: ModuleKind,
 
-    // The def id of the closest normal module (`mod`) ancestor (including this module).
-    normal_ancestor_id: DefId,
+    /// 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.
+    /// 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>,
-    // True if this is a module from other crate that needs to be populated on access.
+    /// True if this is a module from other crate that needs to be populated on access.
     populate_on_access: Cell<bool>,
 
-    // Macro invocations that can expand into items in this module.
+    /// Macro invocations that can expand into items in this module.
     unexpanded_invocations: RefCell<FxHashSet<ExpnId>>,
 
+    /// Whether `#[no_implicit_prelude]` is active.
     no_implicit_prelude: bool,
 
     glob_importers: RefCell<Vec<&'a Import<'a>>>,
     globs: RefCell<Vec<&'a Import<'a>>>,
 
-    // Used to memoize the traits in this module for faster searches through all traits in scope.
+    /// Used to memoize the traits in this module for faster searches through all traits in scope.
     traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
 
     /// Span of the module itself. Used for error reporting.
@@ -492,16 +513,16 @@ impl<'a> ModuleData<'a> {
     fn new(
         parent: Option<Module<'a>>,
         kind: ModuleKind,
-        normal_ancestor_id: DefId,
+        nearest_parent_mod: DefId,
         expansion: ExpnId,
         span: Span,
     ) -> Self {
         ModuleData {
             parent,
             kind,
-            normal_ancestor_id,
+            nearest_parent_mod,
             lazy_resolutions: Default::default(),
-            populate_on_access: Cell::new(!normal_ancestor_id.is_local()),
+            populate_on_access: Cell::new(!nearest_parent_mod.is_local()),
             unexpanded_invocations: Default::default(),
             no_implicit_prelude: false,
             glob_importers: RefCell::new(Vec::new()),
@@ -743,10 +764,13 @@ fn pseudo_vis(&self) -> ty::Visibility {
     }
 
     fn is_variant(&self) -> bool {
-        matches!(self.kind, NameBindingKind::Res(
+        matches!(
+            self.kind,
+            NameBindingKind::Res(
                 Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
                 _,
-            ))
+            )
+        )
     }
 
     fn is_extern_crate(&self) -> bool {
@@ -850,7 +874,7 @@ pub struct ExternPreludeEntry<'a> {
 
 /// Used for better errors for E0773
 enum BuiltinMacroState {
-    NotYetSeen(SyntaxExtension),
+    NotYetSeen(SyntaxExtensionKind),
     AlreadySeen(Span),
 }
 
@@ -1028,7 +1052,7 @@ pub struct ResolverArenas<'a> {
 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(|def_id| def_id.is_local()).unwrap_or(true) {
+        if module.def_id().map_or(true, |def_id| def_id.is_local()) {
             self.local_modules.borrow_mut().push(module);
         }
         module
@@ -1427,7 +1451,7 @@ fn per_ns<F: FnMut(&mut Self, Namespace)>(&mut self, mut f: F) {
     }
 
     fn is_builtin_macro(&mut self, res: Res) -> bool {
-        self.get_macro(res).map_or(false, |ext| ext.is_builtin)
+        self.get_macro(res).map_or(false, |ext| ext.builtin_name.is_some())
     }
 
     fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
@@ -1441,61 +1465,86 @@ fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
 
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
-        let _prof_timer = self.session.prof.generic_activity("resolve_crate");
+        self.session.time("resolve_crate", || {
+            self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
+            self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
+            self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
+            self.session.time("resolve_check_unused", || self.check_unused(krate));
+            self.session.time("resolve_report_errors", || self.report_errors(krate));
+            self.session.time("resolve_postprocess", || self.crate_loader.postprocess(krate));
+        });
+    }
 
-        ImportResolver { r: self }.finalize_imports();
-        self.finalize_macro_resolutions();
+    pub fn traits_in_scope(
+        &mut self,
+        current_trait: Option<Module<'a>>,
+        parent_scope: &ParentScope<'a>,
+        ctxt: SyntaxContext,
+        assoc_item: Option<(Symbol, Namespace)>,
+    ) -> Vec<TraitCandidate> {
+        let mut found_traits = Vec::new();
+
+        if let Some(module) = current_trait {
+            if self.trait_may_have_item(Some(module), assoc_item) {
+                let def_id = module.def_id().unwrap();
+                found_traits.push(TraitCandidate { def_id, import_ids: smallvec![] });
+            }
+        }
 
-        self.late_resolve_crate(krate);
+        self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| {
+            match scope {
+                Scope::Module(module) => {
+                    this.traits_in_module(module, assoc_item, &mut found_traits);
+                }
+                Scope::StdLibPrelude => {
+                    if let Some(module) = this.prelude {
+                        this.traits_in_module(module, assoc_item, &mut found_traits);
+                    }
+                }
+                Scope::ExternPrelude | Scope::ToolPrelude | Scope::BuiltinTypes => {}
+                _ => unreachable!(),
+            }
+            None::<()>
+        });
 
-        self.check_unused(krate);
-        self.report_errors(krate);
-        self.crate_loader.postprocess(krate);
+        found_traits
     }
 
-    fn get_traits_in_module_containing_item(
+    fn traits_in_module(
         &mut self,
-        ident: Ident,
-        ns: Namespace,
         module: Module<'a>,
+        assoc_item: Option<(Symbol, Namespace)>,
         found_traits: &mut Vec<TraitCandidate>,
-        parent_scope: &ParentScope<'a>,
     ) {
-        assert!(ns == TypeNS || ns == ValueNS);
         module.ensure_traits(self);
         let traits = module.traits.borrow();
+        for (trait_name, trait_binding) in traits.as_ref().unwrap().iter() {
+            if self.trait_may_have_item(trait_binding.module(), assoc_item) {
+                let def_id = trait_binding.res().def_id();
+                let import_ids = self.find_transitive_imports(&trait_binding.kind, *trait_name);
+                found_traits.push(TraitCandidate { def_id, import_ids });
+            }
+        }
+    }
 
-        for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
-            // Traits have pseudo-modules that can be used to search for the given ident.
-            if let Some(module) = binding.module() {
-                let mut ident = ident;
-                if ident.span.glob_adjust(module.expansion, binding.span).is_none() {
-                    continue;
-                }
-                if self
-                    .resolve_ident_in_module_unadjusted(
-                        ModuleOrUniformRoot::Module(module),
-                        ident,
-                        ns,
-                        parent_scope,
-                        false,
-                        module.span,
-                    )
-                    .is_ok()
-                {
-                    let import_ids = self.find_transitive_imports(&binding.kind, trait_name);
-                    let trait_def_id = module.def_id().unwrap();
-                    found_traits.push(TraitCandidate { def_id: trait_def_id, import_ids });
-                }
-            } else if let Res::Def(DefKind::TraitAlias, _) = binding.res() {
-                // For now, just treat all trait aliases as possible candidates, since we don't
-                // know if the ident is somewhere in the transitive bounds.
-                let import_ids = self.find_transitive_imports(&binding.kind, trait_name);
-                let trait_def_id = binding.res().def_id();
-                found_traits.push(TraitCandidate { def_id: trait_def_id, import_ids });
-            } else {
-                bug!("candidate is not trait or trait alias?")
+    // List of traits in scope is pruned on best effort basis. We reject traits not having an
+    // associated item with the given name and namespace (if specified). This is a conservative
+    // optimization, proper hygienic type-based resolution of associated items is done in typeck.
+    // We don't reject trait aliases (`trait_module == None`) because we don't have access to their
+    // associated items.
+    fn trait_may_have_item(
+        &mut self,
+        trait_module: Option<Module<'a>>,
+        assoc_item: Option<(Symbol, Namespace)>,
+    ) -> bool {
+        match (trait_module, assoc_item) {
+            (Some(trait_module), Some((name, ns))) => {
+                self.resolutions(trait_module).borrow().iter().any(|resolution| {
+                    let (&BindingKey { ident: assoc_ident, ns: assoc_ns, .. }, _) = resolution;
+                    assoc_ns == ns && assoc_ident.name == name
+                })
             }
+            _ => true,
         }
     }
 
@@ -1519,11 +1568,11 @@ fn new_module(
         &self,
         parent: Module<'a>,
         kind: ModuleKind,
-        normal_ancestor_id: DefId,
+        nearest_parent_mod: DefId,
         expn_id: ExpnId,
         span: Span,
     ) -> Module<'a> {
-        let module = ModuleData::new(Some(parent), kind, normal_ancestor_id, expn_id, span);
+        let module = ModuleData::new(Some(parent), kind, nearest_parent_mod, expn_id, span);
         self.arenas.alloc_module(module)
     }
 
@@ -1610,8 +1659,13 @@ fn visit_scopes<T>(
         &mut self,
         scope_set: ScopeSet,
         parent_scope: &ParentScope<'a>,
-        ident: Ident,
-        mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
+        ctxt: SyntaxContext,
+        mut visitor: impl FnMut(
+            &mut Self,
+            Scope<'a>,
+            /*use_prelude*/ bool,
+            SyntaxContext,
+        ) -> Option<T>,
     ) -> Option<T> {
         // General principles:
         // 1. Not controlled (user-defined) names should have higher priority than controlled names
@@ -1654,7 +1708,7 @@ fn visit_scopes<T>(
         // 4c. Standard library prelude (de-facto closed, controlled).
         // 6. Language prelude: builtin attributes (closed, controlled).
 
-        let rust_2015 = ident.span.rust_2015();
+        let rust_2015 = ctxt.edition() == Edition::Edition2015;
         let (ns, macro_kind, is_absolute_path) = match scope_set {
             ScopeSet::All(ns, _) => (ns, None, false),
             ScopeSet::AbsolutePath(ns) => (ns, None, true),
@@ -1667,7 +1721,7 @@ fn visit_scopes<T>(
             TypeNS | ValueNS => Scope::Module(module),
             MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
         };
-        let mut ident = ident.normalize_to_macros_2_0();
+        let mut ctxt = ctxt.normalize_to_macros_2_0();
         let mut use_prelude = !module.no_implicit_prelude;
 
         loop {
@@ -1703,7 +1757,7 @@ fn visit_scopes<T>(
             };
 
             if visit {
-                if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
+                if let break_result @ Some(..) = visitor(self, scope, use_prelude, ctxt) {
                     return break_result;
                 }
             }
@@ -1733,17 +1787,17 @@ fn visit_scopes<T>(
                 },
                 Scope::CrateRoot => match ns {
                     TypeNS => {
-                        ident.span.adjust(ExpnId::root());
+                        ctxt.adjust(ExpnId::root());
                         Scope::ExternPrelude
                     }
                     ValueNS | MacroNS => break,
                 },
                 Scope::Module(module) => {
                     use_prelude = !module.no_implicit_prelude;
-                    match self.hygienic_lexical_parent(module, &mut ident.span) {
+                    match self.hygienic_lexical_parent(module, &mut ctxt) {
                         Some(parent_module) => Scope::Module(parent_module),
                         None => {
-                            ident.span.adjust(ExpnId::root());
+                            ctxt.adjust(ExpnId::root());
                             match ns {
                                 TypeNS => Scope::ExternPrelude,
                                 ValueNS => Scope::StdLibPrelude,
@@ -1868,16 +1922,18 @@ fn resolve_ident_in_lexical_scope(
         ident = normalized_ident;
         let mut poisoned = None;
         loop {
+            let mut span_data = ident.span.data();
             let opt_module = if let Some(node_id) = record_used_id {
                 self.hygienic_lexical_parent_with_compatibility_fallback(
                     module,
-                    &mut ident.span,
+                    &mut span_data.ctxt,
                     node_id,
                     &mut poisoned,
                 )
             } else {
-                self.hygienic_lexical_parent(module, &mut ident.span)
+                self.hygienic_lexical_parent(module, &mut span_data.ctxt)
             };
+            ident.span = span_data.span();
             module = unwrap_or!(opt_module, break);
             let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
             let result = self.resolve_ident_in_module_unadjusted(
@@ -1951,10 +2007,10 @@ fn resolve_ident_in_lexical_scope(
     fn hygienic_lexical_parent(
         &mut self,
         module: Module<'a>,
-        span: &mut Span,
+        ctxt: &mut SyntaxContext,
     ) -> Option<Module<'a>> {
-        if !module.expansion.outer_expn_is_descendant_of(span.ctxt()) {
-            return Some(self.macro_def_scope(span.remove_mark()));
+        if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
+            return Some(self.macro_def_scope(ctxt.remove_mark()));
         }
 
         if let ModuleKind::Block(..) = module.kind {
@@ -1967,11 +2023,11 @@ fn hygienic_lexical_parent(
     fn hygienic_lexical_parent_with_compatibility_fallback(
         &mut self,
         module: Module<'a>,
-        span: &mut Span,
+        ctxt: &mut SyntaxContext,
         node_id: NodeId,
         poisoned: &mut Option<NodeId>,
     ) -> Option<Module<'a>> {
-        if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
+        if let module @ Some(..) = self.hygienic_lexical_parent(module, ctxt) {
             return module;
         }
 
@@ -1994,9 +2050,9 @@ fn hygienic_lexical_parent_with_compatibility_fallback(
                 // The macro is a proc macro derive
                 if let Some(def_id) = module.expansion.expn_data().macro_def_id {
                     let ext = self.get_macro_by_def_id(def_id);
-                    if !ext.is_builtin
+                    if ext.builtin_name.is_none()
                         && ext.macro_kind() == MacroKind::Derive
-                        && parent.expansion.outer_expn_is_descendant_of(span.ctxt())
+                        && parent.expansion.outer_expn_is_descendant_of(*ctxt)
                     {
                         *poisoned = Some(node_id);
                         return module.parent;
@@ -2118,7 +2174,7 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
                 return self.graph_root;
             }
         };
-        let module = self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.normal_ancestor_id });
+        let module = self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.nearest_parent_mod });
         debug!(
             "resolve_crate_root({:?}): got module {:?} ({:?}) (ident.span = {:?})",
             ident,
@@ -2130,10 +2186,10 @@ fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> {
     }
 
     fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
-        let mut module = self.get_module(module.normal_ancestor_id);
+        let mut module = self.get_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.normal_ancestor_id);
+            module = self.get_module(parent.nearest_parent_mod);
         }
         module
     }
@@ -2427,8 +2483,14 @@ enum FindBindingResult<'a> {
                             (format!("use of undeclared crate or module `{}`", ident), None)
                         }
                     } else {
-                        let mut msg =
-                            format!("could not find `{}` in `{}`", ident, path[i - 1].ident);
+                        let parent = path[i - 1].ident.name;
+                        let parent = if parent == kw::PathRoot {
+                            "crate root".to_owned()
+                        } else {
+                            format!("`{}`", parent)
+                        };
+
+                        let mut msg = format!("could not find `{}` in {}", ident, parent);
                         if ns == TypeNS || ns == ValueNS {
                             let ns_to_try = if ns == TypeNS { ValueNS } else { TypeNS };
                             if let FindBindingResult::Binding(Ok(binding)) =
@@ -2436,11 +2498,11 @@ enum FindBindingResult<'a> {
                             {
                                 let mut found = |what| {
                                     msg = format!(
-                                        "expected {}, found {} `{}` in `{}`",
+                                        "expected {}, found {} `{}` in {}",
                                         ns.descr(),
                                         what,
                                         ident,
-                                        path[i - 1].ident
+                                        parent
                                     )
                                 };
                                 if binding.module().is_some() {
@@ -2598,18 +2660,19 @@ fn validate_res_from_ribs(
                                             ConstantItemKind::Const => "const",
                                             ConstantItemKind::Static => "static",
                                         };
-                                        let sugg = format!(
-                                            "consider using `let` instead of `{}`",
-                                            kind_str
-                                        );
-                                        (span, AttemptToUseNonConstantValueInConstant(ident, sugg))
+                                        (
+                                            span,
+                                            AttemptToUseNonConstantValueInConstant(
+                                                ident, "let", kind_str,
+                                            ),
+                                        )
                                     } else {
-                                        let sugg = "consider using `const` instead of `let`";
                                         (
                                             rib_ident.span,
                                             AttemptToUseNonConstantValueInConstant(
                                                 original_rib_ident_def,
-                                                sugg.to_string(),
+                                                "const",
+                                                "let",
                                             ),
                                         )
                                     };
@@ -2817,7 +2880,7 @@ fn record_partial_res(&mut self, node_id: NodeId, resolution: PartialRes) {
     }
 
     fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
-        vis.is_accessible_from(module.normal_ancestor_id, self)
+        vis.is_accessible_from(module.nearest_parent_mod, self)
     }
 
     fn set_binding_parent_module(&mut self, binding: &'a NameBinding<'a>, module: Module<'a>) {
@@ -2841,7 +2904,7 @@ fn disambiguate_macro_rules_vs_modularized(
             self.binding_parent_modules.get(&PtrKey(modularized)),
         ) {
             (Some(macro_rules), Some(modularized)) => {
-                macro_rules.normal_ancestor_id == modularized.normal_ancestor_id
+                macro_rules.nearest_parent_mod == modularized.nearest_parent_mod
                     && modularized.is_ancestor_of(macro_rules)
             }
             _ => false,
@@ -2999,7 +3062,7 @@ fn report_conflict<'b>(
         let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id();
         let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
         let from_item =
-            self.extern_prelude.get(&ident).map(|entry| entry.introduced_by_item).unwrap_or(true);
+            self.extern_prelude.get(&ident).map_or(true, |entry| entry.introduced_by_item);
         // Only suggest removing an import if both bindings are to the same def, if both spans
         // aren't dummy spans. Further, if both bindings are imports, then the ident must have
         // been introduced by a item.
@@ -3195,34 +3258,6 @@ fn extern_prelude_get(
         })
     }
 
-    /// This is equivalent to `get_traits_in_module_containing_item`, but without filtering by the associated item.
-    ///
-    /// This is used by rustdoc for intra-doc links.
-    pub fn traits_in_scope(&mut self, module_id: DefId) -> Vec<TraitCandidate> {
-        let module = self.get_module(module_id);
-        module.ensure_traits(self);
-        let traits = module.traits.borrow();
-        let to_candidate =
-            |this: &mut Self, &(trait_name, binding): &(Ident, &NameBinding<'_>)| TraitCandidate {
-                def_id: binding.res().def_id(),
-                import_ids: this.find_transitive_imports(&binding.kind, trait_name),
-            };
-
-        let mut candidates: Vec<_> =
-            traits.as_ref().unwrap().iter().map(|x| to_candidate(self, x)).collect();
-
-        if let Some(prelude) = self.prelude {
-            if !module.no_implicit_prelude {
-                prelude.ensure_traits(self);
-                candidates.extend(
-                    prelude.traits.borrow().as_ref().unwrap().iter().map(|x| to_candidate(self, x)),
-                );
-            }
-        }
-
-        candidates
-    }
-
     /// Rustdoc uses this to resolve things in a recoverable way. `ResolutionError<'a>`
     /// isn't something that can be returned because it can't be made to live that long,
     /// and also it's a private type. Fortunately rustdoc doesn't need to know the error,