11//! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`].
22
3+ use std:: ops:: ControlFlow ;
34use std:: { debug_assert_matches, fmt} ;
45
56use rustc_errors:: ErrorGuaranteed ;
@@ -9,7 +10,9 @@ use rustc_hir::def_id::{DefId, LocalDefId};
910use rustc_hir:: lang_items:: LangItem ;
1011use rustc_span:: { DUMMY_SP , Span , Symbol } ;
1112use rustc_type_ir:: lang_items:: { SolverAdtLangItem , SolverProjectionLangItem , SolverTraitLangItem } ;
12- use rustc_type_ir:: { CollectAndApply , Interner , TypeFoldable , Unnormalized , search_graph} ;
13+ use rustc_type_ir:: {
14+ CollectAndApply , Interner , TypeFoldable , Unnormalized , VisitorResult , search_graph,
15+ } ;
1316
1417use crate :: dep_graph:: { DepKind , DepNodeIndex } ;
1518use crate :: infer:: canonical:: CanonicalVarKinds ;
@@ -522,20 +525,31 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
522525 // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
523526 // since we want to skip over blanket impls for non-rigid aliases, and also we
524527 // only want to consider types that *actually* unify with float/int vars.
525- fn for_each_relevant_impl (
528+ fn for_each_relevant_impl < R : VisitorResult > (
526529 self ,
527530 trait_def_id : DefId ,
528531 self_ty : Ty < ' tcx > ,
529- mut f : impl FnMut ( DefId ) ,
530- ) {
532+ mut f : impl FnMut ( DefId ) -> R ,
533+ ) -> R {
534+ macro_rules! ret {
535+ ( $e: expr) => {
536+ match $e. branch( ) {
537+ ControlFlow :: Break ( b) => return R :: from_residual( b) ,
538+ ControlFlow :: Continue ( ( ) ) => { }
539+ }
540+ } ;
541+ }
542+
531543 let tcx = self ;
532544 let trait_impls = tcx. trait_impls_of ( trait_def_id) ;
533545 let mut consider_impls_for_simplified_type = |simp| {
534546 if let Some ( impls_for_type) = trait_impls. non_blanket_impls ( ) . get ( & simp) {
535547 for & impl_def_id in impls_for_type {
536- f ( impl_def_id) ;
548+ ret ! ( f( impl_def_id) )
537549 }
538550 }
551+
552+ R :: output ( )
539553 } ;
540554
541555 match self_ty. kind ( ) {
@@ -566,7 +580,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
566580 self_ty,
567581 ty:: fast_reject:: TreatParams :: AsRigid ,
568582 ) {
569- consider_impls_for_simplified_type ( simp) ;
583+ ret ! ( consider_impls_for_simplified_type( simp) ) ;
570584 }
571585 }
572586
@@ -595,7 +609,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
595609 ty:: SimplifiedType :: Uint ( Usize ) ,
596610 ] ;
597611 for simp in possible_integers {
598- consider_impls_for_simplified_type ( simp) ;
612+ ret ! ( consider_impls_for_simplified_type( simp) ) ;
599613 }
600614 }
601615
@@ -610,7 +624,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
610624 ] ;
611625
612626 for simp in possible_floats {
613- consider_impls_for_simplified_type ( simp) ;
627+ ret ! ( consider_impls_for_simplified_type( simp) ) ;
614628 }
615629 }
616630
@@ -634,11 +648,20 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
634648 #[ allow( rustc:: usage_of_type_ir_traits) ]
635649 self . for_each_blanket_impl ( trait_def_id, f)
636650 }
637- fn for_each_blanket_impl ( self , trait_def_id : DefId , mut f : impl FnMut ( DefId ) ) {
651+ fn for_each_blanket_impl < R : VisitorResult > (
652+ self ,
653+ trait_def_id : DefId ,
654+ mut f : impl FnMut ( DefId ) -> R ,
655+ ) -> R {
638656 let trait_impls = self . trait_impls_of ( trait_def_id) ;
639657 for & impl_def_id in trait_impls. blanket_impls ( ) {
640- f ( impl_def_id) ;
658+ match f ( impl_def_id) . branch ( ) {
659+ ControlFlow :: Break ( b) => return R :: from_residual ( b) ,
660+ ControlFlow :: Continue ( ( ) ) => { }
661+ }
641662 }
663+
664+ R :: output ( )
642665 }
643666
644667 fn has_item_definition ( self , def_id : DefId ) -> bool {
0 commit comments