1//! Logic for lowering higher-kinded outlives constraints
2//! (with placeholders and universes) and turn them into regular
3//! outlives constraints.
4use rustc_data_structures::frozen::Frozen;
5use rustc_data_structures::fx::FxIndexMap;
6use rustc_data_structures::graph::scc;
7use rustc_data_structures::graph::scc::Sccs;
8use rustc_index::IndexVec;
9use rustc_infer::infer::RegionVariableOrigin;
10use rustc_middle::mir::ConstraintCategory;
11use rustc_middle::ty::{RegionVid, UniverseIndex};
12use tracing::{debug, trace};
1314use crate::constraints::{ConstraintSccIndex, OutlivesConstraintSet};
15use crate::consumers::OutlivesConstraint;
16use crate::diagnostics::UniverseInfo;
17use crate::region_infer::values::{LivenessValues, PlaceholderIndices};
18use crate::region_infer::{ConstraintSccs, RegionDefinition, Representative, TypeTest};
19use crate::ty::VarianceDiagInfo;
20use crate::type_check::free_region_relations::UniversalRegionRelations;
21use crate::type_check::{Locations, MirTypeckRegionConstraints};
22use crate::universal_regions::UniversalRegions;
23use crate::{BorrowckInferCtxt, NllRegionVariableOrigin};
2425/// A set of outlives constraints after rewriting to remove
26/// higher-kinded constraints.
27pub(crate) struct LoweredConstraints<'tcx> {
28pub(crate) constraint_sccs: Sccs<RegionVid, ConstraintSccIndex>,
29pub(crate) definitions: Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>,
30pub(crate) scc_annotations: IndexVec<ConstraintSccIndex, RegionTracker>,
31pub(crate) outlives_constraints: Frozen<OutlivesConstraintSet<'tcx>>,
32pub(crate) type_tests: Vec<TypeTest<'tcx>>,
33pub(crate) liveness_constraints: LivenessValues,
34pub(crate) universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>,
35pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
36}
3738impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
39pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
40Self { scc_to_annotation: IndexVec::new(), definitions }
41 }
42}
4344/// A Visitor for SCC annotation construction.
45pub(crate) struct SccAnnotations<'d, 'tcx, A: scc::Annotation> {
46pub(crate) scc_to_annotation: IndexVec<ConstraintSccIndex, A>,
47 definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>,
48}
4950impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
51fn new(&self, element: RegionVid) -> RegionTracker {
52RegionTracker::new(element, &self.definitions[element])
53 }
5455fn annotate_scc(&mut self, scc: ConstraintSccIndex, annotation: RegionTracker) {
56let idx = self.scc_to_annotation.push(annotation);
57if !(idx == scc) { ::core::panicking::panic("assertion failed: idx == scc") };assert!(idx == scc);
58 }
5960type Ann = RegionTracker;
61type SccIdx = ConstraintSccIndex;
62}
6364#[derive(#[automatically_derived]
impl ::core::marker::Copy for PlaceholderReachability { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for PlaceholderReachability {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"PlaceholderReachability", "max_universe", &self.max_universe,
"min_placeholder", &self.min_placeholder, "max_placeholder",
&&self.max_placeholder)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for PlaceholderReachability {
#[inline]
fn clone(&self) -> PlaceholderReachability {
let _: ::core::clone::AssertParamIsClone<(UniverseIndex, RegionVid)>;
let _: ::core::clone::AssertParamIsClone<RegionVid>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PlaceholderReachability {
#[inline]
fn eq(&self, other: &PlaceholderReachability) -> bool {
self.max_universe == other.max_universe &&
self.min_placeholder == other.min_placeholder &&
self.max_placeholder == other.max_placeholder
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PlaceholderReachability {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<(UniverseIndex, RegionVid)>;
let _: ::core::cmp::AssertParamIsEq<RegionVid>;
}
}Eq)]
65struct PlaceholderReachability {
66/// The largest-universed placeholder we can reach
67max_universe: (UniverseIndex, RegionVid),
6869/// The placeholder with the smallest ID
70min_placeholder: RegionVid,
7172/// The placeholder with the largest ID
73max_placeholder: RegionVid,
74}
7576impl PlaceholderReachability {
77/// Merge the reachable placeholders of two graph components.
78fn merge(&mut self, other: &Self) {
79self.max_universe = self.max_universe.max(other.max_universe);
80self.min_placeholder = self.min_placeholder.min(other.min_placeholder);
81self.max_placeholder = self.max_placeholder.max(other.max_placeholder);
82 }
83}
8485/// An annotation for region graph SCCs that tracks
86/// the values of its elements. This annotates a single SCC.
87#[derive(#[automatically_derived]
impl ::core::marker::Copy for RegionTracker { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for RegionTracker {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "RegionTracker",
"reachable_placeholders", &self.reachable_placeholders,
"max_nameable_universe", &self.max_nameable_universe,
"representative", &&self.representative)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for RegionTracker {
#[inline]
fn clone(&self) -> RegionTracker {
let _:
::core::clone::AssertParamIsClone<Option<PlaceholderReachability>>;
let _: ::core::clone::AssertParamIsClone<(UniverseIndex, RegionVid)>;
let _: ::core::clone::AssertParamIsClone<Representative>;
*self
}
}Clone)]
88pub(crate) struct RegionTracker {
89 reachable_placeholders: Option<PlaceholderReachability>,
9091/// The largest universe nameable from this SCC.
92 /// It is the smallest nameable universes of all
93 /// existential regions reachable from it. Small Rvids are preferred.
94max_nameable_universe: (UniverseIndex, RegionVid),
9596/// The representative Region Variable Id for this SCC.
97pub(crate) representative: Representative,
98}
99100impl RegionTracker {
101pub(crate) fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self {
102let reachable_placeholders =
103if #[allow(non_exhaustive_omitted_patterns)] match definition.origin {
NllRegionVariableOrigin::Placeholder(_) => true,
_ => false,
}matches!(definition.origin, NllRegionVariableOrigin::Placeholder(_)) {
104Some(PlaceholderReachability {
105 max_universe: (definition.universe, rvid),
106 min_placeholder: rvid,
107 max_placeholder: rvid,
108 })
109 } else {
110None111 };
112113Self {
114reachable_placeholders,
115 max_nameable_universe: (definition.universe, rvid),
116 representative: Representative::new(rvid, definition),
117 }
118 }
119120/// The largest universe this SCC can name. It's the smallest
121 /// largest nameable universe of any reachable region, or
122 /// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
123pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
124self.max_nameable_universe.0
125}
126127pub(crate) fn max_placeholder_universe_reached(self) -> UniverseIndex {
128self.reachable_placeholders.map(|pls| pls.max_universe.0).unwrap_or(UniverseIndex::ROOT)
129 }
130131/// Can all reachable placeholders be named from `from`?
132 /// True vacuously in case no placeholders were reached.
133fn placeholders_can_be_named_by(&self, from: UniverseIndex) -> bool {
134self.reachable_placeholders.is_none_or(|pls| from.can_name(pls.max_universe.0))
135 }
136137/// Determine if we can name all the placeholders in `other`.
138pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool {
139// HACK: We first check whether we can name the highest existential universe
140 // of `other`. This only exists to avoid errors in case that scc already
141 // depends on a placeholder it cannot name itself.
142self.max_nameable_universe().can_name(other.max_nameable_universe())
143 || other.placeholders_can_be_named_by(self.max_nameable_universe.0)
144 }
145146/// If this SCC reaches a placeholder it can't name, return it.
147fn unnameable_placeholder(&self) -> Option<(UniverseIndex, RegionVid)> {
148self.reachable_placeholders
149 .filter(|pls| !self.max_nameable_universe().can_name(pls.max_universe.0))
150 .map(|pls| pls.max_universe)
151 }
152}
153154impl scc::Annotationfor RegionTracker {
155fn update_scc(&mut self, other: &Self) {
156{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:156",
"rustc_borrowck::handle_placeholders",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(156u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("{0:?} << {1:?}",
self.representative, other.representative) as &dyn Value))])
});
} else { ; }
};trace!("{:?} << {:?}", self.representative, other.representative);
157self.representative = self.representative.min(other.representative);
158self.update_reachable(other);
159 }
160161fn update_reachable(&mut self, other: &Self) {
162self.max_nameable_universe = self.max_nameable_universe.min(other.max_nameable_universe);
163match (self.reachable_placeholders.as_mut(), other.reachable_placeholders.as_ref()) {
164 (None, None) | (Some(_), None) => (),
165 (None, Some(theirs)) => self.reachable_placeholders = Some(*theirs),
166 (Some(ours), Some(theirs)) => ours.merge(theirs),
167 };
168 }
169}
170171/// Determines if the region variable definitions contain
172/// placeholders, and compute them for later use.
173// FIXME: This is also used by opaque type handling. Move it to a separate file.
174pub(super) fn region_definitions<'tcx>(
175 infcx: &BorrowckInferCtxt<'tcx>,
176 universal_regions: &UniversalRegions<'tcx>,
177) -> (Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>, bool) {
178let var_infos = infcx.get_region_var_infos();
179// Create a RegionDefinition for each inference variable. This happens here because
180 // it allows us to sneak in a cheap check for placeholders. Otherwise, its proper home
181 // is in `RegionInferenceContext::new()`, probably.
182let mut definitions = IndexVec::with_capacity(var_infos.len());
183let mut has_placeholders = false;
184185for info in var_infos.iter() {
186let origin = match info.origin {
187 RegionVariableOrigin::Nll(origin) => origin,
188_ => NllRegionVariableOrigin::Existential { name: None },
189 };
190191let definition = RegionDefinition { origin, universe: info.universe, external_name: None };
192193 has_placeholders |= #[allow(non_exhaustive_omitted_patterns)] match origin {
NllRegionVariableOrigin::Placeholder(_) => true,
_ => false,
}matches!(origin, NllRegionVariableOrigin::Placeholder(_));
194 definitions.push(definition);
195 }
196197// Add external names from universal regions in fun function definitions.
198 // FIXME: this two-step method is annoying, but I don't know how to avoid it.
199for (external_name, variable) in universal_regions.named_universal_regions_iter() {
200{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:200",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(200u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("region {0:?} has external name {1:?}",
variable, external_name) as &dyn Value))])
});
} else { ; }
};debug!("region {:?} has external name {:?}", variable, external_name);
201 definitions[variable].external_name = Some(external_name);
202 }
203 (Frozen::freeze(definitions), has_placeholders)
204}
205206/// This method handles placeholders by rewriting the constraint
207/// graph. For each strongly connected component in the constraint
208/// graph such that there is a series of constraints
209/// A: B: C: ... : X where
210/// A contains a placeholder whose universe cannot be named by X,
211/// add a constraint that A: 'static. This is a safe upper bound
212/// in the face of borrow checker/trait solver limitations that will
213/// eventually go away.
214///
215/// For a more precise definition, see the documentation for
216/// [`RegionTracker`] and its methods!
217///
218/// This edge case used to be handled during constraint propagation.
219/// It was rewritten as part of the Polonius project with the goal of moving
220/// higher-kindedness concerns out of the path of the borrow checker,
221/// for two reasons:
222///
223/// 1. Implementing Polonius is difficult enough without also
224/// handling them.
225/// 2. The long-term goal is to handle higher-kinded concerns
226/// in the trait solver, where they belong. This avoids
227/// logic duplication and allows future trait solvers
228/// to compute better bounds than for example our
229/// "must outlive 'static" here.
230///
231/// This code is a stop-gap measure in preparation for the future trait solver.
232///
233/// Every constraint added by this method is an internal `IllegalUniverse` constraint.
234pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>(
235 constraints: MirTypeckRegionConstraints<'tcx>,
236 universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
237 infcx: &BorrowckInferCtxt<'tcx>,
238) -> LoweredConstraints<'tcx> {
239let universal_regions = &universal_region_relations.universal_regions;
240let (definitions, has_placeholders) = region_definitions(infcx, universal_regions);
241242let MirTypeckRegionConstraints {
243 placeholder_indices,
244 placeholder_index_to_region: _,
245 liveness_constraints,
246mut outlives_constraints,
247 universe_causes,
248 type_tests,
249 } = constraints;
250251let fr_static = universal_regions.fr_static;
252let compute_sccs =
253 |constraints: &OutlivesConstraintSet<'tcx>,
254 annotations: &mut SccAnnotations<'_, 'tcx, RegionTracker>| {
255ConstraintSccs::new_with_annotation(
256&constraints.graph(definitions.len()).region_graph(constraints, fr_static),
257annotations,
258 )
259 };
260261let mut scc_annotations = SccAnnotations::init(&definitions);
262let constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);
263264// This code structure is a bit convoluted because it allows for a planned
265 // future change where the early return here has a different type of annotation
266 // that does much less work.
267if !has_placeholders {
268{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:268",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(268u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("No placeholder regions found; skipping rewriting logic!")
as &dyn Value))])
});
} else { ; }
};debug!("No placeholder regions found; skipping rewriting logic!");
269270return LoweredConstraints {
271type_tests,
272constraint_sccs,
273 scc_annotations: scc_annotations.scc_to_annotation,
274definitions,
275 outlives_constraints: Frozen::freeze(outlives_constraints),
276liveness_constraints,
277universe_causes,
278placeholder_indices,
279 };
280 }
281{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:281",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(281u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("Placeholders present; activating placeholder handling logic!")
as &dyn Value))])
});
} else { ; }
};debug!("Placeholders present; activating placeholder handling logic!");
282283let added_constraints = rewrite_placeholder_outlives(
284&constraint_sccs,
285&scc_annotations,
286fr_static,
287&mut outlives_constraints,
288 );
289290let (constraint_sccs, scc_annotations) = if added_constraints {
291let mut annotations = SccAnnotations::init(&definitions);
292293// We changed the constraint set and so must recompute SCCs.
294 // Optimisation opportunity: if we can add them incrementally (and that's
295 // possible because edges to 'static always only merge SCCs into 'static),
296 // we would potentially save a lot of work here.
297(compute_sccs(&outlives_constraints, &mut annotations), annotations.scc_to_annotation)
298 } else {
299// If we didn't add any back-edges; no more work needs doing
300{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:300",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(300u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("No constraints rewritten!")
as &dyn Value))])
});
} else { ; }
};debug!("No constraints rewritten!");
301 (constraint_sccs, scc_annotations.scc_to_annotation)
302 };
303304LoweredConstraints {
305constraint_sccs,
306definitions,
307scc_annotations,
308 outlives_constraints: Frozen::freeze(outlives_constraints),
309type_tests,
310liveness_constraints,
311universe_causes,
312placeholder_indices,
313 }
314}
315316pub(crate) fn rewrite_placeholder_outlives<'tcx>(
317 sccs: &Sccs<RegionVid, ConstraintSccIndex>,
318 annotations: &SccAnnotations<'_, '_, RegionTracker>,
319 fr_static: RegionVid,
320 outlives_constraints: &mut OutlivesConstraintSet<'tcx>,
321) -> bool {
322// Changed to `true` if we added any constraints and need to
323 // recompute SCCs.
324let mut added_constraints = false;
325326let annotations = &annotations.scc_to_annotation;
327328for scc in sccs.all_sccs() {
329// No point in adding 'static: 'static!
330 // This micro-optimisation makes somewhat sense
331 // because static outlives *everything*.
332if scc == sccs.scc(fr_static) {
333continue;
334 }
335336let annotation = annotations[scc];
337338let Some((max_u, max_u_rvid)) = annotation.unnameable_placeholder() else {
339continue;
340 };
341342{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:342",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(342u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("Placeholder universe {1:?} is too large for its SCC, represented by {0:?}",
annotation.representative, max_u) as &dyn Value))])
});
} else { ; }
};debug!(
343"Placeholder universe {max_u:?} is too large for its SCC, represented by {:?}",
344 annotation.representative
345 );
346347// We only add one `r: 'static` constraint per SCC, where `r` is the SCC representative.
348 // That constraint is annotated with some placeholder `unnameable` where
349 // `unnameable` is unnameable from `r` and there is a path in the constraint graph
350 // between them.
351 //
352 // There is one exception; if some other region in this SCC can't name `'r`, then
353 // we pick the region with the smallest universe in the SCC, so that a path can
354 // always start in `'r` to find a motivation that isn't cyclic.
355let blame_to = if annotation.representative.rvid() == max_u_rvid {
356// Assertion: the region that lowered our universe is an existential one and we are a placeholder!
357358 // The SCC's representative is not nameable from some region
359 // that ends up in the SCC.
360let small_universed_rvid = annotation.max_nameable_universe.1;
361{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_borrowck/src/handle_placeholders.rs:361",
"rustc_borrowck::handle_placeholders",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/handle_placeholders.rs"),
::tracing_core::__macro_support::Option::Some(361u32),
::tracing_core::__macro_support::Option::Some("rustc_borrowck::handle_placeholders"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("{1:?} lowered our universe to {0:?}",
annotation.max_nameable_universe(), small_universed_rvid) as
&dyn Value))])
});
} else { ; }
};debug!(
362"{small_universed_rvid:?} lowered our universe to {:?}",
363 annotation.max_nameable_universe()
364 );
365 small_universed_rvid
366 } else {
367// `max_u_rvid` is not nameable by the SCC's representative.
368max_u_rvid
369 };
370371// FIXME: if we can extract a useful blame span here, future error
372 // reporting and constraint search can be simplified.
373374added_constraints = true;
375 outlives_constraints.push(OutlivesConstraint {
376 sup: annotation.representative.rvid(),
377 sub: fr_static,
378 category: ConstraintCategory::OutlivesUnnameablePlaceholder(blame_to),
379 locations: Locations::All(rustc_span::DUMMY_SP),
380 span: rustc_span::DUMMY_SP,
381 variance_info: VarianceDiagInfo::None,
382 from_closure: false,
383 });
384 }
385added_constraints386}