@@ -8,9 +8,13 @@ use rustc_middle::ty::{self, TyCtxt};
8
8
use rustc_span:: Span ;
9
9
use rustc_type_ir:: visit:: TypeVisitable ;
10
10
11
- pub trait SpannedTypeVisitor < ' tcx > {
11
+ pub trait SpannedTypeVisitor < ' tcx > : Sized {
12
12
type Result : VisitorResult = ( ) ;
13
- fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) -> Self :: Result ;
13
+ fn visit (
14
+ & mut self ,
15
+ get_span : impl Fn ( ) -> Span ,
16
+ value : impl TypeVisitable < TyCtxt < ' tcx > > ,
17
+ ) -> Self :: Result ;
14
18
}
15
19
16
20
pub fn walk_types < ' tcx , V : SpannedTypeVisitor < ' tcx > > (
@@ -24,48 +28,61 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
24
28
// Walk over the signature of the function
25
29
DefKind :: AssocFn | DefKind :: Fn => {
26
30
let ty_sig = tcx. fn_sig ( item) . instantiate_identity ( ) ;
27
- let hir_sig = tcx. hir_node_by_def_id ( item) . fn_decl ( ) . unwrap ( ) ;
31
+ let hir_sig = || tcx. hir_node_by_def_id ( item) . fn_decl ( ) . unwrap ( ) ;
28
32
// Walk over the inputs and outputs manually in order to get good spans for them.
29
- try_visit ! ( visitor. visit( hir_sig. output. span( ) , ty_sig. output( ) ) ) ;
30
- for ( hir, ty) in hir_sig . inputs . iter ( ) . zip ( ty_sig. inputs ( ) . iter ( ) ) {
31
- try_visit ! ( visitor. visit( hir. span, ty. map_bound( |x| * x) ) ) ;
33
+ try_visit ! ( visitor. visit( || hir_sig( ) . output. span( ) , ty_sig. output( ) ) ) ;
34
+ for ( hir, ty) in ty_sig. inputs ( ) . iter ( ) . enumerate ( ) {
35
+ try_visit ! ( visitor. visit( || hir_sig ( ) . inputs [ hir] . span, ty. map_bound( |x| * x) ) ) ;
32
36
}
33
37
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
34
- try_visit ! ( visitor. visit( span, pred) ) ;
38
+ try_visit ! ( visitor. visit( || span, pred) ) ;
35
39
}
36
40
}
37
- // Walk over the type behind the alias
38
- DefKind :: TyAlias { ..} | DefKind :: AssocTy |
39
- // Walk over the type of the item
40
- DefKind :: Static ( _) | DefKind :: Const | DefKind :: AssocConst | DefKind :: AnonConst => {
41
+ DefKind :: AssocTy => {
41
42
if let Some ( ty) = tcx. hir_node_by_def_id ( item) . ty ( ) {
42
43
// Associated types in traits don't necessarily have a type that we can visit
43
- try_visit ! ( visitor. visit( ty. span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
44
+ try_visit ! ( visitor. visit( || ty. span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
45
+ }
46
+ for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
47
+ try_visit ! ( visitor. visit( || span, pred) ) ;
48
+ }
49
+ }
50
+ // Walk over the type behind the alias
51
+ DefKind :: TyAlias { .. } |
52
+ // Walk over the type of the item
53
+ DefKind :: Static ( _) | DefKind :: Const | DefKind :: AssocConst => {
54
+ let span = || tcx. hir_node_by_def_id ( item) . ty ( ) . unwrap ( ) . span ;
55
+ try_visit ! ( visitor. visit( span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
56
+
57
+ for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
58
+ try_visit ! ( visitor. visit( || span, pred) ) ;
44
59
}
60
+ }
61
+ DefKind :: AnonConst => {
45
62
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
46
- try_visit ! ( visitor. visit( span, pred) ) ;
63
+ try_visit ! ( visitor. visit( || span, pred) ) ;
47
64
}
48
65
}
49
66
DefKind :: OpaqueTy => {
50
67
for ( pred, span) in tcx. explicit_item_bounds ( item) . instantiate_identity_iter_copied ( ) {
51
- try_visit ! ( visitor. visit( span, pred) ) ;
68
+ try_visit ! ( visitor. visit( || span, pred) ) ;
52
69
}
53
70
}
54
71
// Look at field types
55
72
DefKind :: Struct | DefKind :: Union | DefKind :: Enum => {
56
- let span = tcx. def_ident_span ( item) . unwrap ( ) ;
73
+ let span = || tcx. def_ident_span ( item) . unwrap ( ) ;
57
74
let ty = tcx. type_of ( item) . instantiate_identity ( ) ;
58
75
try_visit ! ( visitor. visit( span, ty) ) ;
59
76
let ty:: Adt ( def, args) = ty. kind ( ) else {
60
- span_bug ! ( span, "invalid type for {kind:?}: {:#?}" , ty. kind( ) )
77
+ span_bug ! ( span( ) , "invalid type for {kind:?}: {:#?}" , ty. kind( ) )
61
78
} ;
62
79
for field in def. all_fields ( ) {
63
- let span = tcx. def_ident_span ( field. did ) . unwrap ( ) ;
80
+ let span = || tcx. def_ident_span ( field. did ) . unwrap ( ) ;
64
81
let ty = field. ty ( tcx, args) ;
65
82
try_visit ! ( visitor. visit( span, ty) ) ;
66
83
}
67
84
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
68
- try_visit ! ( visitor. visit( span, pred) ) ;
85
+ try_visit ! ( visitor. visit( || span, pred) ) ;
69
86
}
70
87
}
71
88
// These are not part of a public API, they can only appear as hidden types, and there
@@ -74,25 +91,33 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
74
91
DefKind :: InlineConst | DefKind :: Closure => { }
75
92
DefKind :: Impl { of_trait } => {
76
93
if of_trait {
77
- let span = tcx. hir_node_by_def_id ( item) . expect_item ( ) . expect_impl ( ) . of_trait . unwrap ( ) . path . span ;
94
+ let span = || {
95
+ tcx. hir_node_by_def_id ( item)
96
+ . expect_item ( )
97
+ . expect_impl ( )
98
+ . of_trait
99
+ . unwrap ( )
100
+ . path
101
+ . span
102
+ } ;
78
103
let args = & tcx. impl_trait_ref ( item) . unwrap ( ) . instantiate_identity ( ) . args [ 1 ..] ;
79
104
try_visit ! ( visitor. visit( span, args) ) ;
80
105
}
81
- let span = match tcx. hir_node_by_def_id ( item) . ty ( ) {
106
+ let span = || match tcx. hir_node_by_def_id ( item) . ty ( ) {
82
107
Some ( ty) => ty. span ,
83
108
_ => tcx. def_span ( item) ,
84
109
} ;
85
110
try_visit ! ( visitor. visit( span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
86
111
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
87
- try_visit ! ( visitor. visit( span, pred) ) ;
112
+ try_visit ! ( visitor. visit( || span, pred) ) ;
88
113
}
89
114
}
90
115
DefKind :: TraitAlias | DefKind :: Trait => {
91
116
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
92
- try_visit ! ( visitor. visit( span, pred) ) ;
117
+ try_visit ! ( visitor. visit( || span, pred) ) ;
93
118
}
94
119
}
95
- | DefKind :: Variant
120
+ DefKind :: Variant
96
121
| DefKind :: TyParam
97
122
| DefKind :: ConstParam
98
123
| DefKind :: Ctor ( _, _)
@@ -104,7 +129,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
104
129
)
105
130
}
106
131
// These don't have any types.
107
- | DefKind :: ExternCrate
132
+ DefKind :: ExternCrate
108
133
| DefKind :: ForeignMod
109
134
| DefKind :: ForeignTy
110
135
| DefKind :: Macro ( _)
0 commit comments