-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
rust/compiler/rustc_middle/src/ty/trait_def.rs
Lines 153 to 158 in 9b60e6c
pub fn find_map_relevant_impl<T, F: FnMut(DefId) -> Option<T>>( | |
self, | |
trait_def_id: DefId, | |
self_ty: Ty<'tcx>, | |
mut f: F, | |
) -> Option<T> { |
This function iterates over all impls which may apply to self_ty
and returns the first Some
. Note that just because an impl is given to f
it may not actually apply to the whole trait_ref
(or deeply matches self_ty
). Because of this it ends up being very easy to misuse. Let's go through a few incorrect uses of this function:
rust/src/librustdoc/passes/collect_intra_doc_links.rs
Lines 738 to 763 in 9b60e6c
tcx.find_map_relevant_impl(trait_, ty, |impl_| { | |
let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); | |
// Check if these are the same type. | |
let impl_type = trait_ref.skip_binder().self_ty(); | |
trace!( | |
"comparing type {} with kind {:?} against type {:?}", | |
impl_type, | |
impl_type.kind(), | |
ty | |
); | |
// Fast path: if this is a primitive simple `==` will work | |
// NOTE: the `match` is necessary; see #92662. | |
// this allows us to ignore generics because the user input | |
// may not include the generic placeholders | |
// e.g. this allows us to match Foo (user comment) with Foo<T> (actual type) | |
let saw_impl = impl_type == ty | |
|| match (impl_type.kind(), ty.kind()) { | |
(ty::Adt(impl_def, _), ty::Adt(ty_def, _)) => { | |
debug!("impl def_id: {:?}, ty def_id: {:?}", impl_def.did(), ty_def.did()); | |
impl_def.did() == ty_def.did() | |
} | |
_ => false, | |
}; | |
if saw_impl { Some((impl_, trait_)) } else { None } | |
}) |
only looks at the first maybe applicable impl even if there are multiple, idk how exactly that function is used, but it should be wrong 😅
rust/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Lines 2195 to 2197 in 9b60e6c
let get_trait_impl = |trait_def_id| { | |
self.tcx.find_map_relevant_impl(trait_def_id, trait_ref.skip_binder().self_ty(), Some) | |
}; |
Checks whether another trait with the same path has an impl for self_ty
. Note that this emits the error message if 2 versions of a crate are used, but the substs implement neither of the traits.
self.tcx.find_map_relevant_impl(id, proj.projection_ty.self_ty(), |did| { |
whatever this is doing 😅 but this should be usable to point to an impl which doesn't actually apply.
I would like to change all the uses of find_map_relevant_impl
to instead use for_each_relevant_impl
.