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 { ; }
};
let mut visit_alias =
||
{
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);
}
};
}
V::Result::output()
};
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 => return visit_alias(),
DefKind::InlineConst if tcx.is_type_system_inline_const(item)
=> return visit_alias(),
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 let mut visit_alias = || {
25 if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
26 if ty.is_suggestable_infer_ty() {
30 return V::Result::output();
31 }
32 try_visit!(
34 visitor.visit(ty.span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
35 );
36 }
37 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
38 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
39 }
40 V::Result::output()
41 };
42 match kind {
43 DefKind::AssocFn | DefKind::Fn => {
45 let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
46 if hir_sig.output.is_suggestable_infer_ty().is_some() {
50 return V::Result::output();
51 }
52 let ty_sig = tcx.fn_sig(item).instantiate_identity().skip_norm_wip();
53 try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
55 for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
56 try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
57 }
58 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
59 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
60 }
61 }
62 DefKind::TyAlias { .. }
64 | DefKind::AssocTy
65 | DefKind::Static { .. }
66 | DefKind::Const { .. }
67 | DefKind::AssocConst { .. }
68 | DefKind::AnonConst => return visit_alias(),
69 DefKind::InlineConst if tcx.is_type_system_inline_const(item) => return visit_alias(),
70 DefKind::OpaqueTy => {
71 for (pred, span) in tcx
72 .explicit_item_bounds(item)
73 .iter_identity_copied()
74 .map(Unnormalized::skip_norm_wip)
75 {
76 try_visit!(visitor.visit(span, pred));
77 }
78 }
79 DefKind::Struct | DefKind::Union | DefKind::Enum => {
81 let span = tcx.def_ident_span(item).unwrap();
82 let ty = tcx.type_of(item).instantiate_identity().skip_norm_wip();
83 try_visit!(visitor.visit(span, ty));
84 let ty::Adt(def, args) = ty.kind() else {
85 span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
86 };
87 for field in def.all_fields() {
88 let span = tcx.def_ident_span(field.did).unwrap();
89 let ty = field.ty(tcx, args);
90 try_visit!(visitor.visit(span, ty));
91 }
92 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
93 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
94 }
95 }
96 DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {}
100 DefKind::Impl { of_trait } => {
101 if of_trait {
102 let span = tcx
103 .hir_node_by_def_id(item)
104 .expect_item()
105 .expect_impl()
106 .of_trait
107 .unwrap()
108 .trait_ref
109 .path
110 .span;
111 let args =
112 &tcx.impl_trait_ref(item).instantiate_identity().skip_norm_wip().args[1..];
113 try_visit!(visitor.visit(span, args));
114 }
115 let span = match tcx.hir_node_by_def_id(item).ty() {
116 Some(ty) => ty.span,
117 _ => tcx.def_span(item),
118 };
119 try_visit!(
120 visitor.visit(span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
121 );
122 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
123 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
124 }
125 }
126 DefKind::TraitAlias | DefKind::Trait => {
127 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
128 try_visit!(visitor.visit(span, pred.skip_norm_wip()));
129 }
130 }
131 DefKind::Variant
132 | DefKind::TyParam
133 | DefKind::ConstParam
134 | DefKind::Ctor(_, _)
135 | DefKind::Field
136 | DefKind::LifetimeParam => {
137 span_bug!(
138 tcx.def_span(item),
139 "{kind:?} has not seen any uses of `walk_types` yet, ping oli-obk if you'd like any help"
140 )
141 }
142 DefKind::ExternCrate
144 | DefKind::ForeignMod
145 | DefKind::ForeignTy
146 | DefKind::Macro(_)
147 | DefKind::GlobalAsm
148 | DefKind::Mod
149 | DefKind::Use => {}
150 }
151 V::Result::output()
152}