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::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
9use rustc_middle::{bug, span_bug};
10use rustc_span::Span;
11use tracing::{instrument, trace};
12
13use crate::errors::{DuplicateArg, NotParam};
14
15struct OpaqueTypeCollector<'tcx> {
16 tcx: TyCtxt<'tcx>,
17 opaques: Vec<LocalDefId>,
18 item: LocalDefId,
20
21 seen: FxHashSet<LocalDefId>,
23
24 span: Option<Span>,
25
26 mode: CollectionMode,
27}
28
29enum CollectionMode {
30 ImplTraitInAssocTypes,
33 Taits,
35 RpitAndAsyncFnOnly,
38}
39
40impl<'tcx> OpaqueTypeCollector<'tcx> {
41 fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
42 let mode = match tcx.def_kind(item) {
43 DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy => {
44 CollectionMode::ImplTraitInAssocTypes
45 }
46 DefKind::TyAlias => CollectionMode::Taits,
47 _ => CollectionMode::RpitAndAsyncFnOnly,
48 };
49 Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None, mode }
50 }
51
52 fn span(&self) -> Span {
53 self.span.unwrap_or_else(|| {
54 self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item))
55 })
56 }
57
58 fn visit_spanned(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
59 let old = self.span;
60 self.span = Some(span);
61 value.visit_with(self);
62 self.span = old;
63 }
64
65 #[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(65u32),
::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(75u32),
::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(83u32),
::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))]
66 fn collect_taits_declared_in_body(&mut self) {
67 let Some(body) = self.tcx.hir_maybe_body_owned_by(self.item) else {
68 return;
69 };
70 let body = body.value;
71 struct TaitInBodyFinder<'a, 'tcx> {
72 collector: &'a mut OpaqueTypeCollector<'tcx>,
73 }
74 impl<'v> intravisit::Visitor<'v> for TaitInBodyFinder<'_, '_> {
75 #[instrument(level = "trace", skip(self))]
76 fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
77 let id = id.owner_id.def_id;
78 if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
79 let items = self.collector.tcx.opaque_types_defined_by(id);
80 self.collector.opaques.extend(items);
81 }
82 }
83 #[instrument(level = "trace", skip(self))]
84 fn visit_nested_body(&mut self, id: rustc_hir::BodyId) {
86 let body = self.collector.tcx.hir_body(id);
87 self.visit_body(body);
88 }
89 }
90 TaitInBodyFinder { collector: self }.visit_expr(body);
91 }
92
93 #[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(93u32),
::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;
}
{
if !self.seen.insert(alias_ty.def_id.expect_local()) { return; }
match self.tcx.local_opaque_ty_origin(alias_ty.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:124",
"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(124u32),
::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(alias_ty.def_id.expect_local());
let parent_count =
self.tcx.generics_of(alias_ty.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(alias_ty.def_id).iter_identity_copied()
{
{
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:146",
"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(146u32),
::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(alias_ty.def_id),
});
}
Err(NotUniqueParam::DuplicateParam(arg)) => {
self.tcx.dcx().emit_err(DuplicateArg {
arg,
span: self.span(),
opaque_span: self.tcx.def_span(alias_ty.def_id),
});
}
}
}
}
}#[instrument(level = "debug", skip(self))]
94 fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
95 if !self.seen.insert(alias_ty.def_id.expect_local()) {
96 return;
97 }
98
99 match self.tcx.local_opaque_ty_origin(alias_ty.def_id.expect_local()) {
101 rustc_hir::OpaqueTyOrigin::FnReturn { .. }
102 | rustc_hir::OpaqueTyOrigin::AsyncFn { .. } => {}
103 rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => match self.mode {
104 CollectionMode::ImplTraitInAssocTypes => {
108 if !in_assoc_ty {
109 return;
110 }
111 }
112 CollectionMode::Taits => {
116 if in_assoc_ty {
117 return;
118 }
119 }
120 CollectionMode::RpitAndAsyncFnOnly => return,
121 },
122 }
123
124 trace!(?alias_ty, "adding");
125 self.opaques.push(alias_ty.def_id.expect_local());
126
127 let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
128 match self
132 .tcx
133 .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::FromFunction)
134 {
135 Ok(()) => {
136 for (pred, span) in
144 self.tcx.explicit_item_bounds(alias_ty.def_id).iter_identity_copied()
145 {
146 trace!(?pred);
147 self.visit_spanned(span, pred);
148 }
149 }
150 Err(NotUniqueParam::NotParam(arg)) => {
151 self.tcx.dcx().emit_err(NotParam {
152 arg,
153 span: self.span(),
154 opaque_span: self.tcx.def_span(alias_ty.def_id),
155 });
156 }
157 Err(NotUniqueParam::DuplicateParam(arg)) => {
158 self.tcx.dcx().emit_err(DuplicateArg {
159 arg,
160 span: self.span(),
161 opaque_span: self.tcx.def_span(alias_ty.def_id),
162 });
163 }
164 }
165 }
166
167 #[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(169u32),
::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:179",
"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(179u32),
::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))]
170 fn collect_taits_from_defines_attr(&mut self) {
171 let hir_id = self.tcx.local_def_id_to_hir_id(self.item);
172 if !hir_id.is_owner() {
173 return;
174 }
175 let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else {
176 return;
177 };
178 for &(span, define) in defines {
179 trace!(?define);
180 let mode = std::mem::replace(&mut self.mode, CollectionMode::Taits);
181 let n = self.opaques.len();
182 super::sig_types::walk_types(self.tcx, define, self);
183 if n == self.opaques.len() {
184 self.tcx.dcx().span_err(span, "item does not contain any opaque types");
185 }
186 self.mode = mode;
187 }
188 self.mode = CollectionMode::RpitAndAsyncFnOnly;
191 }
192}
193
194impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
195 x;#[instrument(skip(self), ret, level = "trace")]
196 fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
197 self.visit_spanned(span, value);
198 }
199}
200
201impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
202 x;#[instrument(skip(self), ret, level = "trace")]
203 fn visit_ty(&mut self, t: Ty<'tcx>) {
204 t.super_visit_with(self);
205 match *t.kind() {
206 ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
207 self.visit_opaque_ty(alias_ty);
208 }
209 ty::Alias(ty::Free, alias_ty) if let Some(def_id) = alias_ty.def_id.as_local() => {
212 if !self.seen.insert(def_id) {
213 return;
214 }
215 self.tcx
216 .type_of(alias_ty.def_id)
217 .instantiate(self.tcx, alias_ty.args)
218 .visit_with(self);
219 }
220 ty::Alias(ty::Projection, alias_ty) => {
221 if let Some(parent) = self.tcx.trait_impl_of_assoc(self.item.to_def_id()) {
225 let impl_trait_ref = self.tcx.impl_trait_ref(parent).instantiate_identity();
226 if alias_ty.trait_ref(self.tcx) == impl_trait_ref {
230 for &assoc in self.tcx.associated_items(parent).in_definition_order() {
231 trace!(?assoc);
232 if assoc.expect_trait_impl() != Ok(alias_ty.def_id) {
233 continue;
234 }
235
236 if !assoc.defaultness(self.tcx).is_final() {
239 continue;
240 }
241
242 if !self.seen.insert(assoc.def_id.expect_local()) {
243 return;
244 }
245
246 let alias_args = alias_ty.args.rebase_onto(
247 self.tcx,
248 impl_trait_ref.def_id,
249 ty::GenericArgs::identity_for_item(self.tcx, parent),
250 );
251
252 if self.tcx.check_args_compatible(assoc.def_id, alias_args) {
253 self.tcx
254 .type_of(assoc.def_id)
255 .instantiate(self.tcx, alias_args)
256 .visit_with(self);
257 return;
258 } else {
259 self.tcx.dcx().span_delayed_bug(
260 self.tcx.def_span(assoc.def_id),
261 "item had incorrect args",
262 );
263 }
264 }
265 }
266 } else if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
267 self.tcx.opt_rpitit_info(alias_ty.def_id)
268 && fn_def_id == self.item.into()
269 {
270 let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
282 let ty::Alias(ty::Opaque, alias_ty) = *ty.kind() else { bug!("{ty:?}") };
283 self.visit_opaque_ty(alias_ty);
284 }
285 }
286 _ => trace!(kind=?t.kind()),
287 }
288 }
289}
290
291fn opaque_types_defined_by<'tcx>(
292 tcx: TyCtxt<'tcx>,
293 item: LocalDefId,
294) -> &'tcx ty::List<LocalDefId> {
295 let kind = tcx.def_kind(item);
296 {
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:296",
"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(296u32),
::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);
297 let mut collector = OpaqueTypeCollector::new(tcx, item);
298 collector.collect_taits_from_defines_attr();
299 super::sig_types::walk_types(tcx, item, &mut collector);
300
301 match kind {
302 DefKind::AssocFn
303 | DefKind::Fn
304 | DefKind::Static { .. }
305 | DefKind::Const
306 | DefKind::AssocConst
307 | DefKind::AnonConst => {
308 collector.collect_taits_declared_in_body();
309 }
310 DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => {
315 collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
316 }
317 DefKind::AssocTy | DefKind::TyAlias | DefKind::GlobalAsm => {}
318 DefKind::OpaqueTy
319 | DefKind::Mod
320 | DefKind::Struct
321 | DefKind::Union
322 | DefKind::Enum
323 | DefKind::Variant
324 | DefKind::Trait
325 | DefKind::ForeignTy
326 | DefKind::TraitAlias
327 | DefKind::TyParam
328 | DefKind::ConstParam
329 | DefKind::Ctor(_, _)
330 | DefKind::Macro(_)
331 | DefKind::ExternCrate
332 | DefKind::Use
333 | DefKind::ForeignMod
334 | DefKind::Field
335 | DefKind::LifetimeParam
336 | DefKind::Impl { .. } => {
337 ::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!(
338 tcx.def_span(item),
339 "`opaque_types_defined_by` not defined for {} `{item:?}`",
340 kind.descr(item.to_def_id())
341 );
342 }
343 }
344 tcx.mk_local_def_ids(&collector.opaques)
345}
346
347pub(super) fn provide(providers: &mut Providers) {
348 *providers = Providers { opaque_types_defined_by, ..*providers };
349}