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-
64use rustc_hir::{def::DefKind, def_id::LocalDefId};
75use rustc_middle::ty::{self, TyCtxt};
86use 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};
109
1110pub 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;
1813}
1914
2015pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
2116 tcx: TyCtxt<'tcx>,
2217 item: LocalDefId,
2318 visitor: &mut V,
24- ) -> ControlFlow< V::BreakTy> {
19+ ) -> V::Result {
2520 let kind = tcx.def_kind(item);
2621 trace!(?kind);
2722 match kind {
@@ -30,12 +25,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
3025 let ty_sig = tcx.fn_sig(item).instantiate_identity();
3126 let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
3227 // 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() ));
3429 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))) ;
3631 }
3732 for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
38- visitor.visit(span, pred)? ;
33+ try_visit!( visitor.visit(span, pred)) ;
3934 }
4035 }
4136 // Walk over the type behind the alias
@@ -44,32 +39,32 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
4439 DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
4540 if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
4641 // 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())) ;
4843 }
4944 for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
50- visitor.visit(span, pred)? ;
45+ try_visit!( visitor.visit(span, pred)) ;
5146 }
5247 }
5348 DefKind::OpaqueTy => {
5449 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)) ;
5651 }
5752 }
5853 // Look at field types
5954 DefKind::Struct | DefKind::Union | DefKind::Enum => {
6055 let span = tcx.def_ident_span(item).unwrap();
6156 let ty = tcx.type_of(item).instantiate_identity();
62- visitor.visit(span, ty);
57+ try_visit!( visitor.visit(span, ty) );
6358 let ty::Adt(def, args) = ty.kind() else {
6459 span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
6560 };
6661 for field in def.all_fields() {
6762 let span = tcx.def_ident_span(field.did).unwrap();
6863 let ty = field.ty(tcx, args);
69- visitor.visit(span, ty);
64+ try_visit!( visitor.visit(span, ty) );
7065 }
7166 for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
72- visitor.visit(span, pred)? ;
67+ try_visit!( visitor.visit(span, pred)) ;
7368 }
7469 }
7570 // 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>>(
8075 if of_trait {
8176 let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
8277 let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..];
83- visitor.visit(span, args)? ;
78+ try_visit!( visitor.visit(span, args)) ;
8479 }
8580 let span = match tcx.hir_node_by_def_id(item).ty() {
8681 Some(ty) => ty.span,
8782 _ => tcx.def_span(item),
8883 };
89- visitor.visit(span, tcx.type_of(item).instantiate_identity());
84+ try_visit!( visitor.visit(span, tcx.type_of(item).instantiate_identity() ));
9085 for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
91- visitor.visit(span, pred)? ;
86+ try_visit!( visitor.visit(span, pred)) ;
9287 }
9388 }
9489 DefKind::TraitAlias | DefKind::Trait => {
9590 for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
96- visitor.visit(span, pred)? ;
91+ try_visit!( visitor.visit(span, pred)) ;
9792 }
9893 }
9994 | DefKind::Variant
@@ -116,5 +111,5 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
116111 | DefKind::Mod
117112 | DefKind::Use => {}
118113 }
119- ControlFlow::Continue(() )
114+ V::Result::output( )
120115}
0 commit comments