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