Add find_map_relevant_impl
This commit is contained in:
parent
2359ecc71f
commit
7993ddd89d
7 changed files with 51 additions and 27 deletions
|
@ -167,6 +167,41 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Applies function to every impl that could possibly match the self type `self_ty` and returns
|
||||
/// the first non-none value.
|
||||
pub fn find_map_relevant_impl<T, F: Fn(DefId) -> Option<T>>(
|
||||
self,
|
||||
def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
f: F,
|
||||
) -> Option<T> {
|
||||
let impls = self.trait_impls_of(def_id);
|
||||
|
||||
for &impl_def_id in impls.blanket_impls.iter() {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
|
||||
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
|
||||
for &impl_def_id in impls {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for &impl_def_id in impls.non_blanket_impls.values().flatten() {
|
||||
if let result @ Some(_) = f(impl_def_id) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns an iterator containing all impls
|
||||
pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);
|
||||
|
|
|
@ -341,19 +341,19 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
pub fn calculate_dtor(
|
||||
self,
|
||||
adt_did: DefId,
|
||||
validate: &mut dyn FnMut(Self, DefId) -> Result<(), ErrorReported>,
|
||||
validate: impl Fn(Self, DefId) -> Result<(), ErrorReported>,
|
||||
) -> Option<ty::Destructor> {
|
||||
let drop_trait = self.lang_items().drop_trait()?;
|
||||
self.ensure().coherent_trait(drop_trait);
|
||||
|
||||
let mut dtor_did = None;
|
||||
let ty = self.type_of(adt_did);
|
||||
self.for_each_relevant_impl(drop_trait, ty, |impl_did| {
|
||||
let dtor_did = self.find_map_relevant_impl(drop_trait, ty, |impl_did| {
|
||||
if let Some(item) = self.associated_items(impl_did).in_definition_order().next() {
|
||||
if validate(self, impl_did).is_ok() {
|
||||
dtor_did = Some(item.def_id);
|
||||
return Some(item.def_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
|
||||
Some(ty::Destructor { did: dtor_did? })
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue