11//! Things related to the Interner in the next-trait-solver.
22
3- use std:: fmt;
3+ use std:: { fmt, ops :: ControlFlow } ;
44
55use intern:: { Interned , InternedRef , InternedSliceRef , impl_internable} ;
6+ use macros:: GenericTypeVisitable ;
67use rustc_ast_ir:: { FloatTy , IntTy , UintTy } ;
78pub use tls_cache:: clear_tls_solver_cache;
89pub use tls_db:: { attach_db, attach_db_allow_change, with_attached_db} ;
@@ -21,8 +22,8 @@ use rustc_hash::FxHashSet;
2122use rustc_index:: bit_set:: DenseBitSet ;
2223use rustc_type_ir:: {
2324 AliasTermKind , AliasTyKind , BoundVar , CollectAndApply , CoroutineWitnessTypes , DebruijnIndex ,
24- EarlyBinder , FlagComputation , Flags , GenericArgKind , ImplPolarity , InferTy , Interner , TraitRef ,
25- TypeFlags , TypeVisitableExt , UniverseIndex , Upcast , Variance ,
25+ EarlyBinder , FlagComputation , Flags , GenericArgKind , GenericTypeVisitable , ImplPolarity ,
26+ InferTy , Interner , TraitRef , TypeFlags , TypeVisitableExt , UniverseIndex , Upcast , Variance ,
2627 elaborate:: elaborate,
2728 error:: TypeError ,
2829 fast_reject,
@@ -169,8 +170,9 @@ macro_rules! interned_slice {
169170 {
170171 #[ inline]
171172 fn generic_visit_with( & self , visitor: & mut V ) {
172- visitor. on_interned_slice( self . interned) ;
173- self . as_slice( ) . iter( ) . for_each( |it| it. generic_visit_with( visitor) ) ;
173+ if visitor. on_interned_slice( self . interned) . is_continue( ) {
174+ self . as_slice( ) . iter( ) . for_each( |it| it. generic_visit_with( visitor) ) ;
175+ }
174176 }
175177 }
176178 } ;
@@ -293,8 +295,14 @@ macro_rules! impl_stored_interned {
293295pub ( crate ) use impl_stored_interned;
294296
295297pub trait WorldExposer {
296- fn on_interned < T : intern:: Internable > ( & mut self , interned : InternedRef < ' _ , T > ) ;
297- fn on_interned_slice < T : intern:: SliceInternable > ( & mut self , interned : InternedSliceRef < ' _ , T > ) ;
298+ fn on_interned < T : intern:: Internable > (
299+ & mut self ,
300+ interned : InternedRef < ' _ , T > ,
301+ ) -> ControlFlow < ( ) > ;
302+ fn on_interned_slice < T : intern:: SliceInternable > (
303+ & mut self ,
304+ interned : InternedSliceRef < ' _ , T > ,
305+ ) -> ControlFlow < ( ) > ;
298306}
299307
300308#[ derive( Debug , Copy , Clone ) ]
@@ -803,7 +811,7 @@ pub struct Pattern<'db> {
803811 interned : InternedRef < ' db , PatternInterned > ,
804812}
805813
806- #[ derive( PartialEq , Eq , Hash ) ]
814+ #[ derive( PartialEq , Eq , Hash , GenericTypeVisitable ) ]
807815struct PatternInterned ( PatternKind < ' static > ) ;
808816
809817impl_internable ! ( gc; PatternInterned ) ;
@@ -884,8 +892,9 @@ impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for Pattern<'db> {
884892
885893impl < ' db , V : WorldExposer > rustc_type_ir:: GenericTypeVisitable < V > for Pattern < ' db > {
886894 fn generic_visit_with ( & self , visitor : & mut V ) {
887- visitor. on_interned ( self . interned ) ;
888- self . kind ( ) . generic_visit_with ( visitor) ;
895+ if visitor. on_interned ( self . interned ) . is_continue ( ) {
896+ self . kind ( ) . generic_visit_with ( visitor) ;
897+ }
889898 }
890899}
891900
@@ -2559,3 +2568,106 @@ mod tls_cache {
25592568 GLOBAL_CACHE . with_borrow_mut ( |handle| * handle = None ) ;
25602569 }
25612570}
2571+
2572+ impl WorldExposer for intern:: GarbageCollector {
2573+ fn on_interned < T : intern:: Internable > (
2574+ & mut self ,
2575+ interned : InternedRef < ' _ , T > ,
2576+ ) -> ControlFlow < ( ) > {
2577+ self . mark_interned_alive ( interned)
2578+ }
2579+
2580+ fn on_interned_slice < T : intern:: SliceInternable > (
2581+ & mut self ,
2582+ interned : InternedSliceRef < ' _ , T > ,
2583+ ) -> ControlFlow < ( ) > {
2584+ self . mark_interned_slice_alive ( interned)
2585+ }
2586+ }
2587+
2588+ /// # Safety
2589+ ///
2590+ /// This cannot be called if there are some not-yet-recorded type values. Generally, if you have a mutable
2591+ /// reference to the database, and there are no other database - then you can call this safely, but you
2592+ /// also need to make sure to maintain the mutable reference while this is running.
2593+ pub unsafe fn collect_ty_garbage ( ) {
2594+ let mut gc = intern:: GarbageCollector :: default ( ) ;
2595+
2596+ gc. add_storage :: < super :: consts:: ConstInterned > ( ) ;
2597+ gc. add_storage :: < super :: consts:: ValtreeInterned > ( ) ;
2598+ gc. add_storage :: < PatternInterned > ( ) ;
2599+ gc. add_storage :: < super :: opaques:: ExternalConstraintsInterned > ( ) ;
2600+ gc. add_storage :: < super :: predicate:: PredicateInterned > ( ) ;
2601+ gc. add_storage :: < super :: region:: RegionInterned > ( ) ;
2602+ gc. add_storage :: < super :: ty:: TyInterned > ( ) ;
2603+
2604+ gc. add_slice_storage :: < super :: predicate:: ClausesStorage > ( ) ;
2605+ gc. add_slice_storage :: < super :: generic_arg:: GenericArgsStorage > ( ) ;
2606+ gc. add_slice_storage :: < BoundVarKindsStorage > ( ) ;
2607+ gc. add_slice_storage :: < VariancesOfStorage > ( ) ;
2608+ gc. add_slice_storage :: < CanonicalVarsStorage > ( ) ;
2609+ gc. add_slice_storage :: < PatListStorage > ( ) ;
2610+ gc. add_slice_storage :: < super :: opaques:: PredefinedOpaquesStorage > ( ) ;
2611+ gc. add_slice_storage :: < super :: opaques:: SolverDefIdsStorage > ( ) ;
2612+ gc. add_slice_storage :: < super :: predicate:: BoundExistentialPredicatesStorage > ( ) ;
2613+ gc. add_slice_storage :: < super :: region:: RegionAssumptionsStorage > ( ) ;
2614+ gc. add_slice_storage :: < super :: ty:: TysStorage > ( ) ;
2615+
2616+ unsafe { gc. collect ( ) } ;
2617+ }
2618+
2619+ macro_rules! impl_gc_visit {
2620+ ( $( $ty: ty) ,* $( , ) ? ) => {
2621+ $(
2622+ impl :: intern:: GcInternedVisit for $ty {
2623+ #[ inline]
2624+ fn visit_with( & self , gc: & mut :: intern:: GarbageCollector ) {
2625+ self . generic_visit_with( gc) ;
2626+ }
2627+ }
2628+ ) *
2629+ } ;
2630+ }
2631+
2632+ impl_gc_visit ! (
2633+ super :: consts:: ConstInterned ,
2634+ super :: consts:: ValtreeInterned ,
2635+ PatternInterned ,
2636+ super :: opaques:: ExternalConstraintsInterned ,
2637+ super :: predicate:: PredicateInterned ,
2638+ super :: region:: RegionInterned ,
2639+ super :: ty:: TyInterned ,
2640+ super :: predicate:: ClausesCachedTypeInfo ,
2641+ ) ;
2642+
2643+ macro_rules! impl_gc_visit_slice {
2644+ ( $( $ty: ty) ,* $( , ) ? ) => {
2645+ $(
2646+ impl :: intern:: GcInternedSliceVisit for $ty {
2647+ #[ inline]
2648+ fn visit_header( header: & <Self as :: intern:: SliceInternable >:: Header , gc: & mut :: intern:: GarbageCollector ) {
2649+ header. generic_visit_with( gc) ;
2650+ }
2651+
2652+ #[ inline]
2653+ fn visit_slice( header: & [ <Self as :: intern:: SliceInternable >:: SliceType ] , gc: & mut :: intern:: GarbageCollector ) {
2654+ header. generic_visit_with( gc) ;
2655+ }
2656+ }
2657+ ) *
2658+ } ;
2659+ }
2660+
2661+ impl_gc_visit_slice ! (
2662+ super :: predicate:: ClausesStorage ,
2663+ super :: generic_arg:: GenericArgsStorage ,
2664+ BoundVarKindsStorage ,
2665+ VariancesOfStorage ,
2666+ CanonicalVarsStorage ,
2667+ PatListStorage ,
2668+ super :: opaques:: PredefinedOpaquesStorage ,
2669+ super :: opaques:: SolverDefIdsStorage ,
2670+ super :: predicate:: BoundExistentialPredicatesStorage ,
2671+ super :: region:: RegionAssumptionsStorage ,
2672+ super :: ty:: TysStorage ,
2673+ ) ;
0 commit comments