11//! This module contains helpers for walking all types of
22//! a signature, while preserving spans as much as possible
33
4- use std :: ops :: ControlFlow ;
5-
4+ use rustc_ast_ir :: try_visit ;
5+ use rustc_ast_ir :: visit :: VisitorResult ;
66use rustc_hir:: { def:: DefKind , def_id:: LocalDefId } ;
77use rustc_middle:: ty:: { self , TyCtxt } ;
88use rustc_span:: Span ;
99use rustc_type_ir:: visit:: TypeVisitable ;
1010
1111pub 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 ;
1814}
1915
2016pub fn walk_types < ' tcx , V : SpannedTypeVisitor < ' tcx > > (
2117 tcx : TyCtxt < ' tcx > ,
2218 item : LocalDefId ,
2319 visitor : & mut V ,
24- ) -> ControlFlow < V :: BreakTy > {
20+ ) -> V :: Result {
2521 let kind = tcx. def_kind ( item) ;
2622 trace ! ( ?kind) ;
2723 match kind {
@@ -30,12 +26,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
3026 let ty_sig = tcx. fn_sig ( item) . instantiate_identity ( ) ;
3127 let hir_sig = tcx. hir_node_by_def_id ( item) . fn_decl ( ) . unwrap ( ) ;
3228 // 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( ) ) ) ;
3430 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) ) ) ;
3632 }
3733 for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
38- visitor. visit ( span, pred) ? ;
34+ try_visit ! ( visitor. visit( span, pred) ) ;
3935 }
4036 }
4137 // Walk over the type behind the alias
@@ -44,32 +40,32 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
4440 DefKind :: Static ( _) | DefKind :: Const | DefKind :: AssocConst | DefKind :: AnonConst => {
4541 if let Some ( ty) = tcx. hir_node_by_def_id ( item) . ty ( ) {
4642 // 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( ) ) ) ;
4844 }
4945 for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
50- visitor. visit ( span, pred) ? ;
46+ try_visit ! ( visitor. visit( span, pred) ) ;
5147 }
5248 }
5349 DefKind :: OpaqueTy => {
5450 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) ) ;
5652 }
5753 }
5854 // Look at field types
5955 DefKind :: Struct | DefKind :: Union | DefKind :: Enum => {
6056 let span = tcx. def_ident_span ( item) . unwrap ( ) ;
6157 let ty = tcx. type_of ( item) . instantiate_identity ( ) ;
62- visitor. visit ( span, ty) ;
58+ try_visit ! ( visitor. visit( span, ty) ) ;
6359 let ty:: Adt ( def, args) = ty. kind ( ) else {
6460 span_bug ! ( span, "invalid type for {kind:?}: {:#?}" , ty. kind( ) )
6561 } ;
6662 for field in def. all_fields ( ) {
6763 let span = tcx. def_ident_span ( field. did ) . unwrap ( ) ;
6864 let ty = field. ty ( tcx, args) ;
69- visitor. visit ( span, ty) ;
65+ try_visit ! ( visitor. visit( span, ty) ) ;
7066 }
7167 for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
72- visitor. visit ( span, pred) ? ;
68+ try_visit ! ( visitor. visit( span, pred) ) ;
7369 }
7470 }
7571 // 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>>(
8076 if of_trait {
8177 let span = tcx. hir_node_by_def_id ( item) . expect_item ( ) . expect_impl ( ) . of_trait . unwrap ( ) . path . span ;
8278 let args = & tcx. impl_trait_ref ( item) . unwrap ( ) . instantiate_identity ( ) . args [ 1 ..] ;
83- visitor. visit ( span, args) ? ;
79+ try_visit ! ( visitor. visit( span, args) ) ;
8480 }
8581 let span = match tcx. hir_node_by_def_id ( item) . ty ( ) {
8682 Some ( ty) => ty. span ,
8783 _ => tcx. def_span ( item) ,
8884 } ;
89- visitor. visit ( span, tcx. type_of ( item) . instantiate_identity ( ) ) ;
85+ try_visit ! ( visitor. visit( span, tcx. type_of( item) . instantiate_identity( ) ) ) ;
9086 for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
91- visitor. visit ( span, pred) ? ;
87+ try_visit ! ( visitor. visit( span, pred) ) ;
9288 }
9389 }
9490 DefKind :: TraitAlias | DefKind :: Trait => {
9591 for ( pred, span) in tcx. predicates_of ( item) . instantiate_identity ( tcx) {
96- visitor. visit ( span, pred) ? ;
92+ try_visit ! ( visitor. visit( span, pred) ) ;
9793 }
9894 }
9995 | DefKind :: Variant
@@ -116,5 +112,5 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
116112 | DefKind :: Mod
117113 | DefKind :: Use => { }
118114 }
119- ControlFlow :: Continue ( ( ) )
115+ V :: Result :: output ( )
120116}
0 commit comments