1
Fork 0

Add find_map_relevant_impl

This commit is contained in:
Dániel Buga 2020-10-09 15:28:32 +02:00
parent 2359ecc71f
commit 7993ddd89d
7 changed files with 51 additions and 27 deletions

View file

@ -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);

View file

@ -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? })