This commit is contained in:
Lukas Wirth 2025-01-01 15:21:49 +01:00
parent 5303dc5d99
commit 1adc805dfa
2 changed files with 46 additions and 68 deletions

View file

@ -5219,49 +5219,25 @@ impl Type {
traits_in_scope: &FxHashSet<TraitId>, traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>, with_local_impls: Option<Module>,
name: Option<&Name>, name: Option<&Name>,
callback: impl FnMut(Function) -> Option<T>, mut callback: impl FnMut(Function) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
struct Callback<T, F> {
f: F,
slot: Option<T>,
}
impl<T, F> MethodCandidateCallback for &'_ mut Callback<T, F>
where
F: FnMut(Function) -> Option<T>,
{
fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()> {
match (self.f)(f) {
it @ Some(_) => {
self.slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
}
}
fn on_trait_method(&mut self, f: Function) -> ControlFlow<()> {
match (self.f)(f) {
it @ Some(_) => {
self.slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
}
}
}
let _p = tracing::info_span!("iterate_method_candidates_with_traits").entered(); let _p = tracing::info_span!("iterate_method_candidates_with_traits").entered();
let mut callback = Callback { slot: None, f: callback }; let mut slot = None;
self.iterate_method_candidates_split_inherent( self.iterate_method_candidates_split_inherent(
db, db,
scope, scope,
traits_in_scope, traits_in_scope,
with_local_impls, with_local_impls,
name, name,
&mut callback, |f| match callback(f) {
it @ Some(_) => {
slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
},
); );
callback.slot slot
} }
pub fn iterate_method_candidates<T>( pub fn iterate_method_candidates<T>(
@ -5361,39 +5337,10 @@ impl Type {
traits_in_scope: &FxHashSet<TraitId>, traits_in_scope: &FxHashSet<TraitId>,
with_local_impls: Option<Module>, with_local_impls: Option<Module>,
name: Option<&Name>, name: Option<&Name>,
callback: impl FnMut(AssocItem) -> Option<T>, mut callback: impl FnMut(AssocItem) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
struct Callback<T, F> {
f: F,
slot: Option<T>,
}
impl<T, F> PathCandidateCallback for &'_ mut Callback<T, F>
where
F: FnMut(AssocItem) -> Option<T>,
{
fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()> {
match (self.f)(item) {
it @ Some(_) => {
self.slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
}
}
fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()> {
match (self.f)(item) {
it @ Some(_) => {
self.slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
}
}
}
let _p = tracing::info_span!("iterate_path_candidates").entered(); let _p = tracing::info_span!("iterate_path_candidates").entered();
let mut callback = Callback { slot: None, f: callback }; let mut slot = None;
self.iterate_path_candidates_split_inherent( self.iterate_path_candidates_split_inherent(
db, db,
@ -5401,9 +5348,15 @@ impl Type {
traits_in_scope, traits_in_scope,
with_local_impls, with_local_impls,
name, name,
&mut callback, |item| match callback(item) {
it @ Some(_) => {
slot = it;
ControlFlow::Break(())
}
None => ControlFlow::Continue(()),
},
); );
callback.slot slot
} }
/// Iterates over inherent methods. /// Iterates over inherent methods.
@ -6167,8 +6120,34 @@ pub trait MethodCandidateCallback {
fn on_trait_method(&mut self, f: Function) -> ControlFlow<()>; fn on_trait_method(&mut self, f: Function) -> ControlFlow<()>;
} }
impl<F> MethodCandidateCallback for F
where
F: FnMut(Function) -> ControlFlow<()>,
{
fn on_inherent_method(&mut self, f: Function) -> ControlFlow<()> {
self(f)
}
fn on_trait_method(&mut self, f: Function) -> ControlFlow<()> {
self(f)
}
}
pub trait PathCandidateCallback { pub trait PathCandidateCallback {
fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()>; fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()>;
fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()>; fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()>;
} }
impl<F> PathCandidateCallback for F
where
F: FnMut(AssocItem) -> ControlFlow<()>,
{
fn on_inherent_item(&mut self, item: AssocItem) -> ControlFlow<()> {
self(item)
}
fn on_trait_item(&mut self, item: AssocItem) -> ControlFlow<()> {
self(item)
}
}

View file

@ -30,7 +30,6 @@ where
ControlFlow::Continue(()) ControlFlow::Continue(())
} }
#[allow(unstable_name_collisions)] // FIXME: Remove this when `is_none_or()` reaches stable.
fn on_trait_item(&mut self, item: hir::AssocItem) -> ControlFlow<()> { fn on_trait_item(&mut self, item: hir::AssocItem) -> ControlFlow<()> {
// The excluded check needs to come before the `seen` test, so that if we see the same method twice, // The excluded check needs to come before the `seen` test, so that if we see the same method twice,
// once as inherent and once not, we will include it. // once as inherent and once not, we will include it.