1use rustc_hir::def::DefKind;
5use rustc_hir::def_id::LocalDefId;
6use rustc_middle::span_bug;
7use rustc_middle::ty::{self, TyCtxt, TypeVisitable, 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();
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)) {
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())) {
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)) {
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() {
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();
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)) {
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().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())) {
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)) {
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)) {
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();
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));
42 }
43 }
44 DefKind::TyAlias { .. } | DefKind::AssocTy |
46 DefKind::Static { .. } | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
48 if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
49 if ty.is_suggestable_infer_ty() {
53 return V::Result::output();
54 }
55 try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
57 }
58 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
59 try_visit!(visitor.visit(span, pred));
60 }
61 }
62 DefKind::OpaqueTy => {
63 for (pred, span) in tcx.explicit_item_bounds(item).iter_identity_copied() {
64 try_visit!(visitor.visit(span, pred));
65 }
66 }
67 DefKind::Struct | DefKind::Union | DefKind::Enum => {
69 let span = tcx.def_ident_span(item).unwrap();
70 let ty = tcx.type_of(item).instantiate_identity();
71 try_visit!(visitor.visit(span, ty));
72 let ty::Adt(def, args) = ty.kind() else {
73 span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
74 };
75 for field in def.all_fields() {
76 let span = tcx.def_ident_span(field.did).unwrap();
77 let ty = field.ty(tcx, args);
78 try_visit!(visitor.visit(span, ty));
79 }
80 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
81 try_visit!(visitor.visit(span, pred));
82 }
83 }
84 DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {}
88 DefKind::Impl { of_trait } => {
89 if of_trait {
90 let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().trait_ref.path.span;
91 let args = &tcx.impl_trait_ref(item).instantiate_identity().args[1..];
92 try_visit!(visitor.visit(span, args));
93 }
94 let span = match tcx.hir_node_by_def_id(item).ty() {
95 Some(ty) => ty.span,
96 _ => tcx.def_span(item),
97 };
98 try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
99 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
100 try_visit!(visitor.visit(span, pred));
101 }
102 }
103 DefKind::TraitAlias | DefKind::Trait => {
104 for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
105 try_visit!(visitor.visit(span, pred));
106 }
107 }
108 | DefKind::Variant
109 | DefKind::TyParam
110 | DefKind::ConstParam
111 | DefKind::Ctor(_, _)
112 | DefKind::Field
113 | DefKind::LifetimeParam => {
114 span_bug!(
115 tcx.def_span(item),
116 "{kind:?} has not seen any uses of `walk_types` yet, ping oli-obk if you'd like any help"
117 )
118 }
119 | DefKind::ExternCrate
121 | DefKind::ForeignMod
122 | DefKind::ForeignTy
123 | DefKind::Macro(_)
124 | DefKind::GlobalAsm
125 | DefKind::Mod
126 | DefKind::Use => {}
127 }
128 V::Result::output()
129}