1use std::debug_assert_matches;
23use rustc_data_structures::fx::FxIndexSet;
4use rustc_hir::def::DefKind;
5use rustc_hir::def_id::{DefId, LocalDefId};
6use rustc_index::bit_set::DenseBitSet;
7use rustc_infer::infer::{SubregionOrigin, TypeOutlivesConstraint};
8use rustc_middle::ty::{
9self, Flags, ImplTraitInTraitData, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
10TypeVisitableExt, TypeVisitor,
11};
12use rustc_span::{DUMMY_SP, bug};
1314use crate::infer::outlives::test_type_match;
15use crate::infer::region_constraints::VerifyIfEq;
16use crate::regions::{region_known_to_outlive, test_region_obligations};
1718/// Given a known `param_env` and a set of well formed types, can we prove that
19/// `ty` outlives `region`.
20///
21/// Copied from `ty_known_to_outlive` without normalization for `ty` because we
22/// don't want trait solving in liveness queries.
23fn param_known_to_outlive<'tcx>(
24 tcx: TyCtxt<'tcx>,
25 id: LocalDefId,
26 param_env: ty::ParamEnv<'tcx>,
27 wf_tys: &FxIndexSet<Ty<'tcx>>,
28 ty: Ty<'tcx>,
29 region: ty::Region<'tcx>,
30) -> bool {
31if true {
{
match ty.kind() {
ty::Param(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ty::Param(_)", ::core::option::Option::None);
}
}
};
};debug_assert_matches!(ty.kind(), ty::Param(_));
3233test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
34infcx.register_type_outlives_constraint_inner(TypeOutlivesConstraint {
35 sub_region: region,
36 sup_type: ty,
37 origin: SubregionOrigin::RelateParamBound(DUMMY_SP, ty, None),
38 });
39Ok(())
40 })
41}
4243/// For a given alias type, this returns the set of indices into the identity generic args that
44/// are relevant for liveness, that can be inferred from outlives bounds on the
45/// alias itself, and the explicit and implicit outlives clauses of the alias.
46/// Callers should use the indices with the concrete args of the alias.
47///
48/// There are three cases to consider:
49/// 1. If there are *no* outlives bounds, then all args are potentially live.
50/// 2. If there is a `'static` outlives bound, then we know that all args are
51/// irrelevant, so we return an empty set.
52/// 3. If there are *any* outlives bounds, then we find any args that are known
53/// to outlive those bounds, since those are the args whose regions the
54/// underlying type could capture.
55{}
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(55u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:70",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(70u32),
::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 ty::OutlivesClause(ty, region) =
clause.as_type_outlives_clause()?.skip_binder();
if ty != alias_ty { return None; }
if region.is_bound() {
Some(tcx.lifetimes.re_static)
} else { Some(region) }
}).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/7bbda45cb1ec0a378d91959646a8fa904be3192a/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/7bbda45cb1ec0a378d91959646a8fa904be3192a/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(&[{
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:113",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(113u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:123",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(123u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:55",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(55u32),
::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)]56pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>(
57 tcx: TyCtxt<'tcx>,
58 kind: ty::AliasTyKind<'tcx>,
59) -> DenseBitSet<u32> {
60let def_id = match kind {
61 ty::AliasTyKind::Projection { def_id }
62 | ty::AliasTyKind::Inherent { def_id }
63 | ty::AliasTyKind::Opaque { def_id }
64 | ty::AliasTyKind::Free { def_id } => def_id,
65 };
66let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
6768// We first want to collect the outlives bounds of the alias.
69let bounds = tcx.item_bounds(def_id).instantiate_identity().skip_norm_wip();
70tracing::debug!(?bounds);
71let alias_ty = Ty::new_alias(
72 tcx,
73 ty::IsRigid::No,
74 ty::AliasTy::new_from_args(tcx, kind, self_identity_args),
75 );
76let outlives_regions: Vec<_> = bounds
77 .iter()
78 .filter_map(|clause| {
79let ty::OutlivesClause(ty, region) = clause.as_type_outlives_clause()?.skip_binder();
80if ty != alias_ty {
81return None;
82 }
8384// Opaques can't have higher-ranked outlives item bounds. Higher-ranked item bounds
85 // for GATs are instantiated with the GAT identity params, so the alias doesn't
86 // contain any bound regions. If the region is bound, the alias outlives everything.
87 // For example: `for<'a> Self::Assoc<'non_bound>: 'a`.
88if region.is_bound() { Some(tcx.lifetimes.re_static) } else { Some(region) }
89 })
90 .collect();
91tracing::debug!(?outlives_regions);
9293// If there are no outlives bounds, then all (non-bivariant) args are potentially live.
94if outlives_regions.is_empty() {
95return DenseBitSet::new_filled(self_identity_args.len());
96 }
9798// If any of the outlives bounds are `'static`, then we know the alias
99 // doesn't capture *any* regions, so we can skip visiting any regions at all.
100 //
101 // I was originally a bit concerned about something like `'a: 'static`, and
102 // whether or not we need to mark `'a` as live. I don't think that we do.
103 //
104 // To dig in a bit: Think about the function using this alias. For the alias
105 // to be well-formed, then it must be proven that the arg (`'a` in this case)
106 // outlives `'static`. Well, if that is proven *once*, then it must be true
107 // across the entire function (because `'static` is free).
108 //
109 // I think this similarly applies to any other free region, like `'a: 'b`
110 // where `'b` is *also* free. Though, we of course can't know *here* which
111 // regions are going to be instantiated with free regions.
112if outlives_regions.contains(&tcx.lifetimes.re_static) {
113tracing::debug!("alias has a 'static outlives bound, so skipping visiting any regions");
114return DenseBitSet::new_empty(self_identity_args.len());
115 }
116117// Okay, so we know we have some outlives bounds, and that none of them are `'static`.
118 // Now, we need to find all other potentially-live args, those that outlive
119 // an outlives-bound region. `args_known_to_outlive_alias_params` does this
120 // for us, and in the case of opaques only includes *captured* regions, too.
121122let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(def_id);
123tracing::debug!(?args_known_to_outlive);
124let mut live_args = DenseBitSet::new_filled(self_identity_args.len());
125for outlives_region in outlives_regions {
126let Some(outlives_params) = args_known_to_outlive
127 .iter()
128 .find(|(idx, _)| self_identity_args[*idx].as_region() == Some(outlives_region))
129else {
130continue;
131 };
132 live_args.intersect(&outlives_params.1);
133 }
134 live_args
135}
136137/// For each region param of this alias compute the indices of the identity args
138/// that are known to outlive it, given only the alias's declared where-clauses.
139///
140/// Note: for opaques (including synthetic associated types from RPITITs),
141/// the outlives relationships are identified in the context of the *parent*,
142/// since bounds and well-formed types are not lowered.
143{}
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(143u32),
::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_span::macros::bug_impl(None,
format_args!("improper def_kind {0:?} passed to `live_args_for_alias_from_outlives_bounds`",
kind), Location::caller())
}
}
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:143",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(143u32),
::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)]144pub(crate) fn args_known_to_outlive_alias_params<'tcx>(
145 tcx: TyCtxt<'tcx>,
146 def_id: LocalDefId,
147) -> Vec<(usize, DenseBitSet<u32>)> {
148match tcx.def_kind(def_id) {
149 DefKind::OpaqueTy => args_known_to_outlive_opaque_params(tcx, def_id),
150 DefKind::AssocTy
151if let Some(ImplTraitInTraitData::Trait { fn_def_id: _, opaque_def_id }) =
152 tcx.opt_rpitit_info(def_id.to_def_id()) =>
153 {
154 args_known_to_outlive_opaque_params(tcx, opaque_def_id.expect_local())
155 }
156 DefKind::AssocTy | DefKind::TyAlias => args_known_to_outlive_non_opaque_params(tcx, def_id),
157 kind => {
158bug!("improper def_kind {kind:?} passed to `live_args_for_alias_from_outlives_bounds`")
159 }
160 }
161}
162163/// For each *captured* region of this alias, compute the *captured* identity
164/// args that are known to outlive it, given the definition of the opaque type
165/// in the the *parent* context.
166///
167/// Some examples:
168/// ```ignore (illustrative)
169/// // Returns `[('a, ['a]), ('b, ['b])]`
170/// fn foo<'a, 'b>() -> impl Sized + use<'a, 'b> {}
171///
172/// // Returns `[('a, ['a]), ('b, ['b])]`
173/// fn foo<'a: 'a, 'b>() -> impl Sized + use<'a, 'b> {}
174///
175/// // Returns `[('a, ['a])]`
176/// fn foo<'a, 'b>() -> impl Sized + use<'a> {}
177///
178/// // Returns `[('a, ['a, 'b]), ('b, ['b])]`
179/// fn foo<'a, 'b: 'a>() -> impl Sized + use<'a, 'b> {}
180///
181/// // Returns `[('a, ['a, 'b]), ('b, ['b])]`
182/// fn foo<'a, 'b>(_: &'a &'b ()) -> impl Sized + use<'a, 'b> {}
183/// ```
184///
185/// Importantly:
186/// - *All* captured regions are considered (not just those in outlives bounds)
187/// - It doesn't matter if the captured region is early-bound or late-bound
188{}
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(188u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:211",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(211u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:240",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(240u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:243",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(243u32),
::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) =>
param_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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:188",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(188u32),
::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)]189pub(crate) fn args_known_to_outlive_opaque_params<'tcx>(
190 tcx: TyCtxt<'tcx>,
191 def_id: LocalDefId,
192) -> Vec<(usize, DenseBitSet<u32>)> {
193let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
194195let mut result = Vec::new();
196197// For implied bounds, we need the set of WF types from the parents.
198 // - For functions, this is all the input and output types.
199 // - For type alias, there are no implied bounds, so this is empty.
200let (parent_def_id, wf_tys) = match tcx.opaque_ty_origin(def_id) {
201 rustc_hir::OpaqueTyOrigin::FnReturn { parent, .. }
202 | rustc_hir::OpaqueTyOrigin::AsyncFn { parent, .. }
203 | rustc_hir::OpaqueTyOrigin::TyAlias { parent, .. } => {
204let wf_tys = FxIndexSet::from_iter(
205 tcx.assumed_wf_types(parent.expect_local()).iter().map(|(ty, _)| *ty),
206 );
207 (parent, wf_tys)
208 }
209 };
210let parent_param_env = tcx.param_env(parent_def_id);
211tracing::debug!(?parent_param_env);
212213// Map the outlives regions to the parent regions.
214 // If we have `fn foo<'a>() -> impl Sized + 'a`, then this gets lowered as
215 // ```ignore (illustrative)
216 // opaque foo_opaque<'a0>: Sized + 'a0;
217 // fn foo<'a>() -> foo::<'a>::foo_opaque<'a> { ... }
218 // ```
219 // This maps `'a0` to `'a`, because that is what will be used to get the
220 // explicit and implied outlives relations.
221 //
222 // I suppose, an alternative way to do this would be iterate through all the
223 // *parent* regions and then find those that are captured. This should be
224 // basically equivalent (except with the added frustration of needing to
225 // build a `Region` from the opaque region's `LocalDefId`).
226let generics = tcx.generics_of(def_id);
227let mut parent_outlives_regions = Vec::with_capacity(generics.own_params.len());
228for (opaque_arg_idx, opaque_arg) in
229self_identity_args.iter().enumerate().skip(generics.parent_count)
230 {
231let Some(opaque_region) = opaque_arg.as_region() else {
232continue;
233 };
234let region_def_id = match opaque_region.kind() {
235 ty::ReEarlyParam(ebr) => generics.param_at(ebr.index as usize, tcx).def_id,
236_ => panic!("unexpected region `{opaque_region}` in opaque bounds"),
237 };
238let parent_region =
239 tcx.map_opaque_lifetime_to_parent_lifetime(region_def_id.expect_local());
240tracing::debug!(?region_def_id, ?parent_region);
241 parent_outlives_regions.push((parent_region, opaque_arg_idx));
242 }
243tracing::debug!(?parent_outlives_regions);
244245// For every captured region, we want to consider outlived args from two sources:
246 // 1) *Types*: These come from *parent* generics (and are not duplicated to the opaque)
247 // 2) *Captured Regions*
248 //
249 // In both cases, we need to check known outlives for the *parent* region, because that's where the param_env and wf_tys are.
250for (parent_outlived_region, opaque_outlived_arg_idx) in parent_outlives_regions.iter() {
251let mut opaque_outlives_args = DenseBitSet::new_empty(self_identity_args.len());
252for (parent_outlived_arg_idx, parent_outlives_arg) in
253self_identity_args[..generics.parent_count].iter().enumerate()
254 {
255let type_outlives = match parent_outlives_arg.kind() {
256// Consts don't have any non-static regions
257ty::GenericArgKind::Const(_) => continue,
258// Lifetimes should be captured
259ty::GenericArgKind::Lifetime(_) => continue,
260 ty::GenericArgKind::Type(t) => param_known_to_outlive(
261 tcx,
262 def_id,
263 parent_param_env,
264&wf_tys,
265 t,
266*parent_outlived_region,
267 ),
268 };
269if !type_outlives {
270continue;
271 }
272273// Types aren't captured, so don't need to map to the opaque
274opaque_outlives_args.insert(parent_outlived_arg_idx as u32);
275 }
276277for &(parent_outlives_region, opaque_arg_idx) in parent_outlives_regions.iter() {
278let region_outlives = parent_outlives_region == *parent_outlived_region
279 || region_known_to_outlive(
280 tcx,
281 def_id,
282 parent_param_env,
283&wf_tys,
284 parent_outlives_region,
285*parent_outlived_region,
286 );
287if !region_outlives {
288continue;
289 }
290291 opaque_outlives_args.insert(opaque_arg_idx as u32);
292 }
293294 result.push((*opaque_outlived_arg_idx, opaque_outlives_args));
295 }
296297 result
298}
299300{}
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(300u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:307",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(307u32),
::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) => {
param_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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:300",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(300u32),
::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)]301pub(crate) fn args_known_to_outlive_non_opaque_params<'tcx>(
302 tcx: TyCtxt<'tcx>,
303 def_id: LocalDefId,
304) -> Vec<(usize, DenseBitSet<u32>)> {
305let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
306let param_env = tcx.param_env(def_id);
307tracing::debug!(?param_env);
308let wf_tys = tcx.assumed_wf_types(def_id).iter().map(|(ty, _)| *ty).collect::<FxIndexSet<_>>();
309let mut result = Vec::new();
310for (outlived_arg_idx, outlived_arg) in self_identity_args.iter().enumerate() {
311let Some(outlived_region) = outlived_arg.as_region() else {
312continue;
313 };
314let mut outliving_args = DenseBitSet::new_empty(self_identity_args.len());
315for (arg_idx, arg) in self_identity_args.iter().enumerate() {
316let outlives = match arg.kind() {
317 ty::GenericArgKind::Lifetime(r) => {
318 region_known_to_outlive(tcx, def_id, param_env, &wf_tys, r, outlived_region)
319 }
320 ty::GenericArgKind::Type(t) => {
321 param_known_to_outlive(tcx, def_id, param_env, &wf_tys, t, outlived_region)
322 }
323 ty::GenericArgKind::Const(_) => false,
324 };
325if outlives {
326 outliving_args.insert(arg_idx as u32);
327 }
328 }
329 result.push((outlived_arg_idx, outliving_args));
330 }
331 result
332}
333334/// For a param-env clause `for<'v..> <T as Trait>::Assoc<..>: 'bound` that
335/// applies to `ty` (an alias with `alias_def_id`), returns the set of indices into the
336/// identity args that the underlying type could possibly capture, as restricted by this clause.
337///
338/// As an example, let's imagine we had the following associated type definition:
339/// ```ignore (illustrative)
340/// type Assoc<'a, 'b, 'c: 'a> = (&'a &'c (), &'b ());
341/// ```
342///
343/// the following clause:
344/// ```ignore (illustrative)
345/// for<'x, 'y> T::Assoc<'x, 'x, 'y>: 'x
346/// ```
347///
348/// We know from the clause alone that *given some substitution of `T:Assoc`*,
349/// we know that it can capture either the first or the second region. However,
350/// the bounds on the associated type itself additionally imply that the
351/// third region can *also* be captured, because it outlives the first.
352///
353/// Now, let's assume we had this clause:
354/// ```ignore (illustrative)
355/// for<'x, 'y> T::Assoc<'x, 'y, 'x>: 'x
356/// ```
357///
358/// Here, we know that `'a` and `'c` could be captured, but there is no outlives
359/// relationship to `'b` for either of those, so the underlying type can't
360/// capture any arg containing `'b`.
361///
362/// Note: because higher-ranked bounds don't have implications, there will be
363/// some cases (like `for<'x, 'y, 'z> T::Assoc<'x, 'y, 'z>: 'x`) that won't
364/// be satisfiable today, but the logic here should hold whenever there *is*.
365///
366/// Returns a filled set if the clause doesn't apply to `ty` or gives us no
367/// information.
368{}
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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(368u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:455",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(455u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:368",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(368u32),
::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)]369fn live_args_for_outlives_clause<'tcx>(
370 tcx: TyCtxt<'tcx>,
371 alias_def_id: DefId,
372 ty: Ty<'tcx>,
373 outlives: ty::Binder<'tcx, ty::TypeOutlivesClause<'tcx>>,
374) -> DenseBitSet<u32> {
375let clause_identity_args = ty::GenericArgs::identity_for_item(tcx, alias_def_id);
376let no_restriction = || DenseBitSet::new_filled(clause_identity_args.len());
377378// N.B. it's okay to skip the binder here (and in the rest of the function),
379 // because all variables under binders do not escape
380let ty::Alias(_, ty::AliasTy { kind: clause_alias_kind, args: clause_args, .. }) =
381*outlives.skip_binder().0.kind()
382else {
383return no_restriction();
384 };
385let clause_def_id = match clause_alias_kind {
386 ty::AliasTyKind::Projection { def_id }
387 | ty::AliasTyKind::Inherent { def_id }
388 | ty::AliasTyKind::Opaque { def_id }
389 | ty::AliasTyKind::Free { def_id } => def_id,
390 };
391if clause_def_id != alias_def_id {
392return no_restriction();
393 }
394395// Here, we're just using this to check if the clause *could apply* to `ty`,
396 // but importantly we don't want to use the returned region, because that is
397 // the "last visited" region in `ty` that matches the outlves bound. Actually,
398 // we want *all* the identity regions in `ty` that match the outlives bound.
399let Some(_) = test_type_match::extract_verify_if_eq(
400 tcx,
401&outlives.map_bound(|ty::OutlivesClause(ty, bound)| VerifyIfEq { ty, bound }),
402 ty,
403 ) else {
404return no_restriction();
405 };
406407let outlived_region = outlives.skip_binder().1;
408match outlived_region.kind() {
409// The underlying type must outlive `'static`, so it can't capture any of the args at all.
410 //
411 // Of course, you may ask: "what if the function has a `'a: 'static` bound?" See the corresponding
412 // comment in `live_args_for_alias_from_outlives_bounds` for why we don't need to worry about that.
413ty::ReStatic => DenseBitSet::new_empty(clause_identity_args.len()),
414 ty::ReBound(_, br) => {
415// The bound is one of the clause's higher-ranked vars. Find the arg
416 // positions it occupies, then (at the alias's identity level) find
417 // all args that are known to outlive one of those positions given
418 // the alias's declared bounds -- only those can be captured by the
419 // underlying type.
420let mut outlived_regions = Vec::new();
421for (clause_arg, (identity_arg_idx, _identity_arg)) in
422clause_args.iter().zip(clause_identity_args.iter().enumerate())
423 {
424match clause_arg.kind() {
425 ty::GenericArgKind::Lifetime(r) => {
426if let ty::ReBound(_, arg_br) = r.kind()
427 && arg_br.var == br.var
428 {
429 outlived_regions.push(identity_arg_idx);
430 }
431 }
432 ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_) => {
433// A bound var inside a type or const arg (e.g.
434 // `for<'a> <F as FnOnce<(&'a mut i32,)>>::Output: 'a`)
435 // can't be reasoned about at the identity-param level,
436 // so conservatively treat the clause as giving no
437 // restriction at all.
438if clause_arg.has_escaping_bound_vars() {
439return no_restriction();
440 }
441 }
442 }
443 }
444if outlived_regions.is_empty() {
445// The bound var doesn't appear in the args at all, so the clause
446 // requires the underlying type to outlive *every* region, which
447 // is equivalent to a `'static` bound.
448return DenseBitSet::new_empty(clause_identity_args.len());
449 }
450451// The underlying type can capture any arg that's known to outlive one
452 // of the bound var's positions (they're all instantiated to the same
453 // region at any use site this clause applies to).
454let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(alias_def_id);
455tracing::debug!(?outlived_regions, ?args_known_to_outlive);
456let mut capturable_args = DenseBitSet::new_empty(clause_identity_args.len());
457for &outlived_arg_idx in &outlived_regions {
458let (_, outliving_args) = args_known_to_outlive
459 .iter()
460 .find(|(arg_idx, _)| *arg_idx == outlived_arg_idx)
461 .unwrap();
462 capturable_args.union(outliving_args);
463 }
464 capturable_args
465 }
466// A free region (e.g. `for<a> T::Assoc<'a, 'x>: 'x`, where `'x` is free).
467 // This is effectively the same as `for<'a, 'b> T::Assoc<'a, 'b>: 'b`,
468 // but that only is sound if we either know that the second substituted
469 // lifetime equals `'x` or if we *constrain* that lifetime to be `'x`.
470 //
471 // In either case, something like this doesn't work today:
472 // ```ignore (illustrative)
473 // fn bar<'a, 'b>(a: &'a mut (), b: &'b ()) -> <Foo as MyTrait>::Assoc<'a, 'b> { b }
474 // fn foo<'x>()
475 // where
476 // for<'h> <Foo as MyTrait>::Assoc<'h, 'x>: 'x,
477 // {
478 // let a = &mut ();
479 // let b: &'x () = &();
480 // let val1 = rpit(a, b);
481 // let val2 = rpit(a, b);
482 // drop(val1);
483 // drop(val32);
484 // }
485 // ```
486 // So, we conservatively treat this as giving no restriction on which args can be captured.
487ty::ReEarlyParam(..) => no_restriction(),
488// Don't know that we actually hit this (maybe `ReError`), go ahead and be conservative.
489_ => no_restriction(),
490 }
491}
492493/// Visits free regions in the type that are relevant for liveness computation.
494/// These regions are passed to `OP`.
495///
496/// Specifically, we visit all of the regions of types recursively, except if
497/// the type is an alias, we look at the outlives bounds in the param-env and
498/// the alias's item bounds. Each such bound restricts which of the alias's
499/// args the underlying type could have captured, so only those (capturable)
500/// args are visited. If there are no applicable bounds, we walk through the
501/// alias's (non-bivariant) args structurally.
502pub struct FreeRegionsVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
503pub tcx: TyCtxt<'tcx>,
504pub param_env: ty::ParamEnv<'tcx>,
505pub op: OP,
506}
507508impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for FreeRegionsVisitor<'tcx, OP>
509where
510OP: FnMut(ty::Region<'tcx>),
511{
512fn visit_region(&mut self, r: ty::Region<'tcx>) {
513match r.kind() {
514// ignore bound regions, keep visiting
515ty::ReBound(_, _) => {}
516_ => (self.op)(r),
517 }
518 }
519520{}
#[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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(520u32),
::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/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs:563",
"rustc_trait_selection::traits::outlives_for_liveness",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/7bbda45cb1ec0a378d91959646a8fa904be3192a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs"),
::tracing_core::__macro_support::Option::Some(563u32),
::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")]521fn visit_ty(&mut self, ty: Ty<'tcx>) {
522// We're only interested in types involving regions
523if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
524return;
525 }
526527match *ty.kind() {
528// We can prove that an alias is live two ways:
529 // 1. All the components are live.
530 // 2. There is a known outlives bound or where-clause, and that
531 // region is live.
532 //
533 // We search through the item bounds and where clauses for
534 // either `'static` or a unique outlives region, and if one is
535 // found, we just need to prove that that region is still live.
536 // If one is not found, then we continue to walk through the alias.
537ty::Alias(_, ty::AliasTy { kind, args, .. }) => {
538let tcx = self.tcx;
539let param_env = self.param_env;
540541// For aliases other than opaques, we have to consider two
542 // sources of information to identity potentially-live args:
543 // - Bounds on alias item itself
544 // - Outlives clauses on the current function that apply to the alias
545 //
546 // Each source of information *restricts* the set of potentially-live
547 // args independently: only the args that can be live for *every*
548 // source of information can be actually live, so we take the intersection.
549let def_id = match kind {
550 ty::AliasTyKind::Projection { def_id }
551 | ty::AliasTyKind::Inherent { def_id }
552 | ty::AliasTyKind::Opaque { def_id }
553 | ty::AliasTyKind::Free { def_id } => def_id,
554 };
555let mut capturable = tcx.live_args_for_alias_from_outlives_bounds(kind).clone();
556557for clause in param_env.caller_bounds() {
558let Some(outlives) = clause.as_type_outlives_clause() else {
559continue;
560 };
561 capturable.intersect(&live_args_for_outlives_clause(tcx, def_id, ty, outlives));
562 }
563tracing::debug!(?capturable);
564565// Skip lifetime parameters that are not captured, since they do
566 // not need to be live.
567let variances = tcx.opt_alias_variances(kind);
568for idx in capturable.iter() {
569if variances.map(|variances| variances[idx as usize]) != Some(ty::Bivariant) {
570 args[idx as usize].visit_with(self);
571 }
572 }
573 }
574575_ => ty.super_visit_with(self),
576 }
577 }
578}