1use rustc_hir::def::DefKind;
5use rustc_hir::def_id::LocalDefId;
6use rustc_middle::span_bug;
7use rustc_middle::ty::{self, TyCtxt, TypeVisitable, Unnormalized, VisitorResult, try_visit};
8use rustc_span::Span;
9use tracing::{instrument, trace};
10
11pub trait SpannedTypeVisitor<'tcx> {
12 type Result: VisitorResult = ();
13 fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
14}
15
16#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("walk_types",
"rustc_ty_utils::sig_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/sig_types.rs"),
::tracing_core::__macro_support::Option::Some(16u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::sig_types"),
::tracing_core::field::FieldSet::new(&["item"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&item)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: V::Result = loop {};
return __tracing_attr_fake_return;
}
{
let kind = tcx.def_kind(item);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_ty_utils/src/sig_types.rs:23",
"rustc_ty_utils::sig_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/sig_types.rs"),
::tracing_core::__macro_support::Option::Some(23u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::sig_types"),
::tracing_core::field::FieldSet::new(&["kind"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&kind) as
&dyn Value))])
});
} else { ; }
};
match kind {
DefKind::AssocFn | DefKind::Fn => {
let hir_sig =
tcx.hir_node_by_def_id(item).fn_decl().unwrap();
if hir_sig.output.is_suggestable_infer_ty().is_some() {
return V::Result::output();
}
let ty_sig =
tcx.fn_sig(item).instantiate_identity().skip_norm_wip();
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(hir_sig.output.span(),
ty_sig.output())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
for (hir, ty) in
hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(hir.span,
ty.map_bound(|x| *x))) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
for (pred, span) in
tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred.skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::TyAlias { .. } | DefKind::AssocTy | DefKind::Static {
.. } | DefKind::Const { .. } | DefKind::AssocConst { .. } |
DefKind::AnonConst => {
if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
if ty.is_suggestable_infer_ty() {
return V::Result::output();
}
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(ty.span,
tcx.type_of(item).instantiate_identity().skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
for (pred, span) in
tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred.skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::OpaqueTy => {
for (pred, span) in
tcx.explicit_item_bounds(item).iter_identity_copied().map(Unnormalized::skip_norm_wip)
{
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::Struct | DefKind::Union | DefKind::Enum => {
let span = tcx.def_ident_span(item).unwrap();
let ty =
tcx.type_of(item).instantiate_identity().skip_norm_wip();
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
ty)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
let ty::Adt(def, args) =
ty.kind() else {
::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("invalid type for {1:?}: {0:#?}", ty.kind(),
kind))
};
for field in def.all_fields() {
let span = tcx.def_ident_span(field.did).unwrap();
let ty = field.ty(tcx, args);
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
ty)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
for (pred, span) in
tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred.skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::InlineConst | DefKind::Closure |
DefKind::SyntheticCoroutineBody => {}
DefKind::Impl { of_trait } => {
if of_trait {
let span =
tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().trait_ref.path.span;
let args =
&tcx.impl_trait_ref(item).instantiate_identity().skip_norm_wip().args[1..];
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
args)) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
let span =
match tcx.hir_node_by_def_id(item).ty() {
Some(ty) => ty.span,
_ => tcx.def_span(item),
};
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
tcx.type_of(item).instantiate_identity().skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
for (pred, span) in
tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred.skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::TraitAlias | DefKind::Trait => {
for (pred, span) in
tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
pred.skip_norm_wip())) {
core::ops::ControlFlow::Continue(()) =>
(),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
}
};
}
}
DefKind::Variant | DefKind::TyParam | DefKind::ConstParam |
DefKind::Ctor(_, _) | DefKind::Field |
DefKind::LifetimeParam => {
::rustc_middle::util::bug::span_bug_fmt(tcx.def_span(item),
format_args!("{0:?} has not seen any uses of `walk_types` yet, ping oli-obk if you\'d like any help",
kind))
}
DefKind::ExternCrate | DefKind::ForeignMod |
DefKind::ForeignTy | DefKind::Macro(_) | DefKind::GlobalAsm
| DefKind::Mod | DefKind::Use => {}
}
V::Result::output()
}
}
}#[instrument(level = "trace", skip(tcx, visitor))]
17pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
18 tcx: TyCtxt<'tcx>,
19 item: LocalDefId,
20 visitor: &mut V,
21) -> V::Result {
22 let kind = tcx.def_kind(item);
23 trace!(?kind);
24 match kind {
25 DefKind::AssocFn | DefKind::Fn => {
27 let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
28 if hir_sig.output.is_suggestable_infer_ty().is_some() {
32 return V::Result::output();
33 }
34 let ty_sig = tcx.fn_sig(item).instantiate_identity().skip_norm_wip();
35 try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
37 for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
38 try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
39 }
40 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
41 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
42 }
43 }
44 DefKind::TyAlias { .. }
46 | DefKind::AssocTy
47 | DefKind::Static { .. }
48 | DefKind::Const { .. }
49 | DefKind::AssocConst { .. }
50 | DefKind::AnonConst => {
51 if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
52 if ty.is_suggestable_infer_ty() {
56 return V::Result::output();
57 }
58 try_visit!(
60 visitor
61 .visit(ty.span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
62 );
63 }
64 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
65 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
66 }
67 }
68 DefKind::OpaqueTy => {
69 for (pred, span) in tcx
70 .explicit_item_bounds(item)
71 .iter_identity_copied()
72 .map(Unnormalized::skip_norm_wip)
73 {
74 try_visit!(visitor.visit(span, pred));
75 }
76 }
77 DefKind::Struct | DefKind::Union | DefKind::Enum => {
79 let span = tcx.def_ident_span(item).unwrap();
80 let ty = tcx.type_of(item).instantiate_identity().skip_norm_wip();
81 try_visit!(visitor.visit(span, ty));
82 let ty::Adt(def, args) = ty.kind() else {
83 span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
84 };
85 for field in def.all_fields() {
86 let span = tcx.def_ident_span(field.did).unwrap();
87 let ty = field.ty(tcx, args);
88 try_visit!(visitor.visit(span, ty));
89 }
90 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
91 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
92 }
93 }
94 DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {}
98 DefKind::Impl { of_trait } => {
99 if of_trait {
100 let span = tcx
101 .hir_node_by_def_id(item)
102 .expect_item()
103 .expect_impl()
104 .of_trait
105 .unwrap()
106 .trait_ref
107 .path
108 .span;
109 let args =
110 &tcx.impl_trait_ref(item).instantiate_identity().skip_norm_wip().args[1..];
111 try_visit!(visitor.visit(span, args));
112 }
113 let span = match tcx.hir_node_by_def_id(item).ty() {
114 Some(ty) => ty.span,
115 _ => tcx.def_span(item),
116 };
117 try_visit!(
118 visitor.visit(span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
119 );
120 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
121 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
122 }
123 }
124 DefKind::TraitAlias | DefKind::Trait => {
125 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
126 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
127 }
128 }
129 DefKind::Variant
130 | DefKind::TyParam
131 | DefKind::ConstParam
132 | DefKind::Ctor(_, _)
133 | DefKind::Field
134 | DefKind::LifetimeParam => {
135 span_bug!(
136 tcx.def_span(item),
137 "{kind:?} has not seen any uses of `walk_types` yet, ping oli-obk if you'd like any help"
138 )
139 }
140 DefKind::ExternCrate
142 | DefKind::ForeignMod
143 | DefKind::ForeignTy
144 | DefKind::Macro(_)
145 | DefKind::GlobalAsm
146 | DefKind::Mod
147 | DefKind::Use => {}
148 }
149 V::Result::output()
150}