resolve: Move get_traits_in_module_containing_item
to Resolver
This commit is contained in:
parent
e674422f86
commit
344a42e66e
@ -8,7 +8,7 @@
|
||||
use RibKind::*;
|
||||
|
||||
use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding};
|
||||
use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult};
|
||||
use crate::{Module, ModuleOrUniformRoot, ParentScope, PathResult};
|
||||
use crate::{ResolutionError, Resolver, Segment, UseError};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
@ -24,7 +24,6 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use rustc_hir::TraitCandidate;
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -2342,95 +2341,31 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
ident.span = ident.span.normalize_to_macros_2_0();
|
||||
let mut search_module = self.parent_scope.module;
|
||||
loop {
|
||||
self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
|
||||
self.r.get_traits_in_module_containing_item(
|
||||
ident,
|
||||
ns,
|
||||
search_module,
|
||||
&mut found_traits,
|
||||
&self.parent_scope,
|
||||
);
|
||||
search_module =
|
||||
unwrap_or!(self.r.hygienic_lexical_parent(search_module, &mut ident.span), break);
|
||||
}
|
||||
|
||||
if let Some(prelude) = self.r.prelude {
|
||||
if !search_module.no_implicit_prelude {
|
||||
self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
|
||||
self.r.get_traits_in_module_containing_item(
|
||||
ident,
|
||||
ns,
|
||||
prelude,
|
||||
&mut found_traits,
|
||||
&self.parent_scope,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
found_traits
|
||||
}
|
||||
|
||||
fn get_traits_in_module_containing_item(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
module: Module<'a>,
|
||||
found_traits: &mut Vec<TraitCandidate>,
|
||||
) {
|
||||
assert!(ns == TypeNS || ns == ValueNS);
|
||||
let mut traits = module.traits.borrow_mut();
|
||||
if traits.is_none() {
|
||||
let mut collected_traits = Vec::new();
|
||||
module.for_each_child(self.r, |_, name, ns, binding| {
|
||||
if ns != TypeNS {
|
||||
return;
|
||||
}
|
||||
match binding.res() {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
|
||||
collected_traits.push((name, binding))
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
*traits = Some(collected_traits.into_boxed_slice());
|
||||
}
|
||||
|
||||
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
|
||||
.r
|
||||
.resolve_ident_in_module_unadjusted(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
&self.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?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_transitive_imports(
|
||||
&mut self,
|
||||
mut kind: &NameBindingKind<'_>,
|
||||
trait_name: Ident,
|
||||
) -> SmallVec<[LocalDefId; 1]> {
|
||||
let mut import_ids = smallvec![];
|
||||
while let NameBindingKind::Import { import, binding, .. } = kind {
|
||||
let id = self.r.local_def_id(import.id);
|
||||
self.r.maybe_unused_trait_imports.insert(id);
|
||||
self.r.add_to_glob_map(&import, trait_name);
|
||||
import_ids.push(id);
|
||||
kind = &binding.kind;
|
||||
}
|
||||
import_ids
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
|
@ -43,9 +43,9 @@ 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, ResolverOutputs};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::Session;
|
||||
@ -54,6 +54,7 @@ use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::BTreeSet;
|
||||
use std::{cmp, fmt, iter, ptr};
|
||||
@ -1430,6 +1431,82 @@ impl<'a> Resolver<'a> {
|
||||
self.crate_loader.postprocess(krate);
|
||||
}
|
||||
|
||||
fn get_traits_in_module_containing_item(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
module: Module<'a>,
|
||||
found_traits: &mut Vec<TraitCandidate>,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
) {
|
||||
assert!(ns == TypeNS || ns == ValueNS);
|
||||
let mut traits = module.traits.borrow_mut();
|
||||
if traits.is_none() {
|
||||
let mut collected_traits = Vec::new();
|
||||
module.for_each_child(self, |_, name, ns, binding| {
|
||||
if ns != TypeNS {
|
||||
return;
|
||||
}
|
||||
match binding.res() {
|
||||
Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
|
||||
collected_traits.push((name, binding))
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
*traits = Some(collected_traits.into_boxed_slice());
|
||||
}
|
||||
|
||||
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?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_transitive_imports(
|
||||
&mut self,
|
||||
mut kind: &NameBindingKind<'_>,
|
||||
trait_name: Ident,
|
||||
) -> SmallVec<[LocalDefId; 1]> {
|
||||
let mut import_ids = smallvec![];
|
||||
while let NameBindingKind::Import { import, binding, .. } = kind {
|
||||
let id = self.local_def_id(import.id);
|
||||
self.maybe_unused_trait_imports.insert(id);
|
||||
self.add_to_glob_map(&import, trait_name);
|
||||
import_ids.push(id);
|
||||
kind = &binding.kind;
|
||||
}
|
||||
import_ids
|
||||
}
|
||||
|
||||
fn new_module(
|
||||
&self,
|
||||
parent: Module<'a>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user