1#![feature(associated_type_defaults)]
6use rustc_hir::def::DefKind;
9use rustc_hir::def_id::LocalDefId;
10use rustc_middle::span_bug;
11use rustc_middle::ty::{self, TyCtxt, TypeVisitable, Unnormalized, VisitorResult, try_visit};
12use rustc_span::Span;
13use tracing::{instrument, trace};
14
15pub trait SpannedTypeVisitor<'tcx> {
16 type Result: VisitorResult = ();
17 fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
18}
19
20#[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_walk", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_walk/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(20u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_walk"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("item")
}> =
::tracing::__macro_support::FieldName::new("item");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&item)
as &dyn ::tracing::field::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_walk/src/lib.rs:27",
"rustc_ty_walk", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_walk/src/lib.rs"),
::tracing_core::__macro_support::Option::Some(27u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_walk"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("kind")
}> =
::tracing::__macro_support::FieldName::new("kind");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&kind)
as &dyn ::tracing::field::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 (clause, span) in
tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
clause.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 (clause, span) in
tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
clause.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 { .. } =>
return visit_alias(),
DefKind::AnonConst if
tcx.anon_const_kind(item) !=
ty::AnonConstKind::NonTypeSystemInline => {
return visit_alias();
}
DefKind::AnonConst | DefKind::Closure |
DefKind::SyntheticCoroutineBody => {}
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 (clause, span) in
tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
clause.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::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 (clause, span) in
tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
clause.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 (clause, span) in
tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
match ::rustc_ast_ir::visit::VisitorResult::branch(visitor.visit(span,
clause.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))]
21pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
22 tcx: TyCtxt<'tcx>,
23 item: LocalDefId,
24 visitor: &mut V,
25) -> V::Result {
26 let kind = tcx.def_kind(item);
27 trace!(?kind);
28 let mut visit_alias = || {
29 if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
30 if ty.is_suggestable_infer_ty() {
34 return V::Result::output();
35 }
36 try_visit!(
38 visitor.visit(ty.span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
39 );
40 }
41 for (clause, span) in tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
42 try_visit!(visitor.visit(span, clause.skip_norm_wip()));
43 }
44 V::Result::output()
45 };
46 match kind {
47 DefKind::AssocFn | DefKind::Fn => {
49 let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
50 if hir_sig.output.is_suggestable_infer_ty().is_some() {
54 return V::Result::output();
55 }
56 let ty_sig = tcx.fn_sig(item).instantiate_identity().skip_norm_wip();
57 try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
59 for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
60 try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
61 }
62 for (clause, span) in tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
63 try_visit!(visitor.visit(span, clause.skip_norm_wip()));
64 }
65 }
66 DefKind::TyAlias { .. }
68 | DefKind::AssocTy
69 | DefKind::Static { .. }
70 | DefKind::Const { .. }
71 | DefKind::AssocConst { .. } => return visit_alias(),
72 DefKind::AnonConst
73 if tcx.anon_const_kind(item) != ty::AnonConstKind::NonTypeSystemInline =>
74 {
75 return visit_alias();
76 }
77 DefKind::AnonConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {}
81 DefKind::OpaqueTy => {
82 for (pred, span) in tcx
83 .explicit_item_bounds(item)
84 .iter_identity_copied()
85 .map(Unnormalized::skip_norm_wip)
86 {
87 try_visit!(visitor.visit(span, pred));
88 }
89 }
90 DefKind::Struct | DefKind::Union | DefKind::Enum => {
92 let span = tcx.def_ident_span(item).unwrap();
93 let ty = tcx.type_of(item).instantiate_identity().skip_norm_wip();
94 try_visit!(visitor.visit(span, ty));
95 let ty::Adt(def, args) = ty.kind() else {
96 span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
97 };
98 for field in def.all_fields() {
99 let span = tcx.def_ident_span(field.did).unwrap();
100 let ty = field.ty(tcx, args);
101 try_visit!(visitor.visit(span, ty));
102 }
103 for (clause, span) in tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
104 try_visit!(visitor.visit(span, clause.skip_norm_wip()));
105 }
106 }
107 DefKind::Impl { of_trait } => {
108 if of_trait {
109 let span = tcx
110 .hir_node_by_def_id(item)
111 .expect_item()
112 .expect_impl()
113 .of_trait
114 .unwrap()
115 .trait_ref
116 .path
117 .span;
118 let args =
119 &tcx.impl_trait_ref(item).instantiate_identity().skip_norm_wip().args[1..];
120 try_visit!(visitor.visit(span, args));
121 }
122 let span = match tcx.hir_node_by_def_id(item).ty() {
123 Some(ty) => ty.span,
124 _ => tcx.def_span(item),
125 };
126 try_visit!(
127 visitor.visit(span, tcx.type_of(item).instantiate_identity().skip_norm_wip())
128 );
129 for (clause, span) in tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
130 try_visit!(visitor.visit(span, clause.skip_norm_wip()));
131 }
132 }
133 DefKind::TraitAlias | DefKind::Trait => {
134 for (clause, span) in tcx.explicit_clauses_of(item).instantiate_identity(tcx) {
135 try_visit!(visitor.visit(span, clause.skip_norm_wip()));
136 }
137 }
138 DefKind::Variant
139 | DefKind::TyParam
140 | DefKind::ConstParam
141 | DefKind::Ctor(_, _)
142 | DefKind::Field
143 | DefKind::LifetimeParam => {
144 span_bug!(
145 tcx.def_span(item),
146 "{kind:?} has not seen any uses of `walk_types` yet, ping oli-obk if you'd like any help"
147 )
148 }
149 DefKind::ExternCrate
151 | DefKind::ForeignMod
152 | DefKind::ForeignTy
153 | DefKind::Macro(_)
154 | DefKind::GlobalAsm
155 | DefKind::Mod
156 | DefKind::Use => {}
157 }
158 V::Result::output()
159}