@@ -43,6 +43,50 @@ pub struct Class<'db> {
43
43
pub ( crate ) known : Option < KnownClass > ,
44
44
}
45
45
46
+ fn explicit_bases_cycle_recover < ' db > (
47
+ _db : & ' db dyn Db ,
48
+ _value : & [ Type < ' db > ] ,
49
+ _count : u32 ,
50
+ _self : Class < ' db > ,
51
+ ) -> salsa:: CycleRecoveryAction < Box < [ Type < ' db > ] > > {
52
+ salsa:: CycleRecoveryAction :: Iterate
53
+ }
54
+
55
+ fn explicit_bases_cycle_initial < ' db > ( _db : & ' db dyn Db , _self : Class < ' db > ) -> Box < [ Type < ' db > ] > {
56
+ Box :: default ( )
57
+ }
58
+
59
+ fn try_mro_cycle_recover < ' db > (
60
+ _db : & ' db dyn Db ,
61
+ _value : & Result < Mro < ' db > , MroError < ' db > > ,
62
+ _count : u32 ,
63
+ _self : Class < ' db > ,
64
+ ) -> salsa:: CycleRecoveryAction < Result < Mro < ' db > , MroError < ' db > > > {
65
+ salsa:: CycleRecoveryAction :: Iterate
66
+ }
67
+
68
+ #[ allow( clippy:: unnecessary_wraps) ]
69
+ fn try_mro_cycle_initial < ' db > (
70
+ db : & ' db dyn Db ,
71
+ self_ : Class < ' db > ,
72
+ ) -> Result < Mro < ' db > , MroError < ' db > > {
73
+ Ok ( Mro :: from_error ( db, self_) )
74
+ }
75
+
76
+ #[ allow( clippy:: ref_option, clippy:: trivially_copy_pass_by_ref) ]
77
+ fn inheritance_cycle_recover < ' db > (
78
+ _db : & ' db dyn Db ,
79
+ _value : & Option < InheritanceCycle > ,
80
+ _count : u32 ,
81
+ _self : Class < ' db > ,
82
+ ) -> salsa:: CycleRecoveryAction < Option < InheritanceCycle > > {
83
+ salsa:: CycleRecoveryAction :: Iterate
84
+ }
85
+
86
+ fn inheritance_cycle_initial < ' db > ( _db : & ' db dyn Db , _self : Class < ' db > ) -> Option < InheritanceCycle > {
87
+ None
88
+ }
89
+
46
90
#[ salsa:: tracked]
47
91
impl < ' db > Class < ' db > {
48
92
/// Return `true` if this class represents `known_class`
@@ -81,8 +125,9 @@ impl<'db> Class<'db> {
81
125
. map ( |ClassLiteralType { class } | class)
82
126
}
83
127
84
- #[ salsa:: tracked( return_ref) ]
128
+ #[ salsa:: tracked( return_ref, cycle_fn=explicit_bases_cycle_recover , cycle_initial=explicit_bases_cycle_initial ) ]
85
129
fn explicit_bases_query ( self , db : & ' db dyn Db ) -> Box < [ Type < ' db > ] > {
130
+ tracing:: trace!( "Class::explicit_bases_query: {}" , self . name( db) ) ;
86
131
let class_stmt = self . node ( db) ;
87
132
88
133
let class_definition = semantic_index ( db, self . file ( db) ) . definition ( class_stmt) ;
@@ -110,6 +155,7 @@ impl<'db> Class<'db> {
110
155
/// Return the types of the decorators on this class
111
156
#[ salsa:: tracked( return_ref) ]
112
157
fn decorators ( self , db : & ' db dyn Db ) -> Box < [ Type < ' db > ] > {
158
+ tracing:: trace!( "Class::decorators: {}" , self . name( db) ) ;
113
159
let class_stmt = self . node ( db) ;
114
160
if class_stmt. decorator_list . is_empty ( ) {
115
161
return Box :: new ( [ ] ) ;
@@ -141,8 +187,9 @@ impl<'db> Class<'db> {
141
187
/// attribute on a class at runtime.
142
188
///
143
189
/// [method resolution order]: https://docs.python.org/3/glossary.html#term-method-resolution-order
144
- #[ salsa:: tracked( return_ref) ]
190
+ #[ salsa:: tracked( return_ref, cycle_fn=try_mro_cycle_recover , cycle_initial=try_mro_cycle_initial ) ]
145
191
pub ( super ) fn try_mro ( self , db : & ' db dyn Db ) -> Result < Mro < ' db > , MroError < ' db > > {
192
+ tracing:: trace!( "Class::try_mro: {}" , self . name( db) ) ;
146
193
Mro :: of_class ( db, self )
147
194
}
148
195
@@ -199,6 +246,8 @@ impl<'db> Class<'db> {
199
246
/// Return the metaclass of this class, or an error if the metaclass cannot be inferred.
200
247
#[ salsa:: tracked]
201
248
pub ( super ) fn try_metaclass ( self , db : & ' db dyn Db ) -> Result < Type < ' db > , MetaclassError < ' db > > {
249
+ tracing:: trace!( "Class::try_metaclass: {}" , self . name( db) ) ;
250
+
202
251
// Identify the class's own metaclass (or take the first base class's metaclass).
203
252
let mut base_classes = self . fully_static_explicit_bases ( db) . peekable ( ) ;
204
253
@@ -662,7 +711,7 @@ impl<'db> Class<'db> {
662
711
///
663
712
/// A class definition like this will fail at runtime,
664
713
/// but we must be resilient to it or we could panic.
665
- #[ salsa:: tracked]
714
+ #[ salsa:: tracked( cycle_fn=inheritance_cycle_recover , cycle_initial=inheritance_cycle_initial ) ]
666
715
pub ( super ) fn inheritance_cycle ( self , db : & ' db dyn Db ) -> Option < InheritanceCycle > {
667
716
/// Return `true` if the class is cyclically defined.
668
717
///
@@ -694,6 +743,8 @@ impl<'db> Class<'db> {
694
743
result
695
744
}
696
745
746
+ tracing:: trace!( "Class::inheritance_cycle: {}" , self . name( db) ) ;
747
+
697
748
let visited_classes = & mut IndexSet :: new ( ) ;
698
749
if !is_cyclically_defined_recursive ( db, self , & mut IndexSet :: new ( ) , visited_classes) {
699
750
None
0 commit comments