1use rustc_data_structures::fx::FxHashSet;
2use rustc_hir::def::DefKind;
3use rustc_hir::def_id::LocalDefId;
4use rustc_hir::intravisit;
5use rustc_hir::intravisit::Visitor;
6use rustc_middle::query::Providers;
7use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
8use rustc_middle::ty::{
9 self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Unnormalized,
10};
11use rustc_middle::{bug, span_bug};
12use rustc_span::Span;
13use tracing::{instrument, trace};
14
15use crate::errors::{DuplicateArg, NotParam};
16
17struct OpaqueTypeCollector<'tcx> {
18 tcx: TyCtxt<'tcx>,
19 opaques: Vec<LocalDefId>,
20 item: LocalDefId,
22
23 seen: FxHashSet<LocalDefId>,
25
26 span: Option<Span>,
27
28 mode: CollectionMode,
29}
30
31enum CollectionMode {
32 ImplTraitInAssocTypes,
35 Taits,
37 RpitAndAsyncFnOnly,
40}
41
42impl<'tcx> OpaqueTypeCollector<'tcx> {
43 fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
44 let mode = match tcx.def_kind(item) {
45 DefKind::AssocConst { .. } | DefKind::AssocFn | DefKind::AssocTy => {
46 CollectionMode::ImplTraitInAssocTypes
47 }
48 DefKind::TyAlias => CollectionMode::Taits,
49 _ => CollectionMode::RpitAndAsyncFnOnly,
50 };
51 Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
52 }
53
54 fn span(&self) -> Span {
55 self.span.unwrap_or_else(|| {
56 self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item))
57 })
58 }
59
60 fn visit_spanned(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
61 let old = self.span;
62 self.span = Some(span);
63 value.visit_with(self);
64 self.span = old;
65 }
66
67 #[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("collect_taits_declared_in_body",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(67u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&[],
::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,
&{ meta.fields().value_set(&[]) })
} 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: () = loop {};
return __tracing_attr_fake_return;
}
{
let Some(body) =
self.tcx.hir_maybe_body_owned_by(self.item) else { return; };
let body = body.value;
struct TaitInBodyFinder<'a, 'tcx> {
collector: &'a mut OpaqueTypeCollector<'tcx>,
}
impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> {
fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
{}
#[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("visit_nested_item",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(77u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["id"],
::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(&id)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
let id = id.owner_id.def_id;
if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
let items = self.collector.tcx.opaque_types_defined_by(id);
self.collector.opaques.extend(items);
}
}
}
}
}
fn visit_nested_body(&mut self, id: rustc_hir::BodyId) {
{}
#[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("visit_nested_body",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(85u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["id"],
::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(&id)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
let body = self.collector.tcx.hir_body(id);
self.visit_body(body);
}
}
}
}
}
TaitInBodyFinder { collector: self }.visit_expr(body);
}
}
}#[instrument(level = "trace", skip(self))]
68 fn collect_taits_declared_in_body(&mut self) {
69 let Some(body) = self.tcx.hir_maybe_body_owned_by(self.item) else {
70 return;
71 };
72 let body = body.value;
73 struct TaitInBodyFinder<'a, 'tcx> {
74 collector: &'a mut OpaqueTypeCollector<'tcx>,
75 }
76 impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> {
77 #[instrument(level = "trace", skip(self))]
78 fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
79 let id = id.owner_id.def_id;
80 if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
81 let items = self.collector.tcx.opaque_types_defined_by(id);
82 self.collector.opaques.extend(items);
83 }
84 }
85 #[instrument(level = "trace", skip(self))]
86 fn visit_nested_body(&mut self, id: rustc_hir::BodyId) {
88 let body = self.collector.tcx.hir_body(id);
89 self.visit_body(body);
90 }
91 }
92 TaitInBodyFinder { collector: self }.visit_expr(body);
93 }
94
95 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::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("visit_opaque_ty",
"rustc_ty_utils::opaque_types", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(95u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["alias_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::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::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(&alias_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: () = loop {};
return __tracing_attr_fake_return;
}
{
let ty::Opaque { def_id } =
alias_ty.kind else {
::rustc_middle::util::bug::bug_fmt(format_args!("{0:?}",
alias_ty))
};
if !self.seen.insert(def_id.expect_local()) { return; }
match self.tcx.local_opaque_ty_origin(def_id.expect_local()) {
rustc_hir::OpaqueTyOrigin::FnReturn { .. } |
rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } =>
match self.mode {
CollectionMode::ImplTraitInAssocTypes => {
if !in_assoc_ty { return; }
}
CollectionMode::Taits => { if in_assoc_ty { return; } }
CollectionMode::RpitAndAsyncFnOnly => return,
},
}
{
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/opaque_types.rs:128",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(128u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["message",
"alias_ty"],
::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(&format_args!("adding")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&alias_ty)
as &dyn Value))])
});
} else { ; }
};
self.opaques.push(def_id.expect_local());
let parent_count = self.tcx.generics_of(def_id).parent_count;
match self.tcx.uses_unique_generic_params(&alias_ty.args[..parent_count],
CheckRegions::FromFunction) {
Ok(()) => {
for (pred, span) in
self.tcx.explicit_item_bounds(def_id).iter_identity_copied().map(Unnormalized::skip_norm_wip)
{
{
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/opaque_types.rs:153",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(153u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["pred"],
::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(&pred) as
&dyn Value))])
});
} else { ; }
};
self.visit_spanned(span, pred);
}
}
Err(NotUniqueParam::NotParam(arg)) => {
self.tcx.dcx().emit_err(NotParam {
arg,
span: self.span(),
opaque_span: self.tcx.def_span(def_id),
});
}
Err(NotUniqueParam::DuplicateParam(arg)) => {
self.tcx.dcx().emit_err(DuplicateArg {
arg,
span: self.span(),
opaque_span: self.tcx.def_span(def_id),
});
}
}
}
}
}#[instrument(level = "debug", skip(self))]
96 fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
97 let ty::Opaque { def_id } = alias_ty.kind else { bug!("{alias_ty:?}") };
98
99 if !self.seen.insert(def_id.expect_local()) {
100 return;
101 }
102
103 match self.tcx.local_opaque_ty_origin(def_id.expect_local()) {
105 rustc_hir::OpaqueTyOrigin::FnReturn { .. }
106 | rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
107 rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => match self.mode {
108 CollectionMode::ImplTraitInAssocTypes => {
112 if !in_assoc_ty {
113 return;
114 }
115 }
116 CollectionMode::Taits => {
120 if in_assoc_ty {
121 return;
122 }
123 }
124 CollectionMode::RpitAndAsyncFnOnly => return,
125 },
126 }
127
128 trace!(?alias_ty, "adding");
129 self.opaques.push(def_id.expect_local());
130
131 let parent_count = self.tcx.generics_of(def_id).parent_count;
132 match self
136 .tcx
137 .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::FromFunction)
138 {
139 Ok(()) => {
140 for (pred, span) in self
148 .tcx
149 .explicit_item_bounds(def_id)
150 .iter_identity_copied()
151 .map(Unnormalized::skip_norm_wip)
152 {
153 trace!(?pred);
154 self.visit_spanned(span, pred);
155 }
156 }
157 Err(NotUniqueParam::NotParam(arg)) => {
158 self.tcx.dcx().emit_err(NotParam {
159 arg,
160 span: self.span(),
161 opaque_span: self.tcx.def_span(def_id),
162 });
163 }
164 Err(NotUniqueParam::DuplicateParam(arg)) => {
165 self.tcx.dcx().emit_err(DuplicateArg {
166 arg,
167 span: self.span(),
168 opaque_span: self.tcx.def_span(def_id),
169 });
170 }
171 }
172 }
173
174 #[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("collect_taits_from_defines_attr",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(176u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&[],
::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,
&{ meta.fields().value_set(&[]) })
} 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: () = loop {};
return __tracing_attr_fake_return;
}
{
let hir_id = self.tcx.local_def_id_to_hir_id(self.item);
if !hir_id.is_owner() { return; }
let Some(defines) =
self.tcx.hir_attr_map(hir_id.owner).define_opaque else {
return;
};
for &(span, define) in defines {
{
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/opaque_types.rs:186",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(186u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_types"),
::tracing_core::field::FieldSet::new(&["define"],
::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(&define) as
&dyn Value))])
});
} else { ; }
};
let mode =
std::mem::replace(&mut self.mode, CollectionMode::Taits);
let n = self.opaques.len();
super::sig_types::walk_types(self.tcx, define, self);
if n == self.opaques.len() {
self.tcx.dcx().span_err(span,
"item does not contain any opaque types");
}
self.mode = mode;
}
self.mode = CollectionMode::RpitAndAsyncFnOnly;
}
}
}#[instrument(level = "trace", skip(self))]
177 fn collect_taits_from_defines_attr(&mut self) {
178 let hir_id = self.tcx.local_def_id_to_hir_id(self.item);
179 if !hir_id.is_owner() {
180 return;
181 }
182 let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else {
183 return;
184 };
185 for &(span, define) in defines {
186 trace!(?define);
187 let mode = std::mem::replace(&mut self.mode, CollectionMode::Taits);
188 let n = self.opaques.len();
189 super::sig_types::walk_types(self.tcx, define, self);
190 if n == self.opaques.len() {
191 self.tcx.dcx().span_err(span, "item does not contain any opaque types");
192 }
193 self.mode = mode;
194 }
195 self.mode = CollectionMode::RpitAndAsyncFnOnly;
198 }
199}
200
201impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
202 x;#[instrument(skip(self), ret, level = "trace")]
203 fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
204 self.visit_spanned(span, value);
205 }
206}
207
208impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
209 x;#[instrument(skip(self), ret, level = "trace")]
210 fn visit_ty(&mut self, t: Ty<'tcx>) {
211 t.super_visit_with(self);
212 match *t.kind() {
213 ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { def_id }, .. })
214 if def_id.is_local() =>
215 {
216 self.visit_opaque_ty(alias_ty);
217 }
218 ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. })
221 if let Some(def_id) = def_id.as_local() =>
222 {
223 if !self.seen.insert(def_id) {
224 return;
225 }
226 self.tcx
227 .type_of(def_id)
228 .instantiate(self.tcx, args)
229 .skip_norm_wip()
230 .visit_with(self);
231 }
232 ty::Alias(
233 alias_ty @ ty::AliasTy { kind: ty::Projection { def_id: alias_def_id }, .. },
234 ) => {
235 if let Some(parent) = self.tcx.trait_impl_of_assoc(self.item.to_def_id()) {
239 let impl_trait_ref =
240 self.tcx.impl_trait_ref(parent).instantiate_identity().skip_norm_wip();
241 if alias_ty.trait_ref(self.tcx) == impl_trait_ref {
245 for &assoc in self.tcx.associated_items(parent).in_definition_order() {
246 trace!(?assoc);
247 if assoc.expect_trait_impl() != Ok(alias_def_id) {
248 continue;
249 }
250
251 if !assoc.defaultness(self.tcx).is_final() {
254 continue;
255 }
256
257 if !self.seen.insert(assoc.def_id.expect_local()) {
258 return;
259 }
260
261 let alias_args = alias_ty.args.rebase_onto(
262 self.tcx,
263 impl_trait_ref.def_id,
264 ty::GenericArgs::identity_for_item(self.tcx, parent),
265 );
266
267 if self.tcx.check_args_compatible(assoc.def_id, alias_args) {
268 self.tcx
269 .type_of(assoc.def_id)
270 .instantiate(self.tcx, alias_args)
271 .skip_norm_wip()
272 .visit_with(self);
273 return;
274 } else {
275 self.tcx.dcx().span_delayed_bug(
276 self.tcx.def_span(assoc.def_id),
277 "item had incorrect args",
278 );
279 }
280 }
281 }
282 } else if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
283 self.tcx.opt_rpitit_info(alias_def_id)
284 && fn_def_id == self.item.into()
285 {
286 let ty = self
298 .tcx
299 .type_of(alias_def_id)
300 .instantiate(self.tcx, alias_ty.args)
301 .skip_norm_wip();
302 let ty::Alias(alias_ty @ ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
303 *ty.kind()
304 else {
305 bug!("{ty:?}")
306 };
307 self.visit_opaque_ty(alias_ty);
308 }
309 }
310 _ => trace!(kind=?t.kind()),
311 }
312 }
313}
314
315fn opaque_types_defined_by<'tcx>(
316 tcx: TyCtxt<'tcx>,
317 item: LocalDefId,
318) -> &'tcx ty::List<LocalDefId> {
319 let kind = tcx.def_kind(item);
320 {
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/opaque_types.rs:320",
"rustc_ty_utils::opaque_types", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_ty_utils/src/opaque_types.rs"),
::tracing_core::__macro_support::Option::Some(320u32),
::tracing_core::__macro_support::Option::Some("rustc_ty_utils::opaque_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 { ; }
};trace!(?kind);
321 let mut collector = OpaqueTypeCollector::new(tcx, item);
322 collector.collect_taits_from_defines_attr();
323 super::sig_types::walk_types(tcx, item, &mut collector);
324
325 match kind {
326 DefKind::AssocFn
327 | DefKind::Fn
328 | DefKind::Static { .. }
329 | DefKind::Const { .. }
330 | DefKind::AssocConst { .. }
331 | DefKind::AnonConst => {
332 collector.collect_taits_declared_in_body();
333 }
334 DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => {
339 collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
340 }
341 DefKind::AssocTy | DefKind::TyAlias | DefKind::GlobalAsm => {}
342 DefKind::OpaqueTy
343 | DefKind::Mod
344 | DefKind::Struct
345 | DefKind::Union
346 | DefKind::Enum
347 | DefKind::Variant
348 | DefKind::Trait
349 | DefKind::ForeignTy
350 | DefKind::TraitAlias
351 | DefKind::TyParam
352 | DefKind::ConstParam
353 | DefKind::Ctor(_, _)
354 | DefKind::Macro(_)
355 | DefKind::ExternCrate
356 | DefKind::Use
357 | DefKind::ForeignMod
358 | DefKind::Field
359 | DefKind::LifetimeParam
360 | DefKind::Impl { .. } => {
361 ::rustc_middle::util::bug::span_bug_fmt(tcx.def_span(item),
format_args!("`opaque_types_defined_by` not defined for {0} `{1:?}`",
kind.descr(item.to_def_id()), item));span_bug!(
362 tcx.def_span(item),
363 "`opaque_types_defined_by` not defined for {} `{item:?}`",
364 kind.descr(item.to_def_id())
365 );
366 }
367 }
368 tcx.mk_local_def_ids(&collector.opaques)
369}
370
371pub(super) fn provide(providers: &mut Providers) {
372 *providers = Providers { opaque_types_defined_by, ..*providers };
373}