Don't allocate in associated_type_shorthand_candidates
This commit is contained in:
parent
5ef0c7a213
commit
c24753ae5d
@ -821,24 +821,38 @@ pub fn associated_type_shorthand_candidates<R>(
|
|||||||
res: TypeNs,
|
res: TypeNs,
|
||||||
mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
|
mut cb: impl FnMut(&Name, &TraitRef, TypeAliasId) -> Option<R>,
|
||||||
) -> Option<R> {
|
) -> Option<R> {
|
||||||
let traits_from_env: Vec<_> = match res {
|
let mut search = |t| {
|
||||||
TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
|
for t in all_super_trait_refs(db, t) {
|
||||||
None => vec![],
|
let data = db.trait_data(t.hir_trait_id());
|
||||||
// FIXME: how to correctly handle higher-ranked bounds here?
|
|
||||||
Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)],
|
for (name, assoc_id) in &data.items {
|
||||||
},
|
if let AssocItemId::TypeAliasId(alias) = assoc_id {
|
||||||
|
if let Some(result) = cb(name, &t, *alias) {
|
||||||
|
return Some(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
match res {
|
||||||
|
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||||
|
TypeNs::SelfType(impl_id) => {
|
||||||
|
search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE))
|
||||||
|
}
|
||||||
TypeNs::GenericParam(param_id) => {
|
TypeNs::GenericParam(param_id) => {
|
||||||
let predicates = db.generic_predicates_for_param(param_id);
|
let predicates = db.generic_predicates_for_param(param_id);
|
||||||
let mut traits_: Vec<_> = predicates
|
let res = predicates.iter().find_map(|pred| match &pred.value.value {
|
||||||
.iter()
|
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||||
.filter_map(|pred| match &pred.value.value {
|
WhereClause::Implemented(tr) => {
|
||||||
// FIXME: how to correctly handle higher-ranked bounds here?
|
search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
|
||||||
WhereClause::Implemented(tr) => {
|
}
|
||||||
Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
|
_ => None,
|
||||||
}
|
});
|
||||||
_ => None,
|
if let res @ Some(_) = res {
|
||||||
})
|
return res;
|
||||||
.collect();
|
}
|
||||||
// Handle `Self::Type` referring to own associated type in trait definitions
|
// Handle `Self::Type` referring to own associated type in trait definitions
|
||||||
if let GenericDefId::TraitId(trait_id) = param_id.parent {
|
if let GenericDefId::TraitId(trait_id) = param_id.parent {
|
||||||
let generics = generics(db.upcast(), trait_id.into());
|
let generics = generics(db.upcast(), trait_id.into());
|
||||||
@ -849,30 +863,13 @@ pub fn associated_type_shorthand_candidates<R>(
|
|||||||
trait_id: to_chalk_trait_id(trait_id),
|
trait_id: to_chalk_trait_id(trait_id),
|
||||||
substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
|
substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
|
||||||
};
|
};
|
||||||
traits_.push(trait_ref);
|
return search(trait_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traits_
|
None
|
||||||
}
|
|
||||||
_ => vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
|
|
||||||
let data = db.trait_data(t.hir_trait_id());
|
|
||||||
|
|
||||||
for (name, assoc_id) in &data.items {
|
|
||||||
match assoc_id {
|
|
||||||
AssocItemId::TypeAliasId(alias) => {
|
|
||||||
if let Some(result) = cb(name, &t, *alias) {
|
|
||||||
return Some(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AssocItemId::FunctionId(_) | AssocItemId::ConstId(_) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the type of all specific fields of a struct or enum variant.
|
/// Build the type of all specific fields of a struct or enum variant.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user