Remove trait_item_map
, clean up resolver.with_type_parameter_rib()
.
This commit is contained in:
parent
2a1d2edb82
commit
1cded8472e
2 changed files with 73 additions and 57 deletions
|
@ -478,9 +478,10 @@ impl<'a> Resolver<'a> {
|
||||||
self.define(module, ident, ns, (child.def, ty::Visibility::Public,
|
self.define(module, ident, ns, (child.def, ty::Visibility::Public,
|
||||||
DUMMY_SP, Mark::root()));
|
DUMMY_SP, Mark::root()));
|
||||||
|
|
||||||
let has_self = self.session.cstore.associated_item_cloned(child.def.def_id())
|
if self.session.cstore.associated_item_cloned(child.def.def_id())
|
||||||
.method_has_self_argument;
|
.method_has_self_argument {
|
||||||
self.trait_item_map.insert((def_id, child.name, ns), (child.def, has_self));
|
self.has_self.insert(child.def.def_id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.populated.set(true);
|
module.populated.set(true);
|
||||||
}
|
}
|
||||||
|
@ -773,7 +774,6 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, item: &'a TraitItem) {
|
fn visit_trait_item(&mut self, item: &'a TraitItem) {
|
||||||
let parent = self.resolver.current_module;
|
let parent = self.resolver.current_module;
|
||||||
let def_id = parent.def_id().unwrap();
|
|
||||||
|
|
||||||
if let TraitItemKind::Macro(_) = item.node {
|
if let TraitItemKind::Macro(_) = item.node {
|
||||||
self.visit_invoc(item.id);
|
self.visit_invoc(item.id);
|
||||||
|
@ -782,16 +782,18 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
|
||||||
|
|
||||||
// Add the item to the trait info.
|
// Add the item to the trait info.
|
||||||
let item_def_id = self.resolver.definitions.local_def_id(item.id);
|
let item_def_id = self.resolver.definitions.local_def_id(item.id);
|
||||||
let (def, ns, has_self) = match item.node {
|
let (def, ns) = match item.node {
|
||||||
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS, false),
|
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
|
||||||
TraitItemKind::Method(ref sig, _) =>
|
TraitItemKind::Method(ref sig, _) => {
|
||||||
(Def::Method(item_def_id), ValueNS, sig.decl.has_self()),
|
if sig.decl.has_self() {
|
||||||
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS, false),
|
self.resolver.has_self.insert(item_def_id);
|
||||||
|
}
|
||||||
|
(Def::Method(item_def_id), ValueNS)
|
||||||
|
}
|
||||||
|
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
|
||||||
TraitItemKind::Macro(_) => bug!(), // handled above
|
TraitItemKind::Macro(_) => bug!(), // handled above
|
||||||
};
|
};
|
||||||
|
|
||||||
self.resolver.trait_item_map.insert((def_id, item.ident.name, ns), (def, has_self));
|
|
||||||
|
|
||||||
let vis = ty::Visibility::Public;
|
let vis = ty::Visibility::Public;
|
||||||
self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
|
self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
|
||||||
|
|
||||||
|
|
|
@ -1111,7 +1111,8 @@ pub struct Resolver<'a> {
|
||||||
|
|
||||||
prelude: Option<Module<'a>>,
|
prelude: Option<Module<'a>>,
|
||||||
|
|
||||||
trait_item_map: FxHashMap<(DefId, Name, Namespace), (Def, bool /* has self */)>,
|
// n.b. This is used only for better diagnostics, not name resolution itself.
|
||||||
|
has_self: FxHashSet<DefId>,
|
||||||
|
|
||||||
// Names of fields of an item `DefId` accessible with dot syntax.
|
// Names of fields of an item `DefId` accessible with dot syntax.
|
||||||
// Used for hints during error reporting.
|
// Used for hints during error reporting.
|
||||||
|
@ -1134,7 +1135,7 @@ pub struct Resolver<'a> {
|
||||||
label_ribs: Vec<Rib<'a>>,
|
label_ribs: Vec<Rib<'a>>,
|
||||||
|
|
||||||
// The trait that the current context can refer to.
|
// The trait that the current context can refer to.
|
||||||
current_trait_ref: Option<(DefId, TraitRef)>,
|
current_trait_ref: Option<(Module<'a>, TraitRef)>,
|
||||||
|
|
||||||
// The current self type if inside an impl (used for better errors).
|
// The current self type if inside an impl (used for better errors).
|
||||||
current_self_type: Option<Ty>,
|
current_self_type: Option<Ty>,
|
||||||
|
@ -1337,7 +1338,7 @@ impl<'a> Resolver<'a> {
|
||||||
graph_root: graph_root,
|
graph_root: graph_root,
|
||||||
prelude: None,
|
prelude: None,
|
||||||
|
|
||||||
trait_item_map: FxHashMap(),
|
has_self: FxHashSet(),
|
||||||
field_names: FxHashMap(),
|
field_names: FxHashMap(),
|
||||||
|
|
||||||
determined_imports: Vec::new(),
|
determined_imports: Vec::new(),
|
||||||
|
@ -1750,22 +1751,21 @@ impl<'a> Resolver<'a> {
|
||||||
let mut function_type_rib = Rib::new(rib_kind);
|
let mut function_type_rib = Rib::new(rib_kind);
|
||||||
let mut seen_bindings = FxHashMap();
|
let mut seen_bindings = FxHashMap();
|
||||||
for type_parameter in &generics.ty_params {
|
for type_parameter in &generics.ty_params {
|
||||||
let name = type_parameter.ident.name;
|
let ident = type_parameter.ident.unhygienize();
|
||||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
||||||
|
|
||||||
if seen_bindings.contains_key(&name) {
|
if seen_bindings.contains_key(&ident) {
|
||||||
let span = seen_bindings.get(&name).unwrap();
|
let span = seen_bindings.get(&ident).unwrap();
|
||||||
resolve_error(self,
|
let err =
|
||||||
type_parameter.span,
|
ResolutionError::NameAlreadyUsedInTypeParameterList(ident.name, span);
|
||||||
ResolutionError::NameAlreadyUsedInTypeParameterList(name,
|
resolve_error(self, type_parameter.span, err);
|
||||||
span));
|
|
||||||
}
|
}
|
||||||
seen_bindings.entry(name).or_insert(type_parameter.span);
|
seen_bindings.entry(ident).or_insert(type_parameter.span);
|
||||||
|
|
||||||
// plain insert (no renaming)
|
// plain insert (no renaming)
|
||||||
let def_id = self.definitions.local_def_id(type_parameter.id);
|
let def_id = self.definitions.local_def_id(type_parameter.id);
|
||||||
let def = Def::TyParam(def_id);
|
let def = Def::TyParam(def_id);
|
||||||
function_type_rib.bindings.insert(Ident::with_empty_ctxt(name), def);
|
function_type_rib.bindings.insert(ident, def);
|
||||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||||
}
|
}
|
||||||
self.ribs[TypeNS].push(function_type_rib);
|
self.ribs[TypeNS].push(function_type_rib);
|
||||||
|
@ -1825,11 +1825,20 @@ impl<'a> Resolver<'a> {
|
||||||
let mut new_val = None;
|
let mut new_val = None;
|
||||||
let mut new_id = None;
|
let mut new_id = None;
|
||||||
if let Some(trait_ref) = opt_trait_ref {
|
if let Some(trait_ref) = opt_trait_ref {
|
||||||
let def = self.smart_resolve_path(trait_ref.ref_id, None,
|
let path: Vec<_> = trait_ref.path.segments.iter().map(|seg| seg.identifier).collect();
|
||||||
&trait_ref.path, PathSource::Trait).base_def();
|
let def = self.smart_resolve_path_fragment(trait_ref.ref_id,
|
||||||
|
None,
|
||||||
|
&path,
|
||||||
|
trait_ref.path.span,
|
||||||
|
trait_ref.path.segments.last().unwrap().span,
|
||||||
|
PathSource::Trait)
|
||||||
|
.base_def();
|
||||||
if def != Def::Err {
|
if def != Def::Err {
|
||||||
new_val = Some((def.def_id(), trait_ref.clone()));
|
|
||||||
new_id = Some(def.def_id());
|
new_id = Some(def.def_id());
|
||||||
|
let span = trait_ref.path.span;
|
||||||
|
if let PathResult::Module(module) = self.resolve_path(&path, None, false, span) {
|
||||||
|
new_val = Some((module, trait_ref.clone()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
|
let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
|
||||||
|
@ -1880,7 +1889,7 @@ impl<'a> Resolver<'a> {
|
||||||
ImplItemKind::Const(..) => {
|
ImplItemKind::Const(..) => {
|
||||||
// If this is a trait impl, ensure the const
|
// If this is a trait impl, ensure the const
|
||||||
// exists in trait
|
// exists in trait
|
||||||
this.check_trait_item(impl_item.ident.name,
|
this.check_trait_item(impl_item.ident,
|
||||||
ValueNS,
|
ValueNS,
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
|n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
|
|n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
|
||||||
|
@ -1889,7 +1898,7 @@ impl<'a> Resolver<'a> {
|
||||||
ImplItemKind::Method(ref sig, _) => {
|
ImplItemKind::Method(ref sig, _) => {
|
||||||
// If this is a trait impl, ensure the method
|
// If this is a trait impl, ensure the method
|
||||||
// exists in trait
|
// exists in trait
|
||||||
this.check_trait_item(impl_item.ident.name,
|
this.check_trait_item(impl_item.ident,
|
||||||
ValueNS,
|
ValueNS,
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
|n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
|
|n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
|
||||||
|
@ -1906,7 +1915,7 @@ impl<'a> Resolver<'a> {
|
||||||
ImplItemKind::Type(ref ty) => {
|
ImplItemKind::Type(ref ty) => {
|
||||||
// If this is a trait impl, ensure the type
|
// If this is a trait impl, ensure the type
|
||||||
// exists in trait
|
// exists in trait
|
||||||
this.check_trait_item(impl_item.ident.name,
|
this.check_trait_item(impl_item.ident,
|
||||||
TypeNS,
|
TypeNS,
|
||||||
impl_item.span,
|
impl_item.span,
|
||||||
|n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
|
|n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
|
||||||
|
@ -1924,15 +1933,15 @@ impl<'a> Resolver<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_trait_item<F>(&self, name: Name, ns: Namespace, span: Span, err: F)
|
fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
|
||||||
where F: FnOnce(Name, &str) -> ResolutionError
|
where F: FnOnce(Name, &str) -> ResolutionError
|
||||||
{
|
{
|
||||||
// If there is a TraitRef in scope for an impl, then the method must be in the
|
// If there is a TraitRef in scope for an impl, then the method must be in the
|
||||||
// trait.
|
// trait.
|
||||||
if let Some((did, ref trait_ref)) = self.current_trait_ref {
|
if let Some((module, _)) = self.current_trait_ref {
|
||||||
if !self.trait_item_map.contains_key(&(did, name, ns)) {
|
if self.resolve_ident_in_module(module, ident, ns, false, false, span).is_err() {
|
||||||
let path_str = path_names_to_string(&trait_ref.path);
|
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
|
||||||
resolve_error(self, span, err(name, &path_str));
|
resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2302,15 +2311,16 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to lookup the name in more relaxed fashion for better error reporting.
|
// Try to lookup the name in more relaxed fashion for better error reporting.
|
||||||
let name = path.last().unwrap().name;
|
let ident = *path.last().unwrap();
|
||||||
let candidates = this.lookup_import_candidates(name, ns, is_expected);
|
let candidates = this.lookup_import_candidates(ident.name, ns, is_expected);
|
||||||
if !candidates.is_empty() {
|
if !candidates.is_empty() {
|
||||||
let mut module_span = this.current_module.span;
|
let mut module_span = this.current_module.span;
|
||||||
module_span.hi = module_span.lo;
|
module_span.hi = module_span.lo;
|
||||||
// Report import candidates as help and proceed searching for labels.
|
// Report import candidates as help and proceed searching for labels.
|
||||||
show_candidates(&mut err, module_span, &candidates, def.is_some());
|
show_candidates(&mut err, module_span, &candidates, def.is_some());
|
||||||
} else if is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
|
} else if is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
|
||||||
let enum_candidates = this.lookup_import_candidates(name, ns, is_enum_variant);
|
let enum_candidates =
|
||||||
|
this.lookup_import_candidates(ident.name, ns, is_enum_variant);
|
||||||
let mut enum_candidates = enum_candidates.iter()
|
let mut enum_candidates = enum_candidates.iter()
|
||||||
.map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
|
.map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
|
||||||
enum_candidates.sort();
|
enum_candidates.sort();
|
||||||
|
@ -2326,7 +2336,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if path.len() == 1 && this.self_type_is_available(span) {
|
if path.len() == 1 && this.self_type_is_available(span) {
|
||||||
if let Some(candidate) = this.lookup_assoc_candidate(name, ns, is_expected) {
|
if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) {
|
||||||
let self_is_available = this.self_value_is_available(path[0].ctxt, span);
|
let self_is_available = this.self_value_is_available(path[0].ctxt, span);
|
||||||
match candidate {
|
match candidate {
|
||||||
AssocSuggestion::Field => {
|
AssocSuggestion::Field => {
|
||||||
|
@ -2440,7 +2450,7 @@ impl<'a> Resolver<'a> {
|
||||||
// or `<T>::A::B`. If `B` should be resolved in value namespace then
|
// or `<T>::A::B`. If `B` should be resolved in value namespace then
|
||||||
// it needs to be added to the trait map.
|
// it needs to be added to the trait map.
|
||||||
if ns == ValueNS {
|
if ns == ValueNS {
|
||||||
let item_name = path.last().unwrap().name;
|
let item_name = *path.last().unwrap();
|
||||||
let traits = self.get_traits_containing_item(item_name, ns);
|
let traits = self.get_traits_containing_item(item_name, ns);
|
||||||
self.trait_map.insert(id, traits);
|
self.trait_map.insert(id, traits);
|
||||||
}
|
}
|
||||||
|
@ -2819,7 +2829,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_assoc_candidate<FilterFn>(&mut self,
|
fn lookup_assoc_candidate<FilterFn>(&mut self,
|
||||||
name: Name,
|
ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
filter_fn: FilterFn)
|
filter_fn: FilterFn)
|
||||||
-> Option<AssocSuggestion>
|
-> Option<AssocSuggestion>
|
||||||
|
@ -2845,7 +2855,7 @@ impl<'a> Resolver<'a> {
|
||||||
Def::Struct(did) | Def::Union(did)
|
Def::Struct(did) | Def::Union(did)
|
||||||
if resolution.unresolved_segments() == 0 => {
|
if resolution.unresolved_segments() == 0 => {
|
||||||
if let Some(field_names) = self.field_names.get(&did) {
|
if let Some(field_names) = self.field_names.get(&did) {
|
||||||
if field_names.iter().any(|&field_name| name == field_name) {
|
if field_names.iter().any(|&field_name| ident.name == field_name) {
|
||||||
return Some(AssocSuggestion::Field);
|
return Some(AssocSuggestion::Field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2857,10 +2867,12 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for associated items in the current trait.
|
// Look for associated items in the current trait.
|
||||||
if let Some((trait_did, _)) = self.current_trait_ref {
|
if let Some((module, _)) = self.current_trait_ref {
|
||||||
if let Some(&(def, has_self)) = self.trait_item_map.get(&(trait_did, name, ns)) {
|
if let Ok(binding) =
|
||||||
|
self.resolve_ident_in_module(module, ident, ns, false, false, module.span) {
|
||||||
|
let def = binding.def();
|
||||||
if filter_fn(def) {
|
if filter_fn(def) {
|
||||||
return Some(if has_self {
|
return Some(if self.has_self.contains(&def.def_id()) {
|
||||||
AssocSuggestion::MethodWithSelf
|
AssocSuggestion::MethodWithSelf
|
||||||
} else {
|
} else {
|
||||||
AssocSuggestion::AssocItem
|
AssocSuggestion::AssocItem
|
||||||
|
@ -3081,13 +3093,13 @@ impl<'a> Resolver<'a> {
|
||||||
// field, we need to add any trait methods we find that match
|
// field, we need to add any trait methods we find that match
|
||||||
// the field name so that we can do some nice error reporting
|
// the field name so that we can do some nice error reporting
|
||||||
// later on in typeck.
|
// later on in typeck.
|
||||||
let traits = self.get_traits_containing_item(name.node.name, ValueNS);
|
let traits = self.get_traits_containing_item(name.node, ValueNS);
|
||||||
self.trait_map.insert(expr.id, traits);
|
self.trait_map.insert(expr.id, traits);
|
||||||
}
|
}
|
||||||
ExprKind::MethodCall(name, ..) => {
|
ExprKind::MethodCall(name, ..) => {
|
||||||
debug!("(recording candidate traits for expr) recording traits for {}",
|
debug!("(recording candidate traits for expr) recording traits for {}",
|
||||||
expr.id);
|
expr.id);
|
||||||
let traits = self.get_traits_containing_item(name.node.name, ValueNS);
|
let traits = self.get_traits_containing_item(name.node, ValueNS);
|
||||||
self.trait_map.insert(expr.id, traits);
|
self.trait_map.insert(expr.id, traits);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -3096,20 +3108,21 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_traits_containing_item(&mut self, name: Name, ns: Namespace) -> Vec<TraitCandidate> {
|
fn get_traits_containing_item(&mut self, ident: Ident, ns: Namespace) -> Vec<TraitCandidate> {
|
||||||
debug!("(getting traits containing item) looking for '{}'", name);
|
debug!("(getting traits containing item) looking for '{}'", ident.name);
|
||||||
|
|
||||||
let mut found_traits = Vec::new();
|
let mut found_traits = Vec::new();
|
||||||
// Look for the current trait.
|
// Look for the current trait.
|
||||||
if let Some((trait_def_id, _)) = self.current_trait_ref {
|
if let Some((module, _)) = self.current_trait_ref {
|
||||||
if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
|
if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
|
||||||
found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: None });
|
let def_id = module.def_id().unwrap();
|
||||||
|
found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut search_module = self.current_module;
|
let mut search_module = self.current_module;
|
||||||
loop {
|
loop {
|
||||||
self.get_traits_in_module_containing_item(name, ns, search_module, &mut found_traits);
|
self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
|
||||||
match search_module.kind {
|
match search_module.kind {
|
||||||
ModuleKind::Block(..) => search_module = search_module.parent.unwrap(),
|
ModuleKind::Block(..) => search_module = search_module.parent.unwrap(),
|
||||||
_ => break,
|
_ => break,
|
||||||
|
@ -3118,7 +3131,7 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
if let Some(prelude) = self.prelude {
|
if let Some(prelude) = self.prelude {
|
||||||
if !search_module.no_implicit_prelude {
|
if !search_module.no_implicit_prelude {
|
||||||
self.get_traits_in_module_containing_item(name, ns, prelude, &mut found_traits);
|
self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3126,9 +3139,9 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_traits_in_module_containing_item(&mut self,
|
fn get_traits_in_module_containing_item(&mut self,
|
||||||
name: Name,
|
ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
module: Module,
|
module: Module<'a>,
|
||||||
found_traits: &mut Vec<TraitCandidate>) {
|
found_traits: &mut Vec<TraitCandidate>) {
|
||||||
let mut traits = module.traits.borrow_mut();
|
let mut traits = module.traits.borrow_mut();
|
||||||
if traits.is_none() {
|
if traits.is_none() {
|
||||||
|
@ -3143,8 +3156,8 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
|
for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
|
||||||
let trait_def_id = binding.def().def_id();
|
let module = binding.module().unwrap();
|
||||||
if self.trait_item_map.contains_key(&(trait_def_id, name, ns)) {
|
if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
|
||||||
let import_id = match binding.kind {
|
let import_id = match binding.kind {
|
||||||
NameBindingKind::Import { directive, .. } => {
|
NameBindingKind::Import { directive, .. } => {
|
||||||
self.maybe_unused_trait_imports.insert(directive.id);
|
self.maybe_unused_trait_imports.insert(directive.id);
|
||||||
|
@ -3153,6 +3166,7 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
let trait_def_id = module.def_id().unwrap();
|
||||||
found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
|
found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue