@@ -12,6 +12,8 @@ mod errors;
1212use std:: fmt;
1313use std:: marker:: PhantomData ;
1414use std:: ops:: ControlFlow ;
15+ use std:: sync:: { Mutex , MutexGuard , OnceLock } ;
16+ use std:: time:: { Duration , Instant } ;
1517
1618use errors:: {
1719 FieldIsPrivate , FieldIsPrivateLabel , FromPrivateDependencyInPublicInterface , InPublicInterface ,
@@ -20,7 +22,7 @@ use errors::{
2022} ;
2123use rustc_ast:: MacroDef ;
2224use rustc_ast:: visit:: { VisitorResult , try_visit} ;
23- use rustc_data_structures:: fx:: FxHashSet ;
25+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2426use rustc_data_structures:: intern:: Interned ;
2527use rustc_errors:: { MultiSpan , listify} ;
2628use rustc_hir as hir;
@@ -86,6 +88,7 @@ pub trait DefIdVisitor<'tcx> {
8688 def_id_visitor : self ,
8789 visited_tys : Default :: default ( ) ,
8890 dummy : Default :: default ( ) ,
91+ // brrr: Default::default(),
8992 }
9093 }
9194 fn visit ( & mut self , ty_fragment : impl TypeVisitable < TyCtxt < ' tcx > > ) -> Self :: Result {
@@ -102,6 +105,82 @@ pub trait DefIdVisitor<'tcx> {
102105 }
103106}
104107
108+ #[ derive( PartialEq , Eq , Hash , Debug ) ]
109+ pub enum Ty2 {
110+ Bool ,
111+ Char ,
112+ Int ,
113+ Uint ,
114+ Float ,
115+ Adt ,
116+ Foreign ,
117+ Str ,
118+ Array ,
119+ Pat ,
120+ Slice ,
121+ RawPtr ,
122+ Ref ,
123+ FnDef ,
124+ FnPtr ,
125+ UnsafeBinder ,
126+ Dynamic ,
127+ Closure ,
128+ CoroutineClosure ,
129+ Coroutine ,
130+ CoroutineWitness ,
131+ Never ,
132+ Tuple ,
133+ Alias ,
134+ Param ,
135+ Bound ,
136+ Placeholder ,
137+ Infer ,
138+ Error ,
139+ }
140+
141+ use Ty2 :: * ;
142+
143+ impl Ty2 {
144+ fn from_ty ( ty : Ty < ' _ > ) -> Ty2 {
145+ match ty. kind ( ) {
146+ ty:: Bool => Bool ,
147+ ty:: Char => Char ,
148+ ty:: Int ( ..) => Int ,
149+ ty:: Uint ( ..) => Uint ,
150+ ty:: Float ( ..) => Float ,
151+ ty:: Adt ( ..) => Adt ,
152+ ty:: Foreign ( ..) => Foreign ,
153+ ty:: Str => Str ,
154+ ty:: Array ( ..) => Array ,
155+ ty:: Pat ( ..) => Pat ,
156+ ty:: Slice ( _) => Slice ,
157+ ty:: RawPtr ( ..) => RawPtr ,
158+ ty:: Ref ( ..) => Ref ,
159+ ty:: FnDef ( ..) => FnDef ,
160+ ty:: FnPtr ( ..) => FnPtr ,
161+ ty:: UnsafeBinder ( ..) => UnsafeBinder ,
162+ ty:: Dynamic ( ..) => Dynamic ,
163+ ty:: Closure ( ..) => Closure ,
164+ ty:: CoroutineClosure ( ..) => CoroutineClosure ,
165+ ty:: Coroutine ( ..) => Coroutine ,
166+ ty:: CoroutineWitness ( ..) => CoroutineWitness ,
167+ ty:: Never => Never ,
168+ ty:: Tuple ( ..) => Tuple ,
169+ ty:: Alias ( ..) => Alias ,
170+ ty:: Param ( ..) => Param ,
171+ ty:: Bound ( ..) => Bound ,
172+ ty:: Placeholder ( ..) => Placeholder ,
173+ ty:: Infer ( ..) => Infer ,
174+ ty:: Error ( ..) => Error ,
175+ }
176+ }
177+ }
178+
179+ pub fn brrr ( ) -> MutexGuard < ' static , FxHashMap < Ty2 , Duration > > {
180+ static MAP : OnceLock < Mutex < FxHashMap < Ty2 , Duration > > > = OnceLock :: new ( ) ;
181+ MAP . get_or_init ( Default :: default) . lock ( ) . unwrap ( )
182+ }
183+
105184pub struct DefIdVisitorSkeleton < ' v , ' tcx , V : ?Sized > {
106185 def_id_visitor : & ' v mut V ,
107186 visited_tys : FxHashSet < Ty < ' tcx > > ,
@@ -171,6 +250,14 @@ where
171250 }
172251}
173252
253+ // impl<V: ?Sized> Drop for DefIdVisitorSkeleton<'_, '_, V> {
254+ // fn drop(&mut self) {
255+ // if !brrr().is_empty() {
256+ // dbg!(brrr());
257+ // }
258+ // }
259+ // }
260+
174261impl < ' tcx , V > TypeVisitor < TyCtxt < ' tcx > > for DefIdVisitorSkeleton < ' _ , ' tcx , V >
175262where
176263 V : DefIdVisitor < ' tcx > + ?Sized ,
@@ -182,6 +269,8 @@ where
182269 }
183270
184271 fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> Self :: Result {
272+ let new = self . visited_tys . insert ( ty) ;
273+ let instant = Instant :: now ( ) ;
185274 let tcx = self . def_id_visitor . tcx ( ) ;
186275 // GenericArgs are not visited here because they are visited below
187276 // in `super_visit_with`.
@@ -192,9 +281,6 @@ where
192281 | ty:: Closure ( def_id, ..)
193282 | ty:: CoroutineClosure ( def_id, ..)
194283 | ty:: Coroutine ( def_id, ..) => {
195- if !self . visited_tys . insert ( ty) {
196- return V :: Result :: output ( ) ;
197- }
198284 try_visit ! ( self . def_id_visitor. visit_def_id( def_id, "type" , & ty) ) ;
199285 if V :: SHALLOW {
200286 return V :: Result :: output ( ) ;
@@ -217,9 +303,6 @@ where
217303 }
218304 }
219305 ty:: Alias ( kind @ ( ty:: Inherent | ty:: Free | ty:: Projection ) , data) => {
220- if !self . visited_tys . insert ( ty) {
221- return V :: Result :: output ( ) ;
222- }
223306 if self . def_id_visitor . skip_assoc_tys ( ) {
224307 // Visitors searching for minimal visibility/reachability want to
225308 // conservatively approximate associated types like `Type::Alias`
@@ -251,9 +334,6 @@ where
251334 } ;
252335 }
253336 ty:: Dynamic ( predicates, ..) => {
254- if !self . visited_tys . insert ( ty) {
255- return V :: Result :: output ( ) ;
256- }
257337 // All traits in the list are considered the "primary" part of the type
258338 // and are visited by shallow visitors.
259339 for predicate in predicates {
@@ -269,17 +349,16 @@ where
269349 }
270350 }
271351 ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, .. } ) => {
272- if !self . visited_tys . insert ( ty) {
273- return V :: Result :: output ( ) ;
352+ if new {
353+ // The intent is to treat `impl Trait1 + Trait2` identically to
354+ // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
355+ // (it either has no visibility, or its visibility is insignificant, like
356+ // visibilities of type aliases) and recurse into bounds instead to go
357+ // through the trait list (default type visitor doesn't visit those traits).
358+ // All traits in the list are considered the "primary" part of the type
359+ // and are visited by shallow visitors.
360+ try_visit ! ( self . visit_clauses( tcx. explicit_item_bounds( def_id) . skip_binder( ) ) ) ;
274361 }
275- // The intent is to treat `impl Trait1 + Trait2` identically to
276- // `dyn Trait1 + Trait2`. Therefore we ignore def-id of the opaque type itself
277- // (it either has no visibility, or its visibility is insignificant, like
278- // visibilities of type aliases) and recurse into bounds instead to go
279- // through the trait list (default type visitor doesn't visit those traits).
280- // All traits in the list are considered the "primary" part of the type
281- // and are visited by shallow visitors.
282- try_visit ! ( self . visit_clauses( tcx. explicit_item_bounds( def_id) . skip_binder( ) ) ) ;
283362 }
284363 // These types have neither their own def-ids nor subcomponents.
285364 ty:: Bool
@@ -303,17 +382,20 @@ where
303382 | ty:: FnPtr ( ..)
304383 | ty:: UnsafeBinder ( _)
305384 | ty:: Error ( _)
306- | ty:: CoroutineWitness ( ..) => {
307- if !self . visited_tys . insert ( ty) {
308- return V :: Result :: output ( ) ;
309- }
310- }
385+ | ty:: CoroutineWitness ( ..) => { }
311386 ty:: Placeholder ( ..) | ty:: Infer ( ..) => {
312387 bug ! ( "unexpected type: {:?}" , ty)
313388 }
314389 }
315390
316- if V :: SHALLOW { V :: Result :: output ( ) } else { ty. super_visit_with ( self ) }
391+ let result = if V :: SHALLOW { V :: Result :: output ( ) } else { ty. super_visit_with ( self ) } ;
392+
393+ if !new {
394+ let duration = instant. elapsed ( ) ;
395+ * brrr ( ) . entry ( Ty2 :: from_ty ( ty) ) . or_default ( ) += duration;
396+ }
397+
398+ result
317399 }
318400
319401 fn visit_const ( & mut self , c : Const < ' tcx > ) -> Self :: Result {
0 commit comments