1use rustc_data_structures::fx::FxHashSet;
2use rustc_data_structures::unord::UnordSet;
3use rustc_hir::def_id::DefId;
4use rustc_span::Span;
5use smallvec::{SmallVec, smallvec};
6use tracing::{debug, instrument};
7
8use crate::ty::{self, Ty, TyCtxt};
9
10fn true_significant_drop_ty<'tcx>(
15 tcx: TyCtxt<'tcx>,
16 ty: Ty<'tcx>,
17) -> Option<SmallVec<[Ty<'tcx>; 2]>> {
18 if let ty::Adt(def, args) = ty.kind() {
19 let mut did = def.did();
20 let mut name_rev = ::alloc::vec::Vec::new()vec![];
21 loop {
22 let key = tcx.def_key(did);
23
24 match key.disambiguated_data.data {
25 rustc_hir::definitions::DefPathData::CrateRoot => {
26 name_rev.push(tcx.crate_name(did.krate));
27 }
28 rustc_hir::definitions::DefPathData::TypeNs(symbol) => {
29 name_rev.push(symbol);
30 }
31 _ => return None,
32 }
33 if let Some(parent) = key.parent {
34 did = DefId { krate: did.krate, index: parent };
35 } else {
36 break;
37 }
38 }
39 let name_str: Vec<_> = name_rev.iter().rev().map(|x| x.as_str()).collect();
40 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/significant_drop_order.rs:40",
"rustc_middle::ty::significant_drop_order",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/significant_drop_order.rs"),
::tracing_core::__macro_support::Option::Some(40u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::significant_drop_order"),
::tracing_core::field::FieldSet::new(&["name_str"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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(&name_str)
as &dyn Value))])
});
} else { ; }
};debug!(?name_str);
41 match name_str[..] {
42 ["syn" | "proc_macro2", ..]
44 | ["core" | "std", "task", "LocalWaker" | "Waker"]
45 | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(::smallvec::SmallVec::new()smallvec![]),
46 ["tracing", "instrument", "Instrumented"] | ["bytes", "Bytes"] => Some(::smallvec::SmallVec::new()smallvec![]),
48 ["hashbrown", "raw", "RawTable" | "RawIntoIter"] => {
49 if let [ty, ..] = &***args
50 && let Some(ty) = ty.as_type()
51 {
52 Some({
let count = 0usize + 1usize;
let mut vec = ::smallvec::SmallVec::new();
if count <= vec.inline_size() {
vec.push(ty);
vec
} else {
::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([ty])))
}
}smallvec![ty])
53 } else {
54 None
55 }
56 }
57 ["hashbrown", "raw", "RawDrain"] => {
58 if let [_, ty, ..] = &***args
59 && let Some(ty) = ty.as_type()
60 {
61 Some({
let count = 0usize + 1usize;
let mut vec = ::smallvec::SmallVec::new();
if count <= vec.inline_size() {
vec.push(ty);
vec
} else {
::smallvec::SmallVec::from_vec(<[_]>::into_vec(::alloc::boxed::box_new([ty])))
}
}smallvec![ty])
62 } else {
63 None
64 }
65 }
66 _ => None,
67 }
68 } else {
69 None
70 }
71}
72
73#[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("extract_component_raw",
"rustc_middle::ty::significant_drop_order",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/significant_drop_order.rs"),
::tracing_core::__macro_support::Option::Some(75u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::significant_drop_order"),
::tracing_core::field::FieldSet::new(&["ty", "ty_seen"],
::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(&ty)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty_seen)
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: SmallVec<[Ty<'tcx>; 4]> = loop {};
return __tracing_attr_fake_return;
}
{
let ty =
tcx.try_normalize_erasing_regions(typing_env,
ty).unwrap_or(ty);
let tys =
tcx.list_significant_drop_tys(typing_env.as_query_input(ty));
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/ty/significant_drop_order.rs:86",
"rustc_middle::ty::significant_drop_order",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/significant_drop_order.rs"),
::tracing_core::__macro_support::Option::Some(86u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::significant_drop_order"),
::tracing_core::field::FieldSet::new(&["message", "ty"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&format_args!("components")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&ty) as
&dyn Value))])
});
} else { ; }
};
let mut out_tys = ::smallvec::SmallVec::new();
for ty in tys {
if let Some(tys) = true_significant_drop_ty(tcx, ty) {
for ty in tys {
if ty_seen.insert(ty) {
out_tys.extend(extract_component_raw(tcx, typing_env, ty,
ty_seen));
}
}
} else { if ty_seen.insert(ty) { out_tys.push(ty); } }
}
out_tys
}
}
}#[instrument(level = "trace", skip(tcx, typing_env))]
76pub fn extract_component_raw<'tcx>(
77 tcx: TyCtxt<'tcx>,
78 typing_env: ty::TypingEnv<'tcx>,
79 ty: Ty<'tcx>,
80 ty_seen: &mut UnordSet<Ty<'tcx>>,
81) -> SmallVec<[Ty<'tcx>; 4]> {
82 let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
84
85 let tys = tcx.list_significant_drop_tys(typing_env.as_query_input(ty));
86 debug!(?ty, "components");
87 let mut out_tys = smallvec![];
88 for ty in tys {
89 if let Some(tys) = true_significant_drop_ty(tcx, ty) {
90 for ty in tys {
92 if ty_seen.insert(ty) {
93 out_tys.extend(extract_component_raw(tcx, typing_env, ty, ty_seen));
94 }
95 }
96 } else {
97 if ty_seen.insert(ty) {
98 out_tys.push(ty);
99 }
100 }
101 }
102 out_tys
103}
104
105#[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("extract_component_with_significant_dtor",
"rustc_middle::ty::significant_drop_order",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/significant_drop_order.rs"),
::tracing_core::__macro_support::Option::Some(105u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::significant_drop_order"),
::tracing_core::field::FieldSet::new(&["ty"],
::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(&ty)
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: SmallVec<[Ty<'tcx>; 4]> = loop {};
return __tracing_attr_fake_return;
}
{
let mut tys =
extract_component_raw(tcx, typing_env, ty,
&mut Default::default());
let mut deduplicate = FxHashSet::default();
tys.retain(|oty| deduplicate.insert(*oty));
tys.into_iter().collect()
}
}
}#[instrument(level = "trace", skip(tcx, typing_env))]
106pub fn extract_component_with_significant_dtor<'tcx>(
107 tcx: TyCtxt<'tcx>,
108 typing_env: ty::TypingEnv<'tcx>,
109 ty: Ty<'tcx>,
110) -> SmallVec<[Ty<'tcx>; 4]> {
111 let mut tys = extract_component_raw(tcx, typing_env, ty, &mut Default::default());
112 let mut deduplicate = FxHashSet::default();
113 tys.retain(|oty| deduplicate.insert(*oty));
114 tys.into_iter().collect()
115}
116
117#[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("ty_dtor_span",
"rustc_middle::ty::significant_drop_order",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/ty/significant_drop_order.rs"),
::tracing_core::__macro_support::Option::Some(120u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::ty::significant_drop_order"),
::tracing_core::field::FieldSet::new(&["ty"],
::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(&ty)
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: Option<Span> = loop {};
return __tracing_attr_fake_return;
}
{
match ty.kind() {
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_)
| ty::Error(_) | ty::Str | ty::Never | ty::RawPtr(_, _) |
ty::Ref(_, _, _) | ty::FnPtr(_, _) | ty::Tuple(_) |
ty::Dynamic(_, _) | ty::Alias(_, _) | ty::Bound(_, _) |
ty::Pat(_, _) | ty::Placeholder(_) | ty::Infer(_) |
ty::Slice(_) | ty::Array(_, _) | ty::UnsafeBinder(_) =>
None,
ty::Adt(adt_def, _) => {
if let Some(dtor) = tcx.adt_destructor(adt_def.did()) {
Some(tcx.def_span(tcx.parent(dtor.did)))
} else { Some(tcx.def_span(adt_def.did())) }
}
ty::Coroutine(did, _) | ty::CoroutineWitness(did, _) |
ty::CoroutineClosure(did, _) | ty::Closure(did, _) |
ty::FnDef(did, _) | ty::Foreign(did) =>
Some(tcx.def_span(did)),
ty::Param(_) => None,
}
}
}
}#[instrument(level = "trace", skip(tcx))]
121pub fn ty_dtor_span<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Span> {
122 match ty.kind() {
123 ty::Bool
124 | ty::Char
125 | ty::Int(_)
126 | ty::Uint(_)
127 | ty::Float(_)
128 | ty::Error(_)
129 | ty::Str
130 | ty::Never
131 | ty::RawPtr(_, _)
132 | ty::Ref(_, _, _)
133 | ty::FnPtr(_, _)
134 | ty::Tuple(_)
135 | ty::Dynamic(_, _)
136 | ty::Alias(_, _)
137 | ty::Bound(_, _)
138 | ty::Pat(_, _)
139 | ty::Placeholder(_)
140 | ty::Infer(_)
141 | ty::Slice(_)
142 | ty::Array(_, _)
143 | ty::UnsafeBinder(_) => None,
144
145 ty::Adt(adt_def, _) => {
146 if let Some(dtor) = tcx.adt_destructor(adt_def.did()) {
147 Some(tcx.def_span(tcx.parent(dtor.did)))
148 } else {
149 Some(tcx.def_span(adt_def.did()))
150 }
151 }
152 ty::Coroutine(did, _)
153 | ty::CoroutineWitness(did, _)
154 | ty::CoroutineClosure(did, _)
155 | ty::Closure(did, _)
156 | ty::FnDef(did, _)
157 | ty::Foreign(did) => Some(tcx.def_span(did)),
158 ty::Param(_) => None,
159 }
160}