1
1
//! This module contains helpers for walking all types of
2
2
//! a signature, while preserving spans as much as possible
3
3
4
- use std :: ops :: ControlFlow ;
5
-
4
+ use rustc_ast_ir :: try_visit ;
5
+ use rustc_ast_ir :: visit :: VisitorResult ;
6
6
use rustc_hir:: { def:: DefKind , def_id:: LocalDefId } ;
7
7
use rustc_middle:: ty:: { self , TyCtxt } ;
8
8
use rustc_span:: Span ;
9
9
use rustc_type_ir:: visit:: TypeVisitable ;
10
10
11
11
pub trait SpannedTypeVisitor < ' tcx > {
12
- type BreakTy = !;
13
- fn visit (
14
- & mut self ,
15
- span : Span ,
16
- value : impl TypeVisitable < TyCtxt < ' tcx > > ,
17
- ) -> ControlFlow < Self :: BreakTy > ;
12
+ type Result : VisitorResult = ( ) ;
13
+ fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) -> Self :: Result ;
18
14
}
19
15
20
16
pub fn walk_types < ' tcx , V : SpannedTypeVisitor < ' tcx > > (
21
17
tcx : TyCtxt < ' tcx > ,
22
18
item : LocalDefId ,
23
19
visitor : & mut V ,
24
- ) -> ControlFlow < V :: BreakTy > {
20
+ ) -> V :: Result {
25
21
let kind = tcx. def_kind ( item) ;
26
22
trace ! ( ?kind) ;
27
23
match kind {
@@ -30,12 +26,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
30
26
let ty_sig = tcx. fn_sig ( item) . instantiate_identity ( ) ;
31
27
let hir_sig = tcx. hir_node_by_def_id ( item) . fn_decl ( ) . unwrap ( ) ;
32
28
// Walk over the inputs and outputs manually in order to get good spans for them.
33
- visitor. visit ( hir_sig. output . span ( ) , ty_sig. output ( ) ) ;
29
+ try_visit ! ( visitor. visit( hir_sig. output. span( ) , ty_sig. output( ) ) ) ;
34
30
for ( hir, ty) in hir_sig. inputs . iter ( ) . zip ( ty_sig. inputs ( ) . iter ( ) ) {
35
- visitor. visit ( hir. span , ty. map_bound ( |x| * x) ) ? ;
31
+ try_visit ! ( visitor. visit( hir. span, ty. map_bound( |x| * x) ) ) ;
36
32
}
37
33
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
38
- visitor. visit ( span, pred) ? ;
34
+ try_visit ! ( visitor. visit( span, pred) ) ;
39
35
}
40
36
}
41
37
// Walk over the type behind the alias
@@ -44,32 +40,32 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
44
40
DefKind :: Static ( _) | DefKind :: Const | DefKind :: AssocConst | DefKind :: AnonConst => {
45
41
if let Some ( ty) = tcx. hir_node_by_def_id ( item) . ty ( ) {
46
42
// Associated types in traits don't necessarily have a type that we can visit
47
- visitor. visit ( ty. span , tcx. type_of ( item) . instantiate_identity ( ) ) ? ;
43
+ try_visit ! ( visitor. visit( ty. span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
48
44
}
49
45
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
50
- visitor. visit ( span, pred) ? ;
46
+ try_visit ! ( visitor. visit( span, pred) ) ;
51
47
}
52
48
}
53
49
DefKind :: OpaqueTy => {
54
50
for ( pred, span) in tcx. explicit_item_bounds ( item) . instantiate_identity_iter_copied ( ) {
55
- visitor. visit ( span, pred) ? ;
51
+ try_visit ! ( visitor. visit( span, pred) ) ;
56
52
}
57
53
}
58
54
// Look at field types
59
55
DefKind :: Struct | DefKind :: Union | DefKind :: Enum => {
60
56
let span = tcx. def_ident_span ( item) . unwrap ( ) ;
61
57
let ty = tcx. type_of ( item) . instantiate_identity ( ) ;
62
- visitor. visit ( span, ty) ;
58
+ try_visit ! ( visitor. visit( span, ty) ) ;
63
59
let ty:: Adt ( def, args) = ty. kind ( ) else {
64
60
span_bug ! ( span, "invalid type for {kind:?}: {:#?}" , ty. kind( ) )
65
61
} ;
66
62
for field in def. all_fields ( ) {
67
63
let span = tcx. def_ident_span ( field. did ) . unwrap ( ) ;
68
64
let ty = field. ty ( tcx, args) ;
69
- visitor. visit ( span, ty) ;
65
+ try_visit ! ( visitor. visit( span, ty) ) ;
70
66
}
71
67
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
72
- visitor. visit ( span, pred) ? ;
68
+ try_visit ! ( visitor. visit( span, pred) ) ;
73
69
}
74
70
}
75
71
// These are not part of a public API, they can only appear as hidden types, and there
@@ -80,20 +76,20 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
80
76
if of_trait {
81
77
let span = tcx. hir_node_by_def_id ( item) . expect_item ( ) . expect_impl ( ) . of_trait . unwrap ( ) . path . span ;
82
78
let args = & tcx. impl_trait_ref ( item) . unwrap ( ) . instantiate_identity ( ) . args [ 1 ..] ;
83
- visitor. visit ( span, args) ? ;
79
+ try_visit ! ( visitor. visit( span, args) ) ;
84
80
}
85
81
let span = match tcx. hir_node_by_def_id ( item) . ty ( ) {
86
82
Some ( ty) => ty. span ,
87
83
_ => tcx. def_span ( item) ,
88
84
} ;
89
- visitor. visit ( span, tcx. type_of ( item) . instantiate_identity ( ) ) ;
85
+ try_visit ! ( visitor. visit( span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
90
86
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
91
- visitor. visit ( span, pred) ? ;
87
+ try_visit ! ( visitor. visit( span, pred) ) ;
92
88
}
93
89
}
94
90
DefKind :: TraitAlias | DefKind :: Trait => {
95
91
for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
96
- visitor. visit ( span, pred) ? ;
92
+ try_visit ! ( visitor. visit( span, pred) ) ;
97
93
}
98
94
}
99
95
| DefKind :: Variant
@@ -116,5 +112,5 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
116
112
| DefKind :: Mod
117
113
| DefKind :: Use => { }
118
114
}
119
- ControlFlow :: Continue ( ( ) )
115
+ V :: Result :: output ( )
120
116
}
0 commit comments