1use rustc_data_structures::fx::FxIndexSet;
2use rustc_hir::def::DefKind;
3use rustc_hir::def_id::{DefId, LocalDefId};
4use rustc_index::bit_set::DenseBitSet;
5use rustc_middle::bug;
6use rustc_middle::ty::{
7self, Flags, ImplTraitInTraitData, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
8TypeVisitableExt, TypeVisitor,
9};
1011use crate::infer::outlives::test_type_match;
12use crate::infer::region_constraints::VerifyIfEq;
13use crate::regions::{region_known_to_outlive, ty_known_to_outlive};
1415/// For a given alias type, this returns the set of indices into the identity generic args that
16/// are relevant for liveness, that can be inferred from outlives bounds on the
17/// alias itself, and the explicit and implicit outlives clauses of the alias.
18/// Callers should use the indices with the concrete args of the alias.
19///
20/// There are three cases to consider:
21/// 1. If there are *no* outlives bounds, then all args are potentially live.
22/// 2. If there is a `'static` outlives bound, then we know that all args are
23/// irrelevant, so we return an empty set.
24/// 3. If there are *any* outlives bounds, then we find any args that are known
25/// to outlive those bounds, since those are the args whose regions the
26/// underlying type could capture.
27{}
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("live_args_for_alias_from_outlives_bounds",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(27u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&kind)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[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: DenseBitSet<u32> = loop {};
return __tracing_attr_fake_return;
}
{
let def_id =
match kind {
ty::AliasTyKind::Projection { def_id } |
ty::AliasTyKind::Inherent { def_id } |
ty::AliasTyKind::Opaque { def_id } | ty::AliasTyKind::Free {
def_id } => def_id,
};
let self_identity_args =
ty::GenericArgs::identity_for_item(tcx, def_id);
let bounds =
tcx.item_bounds(def_id).instantiate_identity().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 /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:42",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(42u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("bounds")
}> =
::tracing::__macro_support::FieldName::new("bounds");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&bounds)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let alias_ty =
Ty::new_alias(tcx, ty::IsRigid::No,
ty::AliasTy::new_from_args(tcx, kind, self_identity_args));
let outlives_regions: Vec<_> =
bounds.iter().filter_map(|clause|
{
let outlives = clause.as_type_outlives_clause()?;
if let Some(outlives) = outlives.no_bound_vars() &&
outlives.0 == alias_ty {
Some(outlives.1)
} else {
test_type_match::extract_verify_if_eq(tcx,
&outlives.map_bound(|ty::OutlivesClause(ty, bound)|
VerifyIfEq { ty, bound }), alias_ty)
}
}).collect();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:69",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(69u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("outlives_regions")
}> =
::tracing::__macro_support::FieldName::new("outlives_regions");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&outlives_regions)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
if outlives_regions.is_empty() {
return DenseBitSet::new_filled(self_identity_args.len());
}
if outlives_regions.contains(&tcx.lifetimes.re_static) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:91",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(91u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("alias has a \'static outlives bound, so skipping visiting any regions")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
return DenseBitSet::new_empty(self_identity_args.len());
}
let args_known_to_outlive =
tcx.args_known_to_outlive_alias_params(def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:101",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(101u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("args_known_to_outlive")
}> =
::tracing::__macro_support::FieldName::new("args_known_to_outlive");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&args_known_to_outlive)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let mut live_args =
DenseBitSet::new_filled(self_identity_args.len());
for outlives_region in outlives_regions {
let Some(outlives_params) =
args_known_to_outlive.iter().find(|(idx, _)|
self_identity_args[*idx].as_region() ==
Some(outlives_region)) else { continue; };
live_args.intersect(&outlives_params.1);
}
live_args
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:27",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(27u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[tracing::instrument(level = "debug", skip(tcx), ret)]28pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>(
29 tcx: TyCtxt<'tcx>,
30 kind: ty::AliasTyKind<'tcx>,
31) -> DenseBitSet<u32> {
32let def_id = match kind {
33 ty::AliasTyKind::Projection { def_id }
34 | ty::AliasTyKind::Inherent { def_id }
35 | ty::AliasTyKind::Opaque { def_id }
36 | ty::AliasTyKind::Free { def_id } => def_id,
37 };
38let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
3940// We first want to collect the outlives bounds of the alias.
41let bounds = tcx.item_bounds(def_id).instantiate_identity().skip_norm_wip();
42tracing::debug!(?bounds);
43let alias_ty = Ty::new_alias(
44 tcx,
45 ty::IsRigid::No,
46 ty::AliasTy::new_from_args(tcx, kind, self_identity_args),
47 );
48let outlives_regions: Vec<_> = bounds
49 .iter()
50 .filter_map(|clause| {
51let outlives = clause.as_type_outlives_clause()?;
52if let Some(outlives) = outlives.no_bound_vars()
53 && outlives.0 == alias_ty
54 {
55Some(outlives.1)
56 } else {
57 test_type_match::extract_verify_if_eq(
58 tcx,
59&outlives.map_bound(|ty::OutlivesClause(ty, bound)| VerifyIfEq { ty, bound }),
60// FIXME(#155345): Region handling should generally only
61 // deal with rigid aliases, making sure we do so correctly
62 // everywhere is effort, so we're just using `No` everywhere
63 // for now. This should change soon.
64alias_ty,
65 )
66 }
67 })
68 .collect();
69tracing::debug!(?outlives_regions);
7071// If there are no outlives bounds, then all (non-bivariant) args are potentially live.
72if outlives_regions.is_empty() {
73return DenseBitSet::new_filled(self_identity_args.len());
74 }
7576// If any of the outlives bounds are `'static`, then we know the alias
77 // doesn't capture *any* regions, so we can skip visiting any regions at all.
78 //
79 // I was originally a bit concerned about something like `'a: 'static`, and
80 // whether or not we need to mark `'a` as live. I don't think that we do.
81 //
82 // To dig in a bit: Think about the function using this alias. For the alias
83 // to be well-formed, then it must be proven that the arg (`'a` in this case)
84 // outlives `'static`. Well, if that is proven *once*, then it must be true
85 // across the entire function (because `'static` is free).
86 //
87 // I think this similarly applies to any other free region, like `'a: 'b`
88 // where `'b` is *also* free. Though, we of course can't know *here* which
89 // regions are going to be instantiated with free regions.
90if outlives_regions.contains(&tcx.lifetimes.re_static) {
91tracing::debug!("alias has a 'static outlives bound, so skipping visiting any regions");
92return DenseBitSet::new_empty(self_identity_args.len());
93 }
9495// Okay, so we know we have some outlives bounds, and that none of them are `'static`.
96 // Now, we need to find all other potentially-live args, those that outlive
97 // an outlives-bound region. `args_known_to_outlive_alias_params` does this
98 // for us, and in the case of opaques only includes *captured* regions, too.
99100let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(def_id);
101tracing::debug!(?args_known_to_outlive);
102let mut live_args = DenseBitSet::new_filled(self_identity_args.len());
103for outlives_region in outlives_regions {
104let Some(outlives_params) = args_known_to_outlive
105 .iter()
106 .find(|(idx, _)| self_identity_args[*idx].as_region() == Some(outlives_region))
107else {
108continue;
109 };
110 live_args.intersect(&outlives_params.1);
111 }
112 live_args
113}
114115/// For each region param of this alias compute the indices of the identity args
116/// that are known to outlive it, given only the alias's declared where-clauses.
117///
118/// Note: for opaques (including synthetic associated types from RPITITs),
119/// the outlives relationships are identified in the context of the *parent*,
120/// since bounds and well-formed types are not lowered.
121{}
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("args_known_to_outlive_alias_params",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(121u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[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:
Vec<(usize, DenseBitSet<u32>)> = loop {};
return __tracing_attr_fake_return;
}
{
match tcx.def_kind(def_id) {
DefKind::OpaqueTy =>
args_known_to_outlive_opaque_params(tcx, def_id),
DefKind::AssocTy if
let Some(ImplTraitInTraitData::Trait {
fn_def_id: _, opaque_def_id }) =
tcx.opt_rpitit_info(def_id.to_def_id()) => {
args_known_to_outlive_opaque_params(tcx,
opaque_def_id.expect_local())
}
DefKind::AssocTy | DefKind::TyAlias =>
args_known_to_outlive_non_opaque_params(tcx, def_id),
kind => {
::rustc_middle::util::bug::bug_fmt(format_args!("improper def_kind {0:?} passed to `live_args_for_alias_from_outlives_bounds`",
kind))
}
}
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:121",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(121u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[tracing::instrument(level = "debug", skip(tcx), ret)]122pub(crate) fn args_known_to_outlive_alias_params<'tcx>(
123 tcx: TyCtxt<'tcx>,
124 def_id: LocalDefId,
125) -> Vec<(usize, DenseBitSet<u32>)> {
126match tcx.def_kind(def_id) {
127 DefKind::OpaqueTy => args_known_to_outlive_opaque_params(tcx, def_id),
128 DefKind::AssocTy
129if let Some(ImplTraitInTraitData::Trait { fn_def_id: _, opaque_def_id }) =
130 tcx.opt_rpitit_info(def_id.to_def_id()) =>
131 {
132 args_known_to_outlive_opaque_params(tcx, opaque_def_id.expect_local())
133 }
134 DefKind::AssocTy | DefKind::TyAlias => args_known_to_outlive_non_opaque_params(tcx, def_id),
135 kind => {
136bug!("improper def_kind {kind:?} passed to `live_args_for_alias_from_outlives_bounds`")
137 }
138 }
139}
140141/// For each *captured* region of this alias, compute the *captured* identity
142/// args that are known to outlive it, given the definition of the opaque type
143/// in the the *parent* context.
144///
145/// Some examples:
146/// ```ignore (illustrative)
147/// // Returns `[('a, ['a]), ('b, ['b])]`
148/// fn foo<'a, 'b>() -> impl Sized + use<'a, 'b> {}
149///
150/// // Returns `[('a, ['a]), ('b, ['b])]`
151/// fn foo<'a: 'a, 'b>() -> impl Sized + use<'a, 'b> {}
152///
153/// // Returns `[('a, ['a])]`
154/// fn foo<'a, 'b>() -> impl Sized + use<'a> {}
155///
156/// // Returns `[('a, ['a, 'b]), ('b, ['b])]`
157/// fn foo<'a, 'b: 'a>() -> impl Sized + use<'a, 'b> {}
158///
159/// // Returns `[('a, ['a, 'b]), ('b, ['b])]`
160/// fn foo<'a, 'b>(_: &'a &'b ()) -> impl Sized + use<'a, 'b> {}
161/// ```
162///
163/// Importantly:
164/// - *All* captured regions are considered (not just those in outlives bounds)
165/// - It doesn't matter if the captured region is early-bound or late-bound
166{}
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("args_known_to_outlive_opaque_params",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(166u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[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:
Vec<(usize, DenseBitSet<u32>)> = loop {};
return __tracing_attr_fake_return;
}
{
let self_identity_args =
ty::GenericArgs::identity_for_item(tcx, def_id);
let mut result = Vec::new();
let (parent_def_id, wf_tys) =
match tcx.opaque_ty_origin(def_id) {
rustc_hir::OpaqueTyOrigin::FnReturn { parent, .. } |
rustc_hir::OpaqueTyOrigin::AsyncFn { parent, .. } |
rustc_hir::OpaqueTyOrigin::TyAlias { parent, .. } => {
let wf_tys =
FxIndexSet::from_iter(tcx.assumed_wf_types(parent.expect_local()).iter().map(|(ty,
_)| *ty));
(parent, wf_tys)
}
};
let parent_param_env = tcx.param_env(parent_def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:189",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(189u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("parent_param_env")
}> =
::tracing::__macro_support::FieldName::new("parent_param_env");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&parent_param_env)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let generics = tcx.generics_of(def_id);
let mut parent_outlives_regions =
Vec::with_capacity(generics.own_params.len());
for (opaque_arg_idx, opaque_arg) in
self_identity_args.iter().enumerate().skip(generics.parent_count)
{
let Some(opaque_region) =
opaque_arg.as_region() else { continue; };
let region_def_id =
match opaque_region.kind() {
ty::ReEarlyParam(ebr) =>
generics.param_at(ebr.index as usize, tcx).def_id,
_ => {
::core::panicking::panic_fmt(format_args!("unexpected region `{0}` in opaque bounds",
opaque_region));
}
};
let parent_region =
tcx.map_opaque_lifetime_to_parent_lifetime(region_def_id.expect_local());
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:218",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(218u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("region_def_id")
}> =
::tracing::__macro_support::FieldName::new("region_def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("parent_region")
}> =
::tracing::__macro_support::FieldName::new("parent_region");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(®ion_def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&parent_region)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
parent_outlives_regions.push((parent_region,
opaque_arg_idx));
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:221",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(221u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("parent_outlives_regions")
}> =
::tracing::__macro_support::FieldName::new("parent_outlives_regions");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&parent_outlives_regions)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
for (parent_outlived_region, opaque_outlived_arg_idx) in
parent_outlives_regions.iter() {
let mut opaque_outlives_args =
DenseBitSet::new_empty(self_identity_args.len());
for (parent_outlived_arg_idx, parent_outlives_arg) in
self_identity_args[..generics.parent_count].iter().enumerate()
{
let type_outlives =
match parent_outlives_arg.kind() {
ty::GenericArgKind::Const(_) => continue,
ty::GenericArgKind::Lifetime(_) => continue,
ty::GenericArgKind::Type(t) =>
ty_known_to_outlive(tcx, def_id, parent_param_env, &wf_tys,
t, *parent_outlived_region),
};
if !type_outlives { continue; }
opaque_outlives_args.insert(parent_outlived_arg_idx as u32);
}
for &(parent_outlives_region, opaque_arg_idx) in
parent_outlives_regions.iter() {
let region_outlives =
parent_outlives_region == *parent_outlived_region ||
region_known_to_outlive(tcx, def_id, parent_param_env,
&wf_tys, parent_outlives_region, *parent_outlived_region);
if !region_outlives { continue; }
opaque_outlives_args.insert(opaque_arg_idx as u32);
}
result.push((*opaque_outlived_arg_idx,
opaque_outlives_args));
}
result
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:166",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(166u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[tracing::instrument(level = "debug", skip(tcx), ret)]167pub(crate) fn args_known_to_outlive_opaque_params<'tcx>(
168 tcx: TyCtxt<'tcx>,
169 def_id: LocalDefId,
170) -> Vec<(usize, DenseBitSet<u32>)> {
171let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
172173let mut result = Vec::new();
174175// For implied bounds, we need the set of WF types from the parents.
176 // - For functions, this is all the input and output types.
177 // - For type alias, there are no implied bounds, so this is empty.
178let (parent_def_id, wf_tys) = match tcx.opaque_ty_origin(def_id) {
179 rustc_hir::OpaqueTyOrigin::FnReturn { parent, .. }
180 | rustc_hir::OpaqueTyOrigin::AsyncFn { parent, .. }
181 | rustc_hir::OpaqueTyOrigin::TyAlias { parent, .. } => {
182let wf_tys = FxIndexSet::from_iter(
183 tcx.assumed_wf_types(parent.expect_local()).iter().map(|(ty, _)| *ty),
184 );
185 (parent, wf_tys)
186 }
187 };
188let parent_param_env = tcx.param_env(parent_def_id);
189tracing::debug!(?parent_param_env);
190191// Map the outlives regions to the parent regions.
192 // If we have `fn foo<'a>() -> impl Sized + 'a`, then this gets lowered as
193 // ```ignore (illustrative)
194 // opaque foo_opaque<'a0>: Sized + 'a0;
195 // fn foo<'a>() -> foo::<'a>::foo_opaque<'a> { ... }
196 // ```
197 // This maps `'a0` to `'a`, because that is what will be used to get the
198 // explicit and implied outlives relations.
199 //
200 // I suppose, an alternative way to do this would be iterate through all the
201 // *parent* regions and then find those that are captured. This should be
202 // basically equivalent (except with the added frustration of needing to
203 // build a `Region` from the opaque region's `LocalDefId`).
204let generics = tcx.generics_of(def_id);
205let mut parent_outlives_regions = Vec::with_capacity(generics.own_params.len());
206for (opaque_arg_idx, opaque_arg) in
207self_identity_args.iter().enumerate().skip(generics.parent_count)
208 {
209let Some(opaque_region) = opaque_arg.as_region() else {
210continue;
211 };
212let region_def_id = match opaque_region.kind() {
213 ty::ReEarlyParam(ebr) => generics.param_at(ebr.index as usize, tcx).def_id,
214_ => panic!("unexpected region `{opaque_region}` in opaque bounds"),
215 };
216let parent_region =
217 tcx.map_opaque_lifetime_to_parent_lifetime(region_def_id.expect_local());
218tracing::debug!(?region_def_id, ?parent_region);
219 parent_outlives_regions.push((parent_region, opaque_arg_idx));
220 }
221tracing::debug!(?parent_outlives_regions);
222223// For every captured region, we want to consider outlived args from two sources:
224 // 1) *Types*: These come from *parent* generics (and are not duplicated to the opaque)
225 // 2) *Captured Regions*
226 //
227 // In both cases, we need to check known outlives for the *parent* region, because that's where the param_env and wf_tys are.
228for (parent_outlived_region, opaque_outlived_arg_idx) in parent_outlives_regions.iter() {
229let mut opaque_outlives_args = DenseBitSet::new_empty(self_identity_args.len());
230for (parent_outlived_arg_idx, parent_outlives_arg) in
231self_identity_args[..generics.parent_count].iter().enumerate()
232 {
233let type_outlives = match parent_outlives_arg.kind() {
234// Consts don't have any non-static regions
235ty::GenericArgKind::Const(_) => continue,
236// Lifetimes should be captured
237ty::GenericArgKind::Lifetime(_) => continue,
238 ty::GenericArgKind::Type(t) => ty_known_to_outlive(
239 tcx,
240 def_id,
241 parent_param_env,
242&wf_tys,
243 t,
244*parent_outlived_region,
245 ),
246 };
247if !type_outlives {
248continue;
249 }
250251// Types aren't captured, so don't need to map to the opaque
252opaque_outlives_args.insert(parent_outlived_arg_idx as u32);
253 }
254255for &(parent_outlives_region, opaque_arg_idx) in parent_outlives_regions.iter() {
256let region_outlives = parent_outlives_region == *parent_outlived_region
257 || region_known_to_outlive(
258 tcx,
259 def_id,
260 parent_param_env,
261&wf_tys,
262 parent_outlives_region,
263*parent_outlived_region,
264 );
265if !region_outlives {
266continue;
267 }
268269 opaque_outlives_args.insert(opaque_arg_idx as u32);
270 }
271272 result.push((*opaque_outlived_arg_idx, opaque_outlives_args));
273 }
274275 result
276}
277278{}
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("args_known_to_outlive_non_opaque_params",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(278u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[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:
Vec<(usize, DenseBitSet<u32>)> = loop {};
return __tracing_attr_fake_return;
}
{
let self_identity_args =
ty::GenericArgs::identity_for_item(tcx, def_id);
let param_env = tcx.param_env(def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:285",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(285u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("param_env")
}> =
::tracing::__macro_support::FieldName::new("param_env");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(¶m_env)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let wf_tys =
tcx.assumed_wf_types(def_id).iter().map(|(ty, _)|
*ty).collect::<FxIndexSet<_>>();
let mut result = Vec::new();
for (outlived_arg_idx, outlived_arg) in
self_identity_args.iter().enumerate() {
let Some(outlived_region) =
outlived_arg.as_region() else { continue; };
let mut outliving_args =
DenseBitSet::new_empty(self_identity_args.len());
for (arg_idx, arg) in self_identity_args.iter().enumerate()
{
let outlives =
match arg.kind() {
ty::GenericArgKind::Lifetime(r) => {
region_known_to_outlive(tcx, def_id, param_env, &wf_tys, r,
outlived_region)
}
ty::GenericArgKind::Type(t) => {
ty_known_to_outlive(tcx, def_id, param_env, &wf_tys, t,
outlived_region)
}
ty::GenericArgKind::Const(_) => false,
};
if outlives { outliving_args.insert(arg_idx as u32); }
}
result.push((outlived_arg_idx, outliving_args));
}
result
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:278",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(278u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[tracing::instrument(level = "debug", skip(tcx), ret)]279pub(crate) fn args_known_to_outlive_non_opaque_params<'tcx>(
280 tcx: TyCtxt<'tcx>,
281 def_id: LocalDefId,
282) -> Vec<(usize, DenseBitSet<u32>)> {
283let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
284let param_env = tcx.param_env(def_id);
285tracing::debug!(?param_env);
286let wf_tys = tcx.assumed_wf_types(def_id).iter().map(|(ty, _)| *ty).collect::<FxIndexSet<_>>();
287let mut result = Vec::new();
288for (outlived_arg_idx, outlived_arg) in self_identity_args.iter().enumerate() {
289let Some(outlived_region) = outlived_arg.as_region() else {
290continue;
291 };
292let mut outliving_args = DenseBitSet::new_empty(self_identity_args.len());
293for (arg_idx, arg) in self_identity_args.iter().enumerate() {
294let outlives = match arg.kind() {
295 ty::GenericArgKind::Lifetime(r) => {
296 region_known_to_outlive(tcx, def_id, param_env, &wf_tys, r, outlived_region)
297 }
298 ty::GenericArgKind::Type(t) => {
299 ty_known_to_outlive(tcx, def_id, param_env, &wf_tys, t, outlived_region)
300 }
301 ty::GenericArgKind::Const(_) => false,
302 };
303if outlives {
304 outliving_args.insert(arg_idx as u32);
305 }
306 }
307 result.push((outlived_arg_idx, outliving_args));
308 }
309 result
310}
311312/// For a param-env clause `for<'v..> <T as Trait>::Assoc<..>: 'bound` that
313/// applies to `ty` (an alias with `alias_def_id`), returns the set of indices into the
314/// identity args that the underlying type could possibly capture, as restricted by this clause.
315///
316/// As an example, let's imagine we had the following associated type definition:
317/// ```ignore (illustrative)
318/// type Assoc<'a, 'b, 'c: 'a> = (&'a &'c (), &'b ());
319/// ```
320///
321/// the following clause:
322/// ```ignore (illustrative)
323/// for<'x, 'y> T::Assoc<'x, 'x, 'y>: 'x
324/// ```
325///
326/// We know from the clause alone that *given some substitution of `T:Assoc`*,
327/// we know that it can capture either the first or the second region. However,
328/// the bounds on the associated type itself additionally imply that the
329/// third region can *also* be captured, because it outlives the first.
330///
331/// Now, let's assume we had this clause:
332/// ```ignore (illustrative)
333/// for<'x, 'y> T::Assoc<'x, 'y, 'x>: 'x
334/// ```
335///
336/// Here, we know that `'a` and `'c` could be captured, but there is no outlives
337/// relationship to `'b` for either of those, so the underlying type can't
338/// capture any arg containing `'b`.
339///
340/// Note: because higher-ranked bounds don't have implications, there will be
341/// some cases (like `for<'x, 'y, 'z> T::Assoc<'x, 'y, 'z>: 'x`) that won't
342/// be satisfiable today, but the logic here should hold whenever there *is*.
343///
344/// Returns a filled set if the clause doesn't apply to `ty` or gives us no
345/// information.
346{}
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("live_args_for_outlives_clause",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(346u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("alias_def_id")
}> =
::tracing::__macro_support::FieldName::new("alias_def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("ty")
}> =
::tracing::__macro_support::FieldName::new("ty");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("outlives")
}> =
::tracing::__macro_support::FieldName::new("outlives");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&alias_def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&outlives)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[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: DenseBitSet<u32> = loop {};
return __tracing_attr_fake_return;
}
{
let clause_identity_args =
ty::GenericArgs::identity_for_item(tcx, alias_def_id);
let no_restriction =
|| DenseBitSet::new_filled(clause_identity_args.len());
let ty::Alias(_, ty::AliasTy {
kind: clause_alias_kind, args: clause_args, .. }) =
*outlives.skip_binder().0.kind() else {
return no_restriction();
};
let clause_def_id =
match clause_alias_kind {
ty::AliasTyKind::Projection { def_id } |
ty::AliasTyKind::Inherent { def_id } |
ty::AliasTyKind::Opaque { def_id } | ty::AliasTyKind::Free {
def_id } => def_id,
};
if clause_def_id != alias_def_id {
return no_restriction();
}
let Some(_) =
test_type_match::extract_verify_if_eq(tcx,
&outlives.map_bound(|ty::OutlivesClause(ty, bound)|
VerifyIfEq { ty, bound }),
ty) else { return no_restriction(); };
let outlived_region = outlives.skip_binder().1;
match outlived_region.kind() {
ty::ReStatic =>
DenseBitSet::new_empty(clause_identity_args.len()),
ty::ReBound(_, br) => {
let mut outlived_regions = Vec::new();
for (clause_arg, (identity_arg_idx, _identity_arg)) in
clause_args.iter().zip(clause_identity_args.iter().enumerate())
{
match clause_arg.kind() {
ty::GenericArgKind::Lifetime(r) => {
if let ty::ReBound(_, arg_br) = r.kind() &&
arg_br.var == br.var {
outlived_regions.push(identity_arg_idx);
}
}
ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_)
=> {
if clause_arg.has_escaping_bound_vars() {
return no_restriction();
}
}
}
}
if outlived_regions.is_empty() {
return DenseBitSet::new_empty(clause_identity_args.len());
}
let args_known_to_outlive =
tcx.args_known_to_outlive_alias_params(alias_def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:433",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(433u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("outlived_regions")
}> =
::tracing::__macro_support::FieldName::new("outlived_regions");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("args_known_to_outlive")
}> =
::tracing::__macro_support::FieldName::new("args_known_to_outlive");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&outlived_regions)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&args_known_to_outlive)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let mut capturable_args =
DenseBitSet::new_empty(clause_identity_args.len());
for &outlived_arg_idx in &outlived_regions {
let (_, outliving_args) =
args_known_to_outlive.iter().find(|(arg_idx, _)|
*arg_idx == outlived_arg_idx).unwrap();
capturable_args.union(outliving_args);
}
capturable_args
}
ty::ReEarlyParam(..) => no_restriction(),
_ => no_restriction(),
}
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:346",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(346u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[tracing::instrument(level = "debug", skip(tcx), ret)]347fn live_args_for_outlives_clause<'tcx>(
348 tcx: TyCtxt<'tcx>,
349 alias_def_id: DefId,
350 ty: Ty<'tcx>,
351 outlives: ty::Binder<'tcx, ty::TypeOutlivesClause<'tcx>>,
352) -> DenseBitSet<u32> {
353let clause_identity_args = ty::GenericArgs::identity_for_item(tcx, alias_def_id);
354let no_restriction = || DenseBitSet::new_filled(clause_identity_args.len());
355356// N.B. it's okay to skip the binder here (and in the rest of the function),
357 // because all variables under binders do not escape
358let ty::Alias(_, ty::AliasTy { kind: clause_alias_kind, args: clause_args, .. }) =
359*outlives.skip_binder().0.kind()
360else {
361return no_restriction();
362 };
363let clause_def_id = match clause_alias_kind {
364 ty::AliasTyKind::Projection { def_id }
365 | ty::AliasTyKind::Inherent { def_id }
366 | ty::AliasTyKind::Opaque { def_id }
367 | ty::AliasTyKind::Free { def_id } => def_id,
368 };
369if clause_def_id != alias_def_id {
370return no_restriction();
371 }
372373// Here, we're just using this to check if the clause *could apply* to `ty`,
374 // but importantly we don't want to use the returned region, because that is
375 // the "last visited" region in `ty` that matches the outlves bound. Actually,
376 // we want *all* the identity regions in `ty` that match the outlives bound.
377let Some(_) = test_type_match::extract_verify_if_eq(
378 tcx,
379&outlives.map_bound(|ty::OutlivesClause(ty, bound)| VerifyIfEq { ty, bound }),
380 ty,
381 ) else {
382return no_restriction();
383 };
384385let outlived_region = outlives.skip_binder().1;
386match outlived_region.kind() {
387// The underlying type must outlive `'static`, so it can't capture any of the args at all.
388 //
389 // Of course, you may ask: "what if the function has a `'a: 'static` bound?" See the corresponding
390 // comment in `live_args_for_alias_from_outlives_bounds` for why we don't need to worry about that.
391ty::ReStatic => DenseBitSet::new_empty(clause_identity_args.len()),
392 ty::ReBound(_, br) => {
393// The bound is one of the clause's higher-ranked vars. Find the arg
394 // positions it occupies, then (at the alias's identity level) find
395 // all args that are known to outlive one of those positions given
396 // the alias's declared bounds -- only those can be captured by the
397 // underlying type.
398let mut outlived_regions = Vec::new();
399for (clause_arg, (identity_arg_idx, _identity_arg)) in
400clause_args.iter().zip(clause_identity_args.iter().enumerate())
401 {
402match clause_arg.kind() {
403 ty::GenericArgKind::Lifetime(r) => {
404if let ty::ReBound(_, arg_br) = r.kind()
405 && arg_br.var == br.var
406 {
407 outlived_regions.push(identity_arg_idx);
408 }
409 }
410 ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_) => {
411// A bound var inside a type or const arg (e.g.
412 // `for<'a> <F as FnOnce<(&'a mut i32,)>>::Output: 'a`)
413 // can't be reasoned about at the identity-param level,
414 // so conservatively treat the clause as giving no
415 // restriction at all.
416if clause_arg.has_escaping_bound_vars() {
417return no_restriction();
418 }
419 }
420 }
421 }
422if outlived_regions.is_empty() {
423// The bound var doesn't appear in the args at all, so the clause
424 // requires the underlying type to outlive *every* region, which
425 // is equivalent to a `'static` bound.
426return DenseBitSet::new_empty(clause_identity_args.len());
427 }
428429// The underlying type can capture any arg that's known to outlive one
430 // of the bound var's positions (they're all instantiated to the same
431 // region at any use site this clause applies to).
432let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(alias_def_id);
433tracing::debug!(?outlived_regions, ?args_known_to_outlive);
434let mut capturable_args = DenseBitSet::new_empty(clause_identity_args.len());
435for &outlived_arg_idx in &outlived_regions {
436let (_, outliving_args) = args_known_to_outlive
437 .iter()
438 .find(|(arg_idx, _)| *arg_idx == outlived_arg_idx)
439 .unwrap();
440 capturable_args.union(outliving_args);
441 }
442 capturable_args
443 }
444// A free region (e.g. `for<a> T::Assoc<'a, 'x>: 'x`, where `'x` is free).
445 // This is effectively the same as `for<'a, 'b> T::Assoc<'a, 'b>: 'b`,
446 // but that only is sound if we either know that the second substituted
447 // lifetime equals `'x` or if we *constrain* that lifetime to be `'x`.
448 //
449 // In either case, something like this doesn't work today:
450 // ```ignore (illustrative)
451 // fn bar<'a, 'b>(a: &'a mut (), b: &'b ()) -> <Foo as MyTrait>::Assoc<'a, 'b> { b }
452 // fn foo<'x>()
453 // where
454 // for<'h> <Foo as MyTrait>::Assoc<'h, 'x>: 'x,
455 // {
456 // let a = &mut ();
457 // let b: &'x () = &();
458 // let val1 = rpit(a, b);
459 // let val2 = rpit(a, b);
460 // drop(val1);
461 // drop(val32);
462 // }
463 // ```
464 // So, we conservatively treat this as giving no restriction on which args can be captured.
465ty::ReEarlyParam(..) => no_restriction(),
466// Don't know that we actually hit this (maybe `ReError`), go ahead and be conservative.
467_ => no_restriction(),
468 }
469}
470471/// Visits free regions in the type that are relevant for liveness computation.
472/// These regions are passed to `OP`.
473///
474/// Specifically, we visit all of the regions of types recursively, except if
475/// the type is an alias, we look at the outlives bounds in the param-env and
476/// the alias's item bounds. Each such bound restricts which of the alias's
477/// args the underlying type could have captured, so only those (capturable)
478/// args are visited. If there are no applicable bounds, we walk through the
479/// alias's (non-bivariant) args structurally.
480pub struct FreeRegionsVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
481pub tcx: TyCtxt<'tcx>,
482pub param_env: ty::ParamEnv<'tcx>,
483pub op: OP,
484}
485486impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
487where
488OP: FnMut(ty::Region<'tcx>),
489{
490fn visit_region(&mut self, r: ty::Region<'tcx>) {
491match r.kind() {
492// ignore bound regions, keep visiting
493ty::ReBound(_, _) => {}
494_ => (self.op)(r),
495 }
496 }
497498{}
#[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_ty",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(498u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("ty")
}> =
::tracing::__macro_support::FieldName::new("ty");
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::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ty)
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: () = loop {};
return __tracing_attr_fake_return;
}
{
if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
return;
}
match *ty.kind() {
ty::Alias(_, ty::AliasTy { kind, args, .. }) => {
let tcx = self.tcx;
let param_env = self.param_env;
let def_id =
match kind {
ty::AliasTyKind::Projection { def_id } |
ty::AliasTyKind::Inherent { def_id } |
ty::AliasTyKind::Opaque { def_id } | ty::AliasTyKind::Free {
def_id } => def_id,
};
let mut capturable =
tcx.live_args_for_alias_from_outlives_bounds(kind).clone();
for clause in param_env.caller_bounds() {
let Some(outlives) =
clause.as_type_outlives_clause() else { continue; };
capturable.intersect(&live_args_for_outlives_clause(tcx,
def_id, ty, outlives));
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:541",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/809936eac66c547a5127ce1da805f0d3a6789b98/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(541u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::outlives_for_liveness"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("capturable")
}> =
::tracing::__macro_support::FieldName::new("capturable");
NAME.as_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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&capturable)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let variances = tcx.opt_alias_variances(kind);
for idx in capturable.iter() {
if variances.map(|variances| variances[idx as usize]) !=
Some(ty::Bivariant) {
args[idx as usize].visit_with(self);
}
}
}
_ => ty.super_visit_with(self),
}
}
}
}#[tracing::instrument(skip(self), level = "debug")]499fn visit_ty(&mut self, ty: Ty<'tcx>) {
500// We're only interested in types involving regions
501if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
502return;
503 }
504505match *ty.kind() {
506// We can prove that an alias is live two ways:
507 // 1. All the components are live.
508 // 2. There is a known outlives bound or where-clause, and that
509 // region is live.
510 //
511 // We search through the item bounds and where clauses for
512 // either `'static` or a unique outlives region, and if one is
513 // found, we just need to prove that that region is still live.
514 // If one is not found, then we continue to walk through the alias.
515ty::Alias(_, ty::AliasTy { kind, args, .. }) => {
516let tcx = self.tcx;
517let param_env = self.param_env;
518519// For aliases other than opaques, we have to consider two
520 // sources of information to identity potentially-live args:
521 // - Bounds on alias item itself
522 // - Outlives clauses on the current function that apply to the alias
523 //
524 // Each source of information *restricts* the set of potentially-live
525 // args independently: only the args that can be live for *every*
526 // source of information can be actually live, so we take the intersection.
527let def_id = match kind {
528 ty::AliasTyKind::Projection { def_id }
529 | ty::AliasTyKind::Inherent { def_id }
530 | ty::AliasTyKind::Opaque { def_id }
531 | ty::AliasTyKind::Free { def_id } => def_id,
532 };
533let mut capturable = tcx.live_args_for_alias_from_outlives_bounds(kind).clone();
534535for clause in param_env.caller_bounds() {
536let Some(outlives) = clause.as_type_outlives_clause() else {
537continue;
538 };
539 capturable.intersect(&live_args_for_outlives_clause(tcx, def_id, ty, outlives));
540 }
541tracing::debug!(?capturable);
542543// Skip lifetime parameters that are not captured, since they do
544 // not need to be live.
545let variances = tcx.opt_alias_variances(kind);
546for idx in capturable.iter() {
547if variances.map(|variances| variances[idx as usize]) != Some(ty::Bivariant) {
548 args[idx as usize].visit_with(self);
549 }
550 }
551 }
552553_ => ty.super_visit_with(self),
554 }
555 }
556}