From 56bbe1cb6ff2d4a89221eeaf966b20956d515df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 6 May 2026 16:13:17 +0200 Subject: [PATCH] return faster from internal iterators --- compiler/rustc_ast_ir/src/visit.rs | 23 ++++++++++ .../src/ty/context/impl_interner.rs | 43 ++++++++++++++----- .../src/solve/assembly/mod.rs | 2 +- compiler/rustc_type_ir/src/interner.rs | 13 ++++-- 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast_ir/src/visit.rs b/compiler/rustc_ast_ir/src/visit.rs index f6d6bf3a3e309..8315c080dfa86 100644 --- a/compiler/rustc_ast_ir/src/visit.rs +++ b/compiler/rustc_ast_ir/src/visit.rs @@ -41,6 +41,29 @@ impl VisitorResult for ControlFlow { } } +impl VisitorResult for Result<(), E> { + type Residual = E; + + fn output() -> Self { + Ok(()) + } + fn from_residual(residual: Self::Residual) -> Self { + Err(residual) + } + fn from_branch(b: ControlFlow) -> Self { + match b { + ControlFlow::Continue(()) => Ok(()), + ControlFlow::Break(e) => Err(e), + } + } + fn branch(self) -> ControlFlow { + match self { + Ok(()) => ControlFlow::Continue(()), + Err(e) => ControlFlow::Break(e), + } + } +} + #[macro_export] macro_rules! try_visit { ($e:expr) => { diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index bacddb6808290..b18ce5b4a0108 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -1,5 +1,6 @@ //! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`]. +use std::ops::ControlFlow; use std::{debug_assert_matches, fmt}; use rustc_errors::ErrorGuaranteed; @@ -9,7 +10,9 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem}; -use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, Unnormalized, search_graph}; +use rustc_type_ir::{ + CollectAndApply, Interner, TypeFoldable, Unnormalized, VisitorResult, search_graph, +}; use crate::dep_graph::{DepKind, DepNodeIndex}; use crate::infer::canonical::CanonicalVarKinds; @@ -500,20 +503,31 @@ impl<'tcx> Interner for TyCtxt<'tcx> { // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`, // since we want to skip over blanket impls for non-rigid aliases, and also we // only want to consider types that *actually* unify with float/int vars. - fn for_each_relevant_impl( + fn for_each_relevant_impl( self, trait_def_id: DefId, self_ty: Ty<'tcx>, - mut f: impl FnMut(DefId), - ) { + mut f: impl FnMut(DefId) -> R, + ) -> R { + macro_rules! ret { + ($e: expr) => { + match $e.branch() { + ControlFlow::Break(b) => return R::from_residual(b), + ControlFlow::Continue(()) => {} + } + }; + } + let tcx = self; let trait_impls = tcx.trait_impls_of(trait_def_id); let mut consider_impls_for_simplified_type = |simp| { if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) { for &impl_def_id in impls_for_type { - f(impl_def_id); + ret!(f(impl_def_id)) } } + + R::output() }; match self_ty.kind() { @@ -544,7 +558,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self_ty, ty::fast_reject::TreatParams::AsRigid, ) { - consider_impls_for_simplified_type(simp); + ret!(consider_impls_for_simplified_type(simp)); } } @@ -573,7 +587,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ty::SimplifiedType::Uint(Usize), ]; for simp in possible_integers { - consider_impls_for_simplified_type(simp); + ret!(consider_impls_for_simplified_type(simp)); } } @@ -588,7 +602,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ]; for simp in possible_floats { - consider_impls_for_simplified_type(simp); + ret!(consider_impls_for_simplified_type(simp)); } } @@ -612,11 +626,20 @@ impl<'tcx> Interner for TyCtxt<'tcx> { #[allow(rustc::usage_of_type_ir_traits)] self.for_each_blanket_impl(trait_def_id, f) } - fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) { + fn for_each_blanket_impl( + self, + trait_def_id: DefId, + mut f: impl FnMut(DefId) -> R, + ) -> R { let trait_impls = self.trait_impls_of(trait_def_id); for &impl_def_id in trait_impls.blanket_impls() { - f(impl_def_id); + match f(impl_def_id).branch() { + ControlFlow::Break(b) => return R::from_residual(b), + ControlFlow::Continue(()) => {} + } } + + R::output() } fn has_item_definition(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index eb7e3b93c0bcc..c7e33e1f94f27 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -1129,7 +1129,7 @@ where // FIXME(trait-system-refactor-initiative#229): This isn't // perfect yet as it still allows us to incorrectly constrain // other inference variables. - Err(NoSolution) + Err(NoSolution.into()) } }) { Ok(candidate) => candidates.push(candidate), diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index e13c4279a68a1..1d4e625e3ab1b 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -4,6 +4,7 @@ use std::hash::Hash; use std::ops::Deref; use rustc_ast_ir::Movability; +use rustc_ast_ir::visit::VisitorResult; use rustc_index::bit_set::DenseBitSet; use crate::fold::TypeFoldable; @@ -352,13 +353,17 @@ pub trait Interner: def_id: Self::TraitId, ) -> impl IntoIterator; - fn for_each_relevant_impl( + fn for_each_relevant_impl( self, trait_def_id: Self::TraitId, self_ty: Self::Ty, - f: impl FnMut(Self::ImplId), - ); - fn for_each_blanket_impl(self, trait_def_id: Self::TraitId, f: impl FnMut(Self::ImplId)); + f: impl FnMut(Self::ImplId) -> R, + ) -> R; + fn for_each_blanket_impl( + self, + trait_def_id: Self::TraitId, + f: impl FnMut(Self::ImplId) -> R, + ) -> R; fn has_item_definition(self, def_id: Self::DefId) -> bool;