Skip to main content

rustc_borrowck/
handle_placeholders.rs

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};
13
14use 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};
24
25/// A set of outlives constraints after rewriting to remove
26/// higher-kinded constraints.
27pub(crate) struct LoweredConstraints<'tcx> {
28    pub(crate) constraint_sccs: Sccs<RegionVid, ConstraintSccIndex>,
29    pub(crate) definitions: Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>,
30    pub(crate) scc_annotations: IndexVec<ConstraintSccIndex, RegionTracker>,
31    pub(crate) outlives_constraints: Frozen<OutlivesConstraintSet<'tcx>>,
32    pub(crate) type_tests: Vec<TypeTest<'tcx>>,
33    pub(crate) liveness_constraints: LivenessValues,
34    pub(crate) universe_causes: FxIndexMap<UniverseIndex, UniverseInfo<'tcx>>,
35    pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
36}
37
38impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
39    pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
40        Self { scc_to_annotation: IndexVec::new(), definitions }
41    }
42}
43
44/// A Visitor for SCC annotation construction.
45pub(crate) struct SccAnnotations<'d, 'tcx, A: scc::Annotation> {
46    pub(crate) scc_to_annotation: IndexVec<ConstraintSccIndex, A>,
47    definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>,
48}
49
50impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
51    fn new(&self, element: RegionVid) -> RegionTracker {
52        RegionTracker::new(element, &self.definitions[element])
53    }
54
55    fn annotate_scc(&mut self, scc: ConstraintSccIndex, annotation: RegionTracker) {
56        let idx = self.scc_to_annotation.push(annotation);
57        if !(idx == scc) { ::core::panicking::panic("assertion failed: idx == scc") };assert!(idx == scc);
58    }
59
60    type Ann = RegionTracker;
61    type SccIdx = ConstraintSccIndex;
62}
63
64#[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
67    max_universe: (UniverseIndex, RegionVid),
68
69    /// The placeholder with the smallest ID
70    min_placeholder: RegionVid,
71
72    /// The placeholder with the largest ID
73    max_placeholder: RegionVid,
74}
75
76impl PlaceholderReachability {
77    /// Merge the reachable placeholders of two graph components.
78    fn merge(&mut self, other: &Self) {
79        self.max_universe = self.max_universe.max(other.max_universe);
80        self.min_placeholder = self.min_placeholder.min(other.min_placeholder);
81        self.max_placeholder = self.max_placeholder.max(other.max_placeholder);
82    }
83}
84
85/// 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>,
90
91    /// 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.
94    max_nameable_universe: (UniverseIndex, RegionVid),
95
96    /// The representative Region Variable Id for this SCC.
97    pub(crate) representative: Representative,
98}
99
100impl RegionTracker {
101    pub(crate) fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self {
102        let reachable_placeholders =
103            if #[allow(non_exhaustive_omitted_patterns)] match definition.origin {
    NllRegionVariableOrigin::Placeholder(_) => true,
    _ => false,
}matches!(definition.origin, NllRegionVariableOrigin::Placeholder(_)) {
104                Some(PlaceholderReachability {
105                    max_universe: (definition.universe, rvid),
106                    min_placeholder: rvid,
107                    max_placeholder: rvid,
108                })
109            } else {
110                None
111            };
112
113        Self {
114            reachable_placeholders,
115            max_nameable_universe: (definition.universe, rvid),
116            representative: Representative::new(rvid, definition),
117        }
118    }
119
120    /// 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)`
123    pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
124        self.max_nameable_universe.0
125    }
126
127    pub(crate) fn max_placeholder_universe_reached(self) -> UniverseIndex {
128        self.reachable_placeholders.map(|pls| pls.max_universe.0).unwrap_or(UniverseIndex::ROOT)
129    }
130
131    /// Can all reachable placeholders be named from `from`?
132    /// True vacuously in case no placeholders were reached.
133    fn placeholders_can_be_named_by(&self, from: UniverseIndex) -> bool {
134        self.reachable_placeholders.is_none_or(|pls| from.can_name(pls.max_universe.0))
135    }
136
137    /// Determine if we can name all the placeholders in `other`.
138    pub(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.
142        self.max_nameable_universe().can_name(other.max_nameable_universe())
143            || other.placeholders_can_be_named_by(self.max_nameable_universe.0)
144    }
145
146    /// If this SCC reaches a placeholder it can't name, return it.
147    fn unnameable_placeholder(&self) -> Option<(UniverseIndex, RegionVid)> {
148        self.reachable_placeholders
149            .filter(|pls| !self.max_nameable_universe().can_name(pls.max_universe.0))
150            .map(|pls| pls.max_universe)
151    }
152}
153
154impl scc::Annotation for RegionTracker {
155    fn 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);
157        self.representative = self.representative.min(other.representative);
158        self.update_reachable(other);
159    }
160
161    fn update_reachable(&mut self, other: &Self) {
162        self.max_nameable_universe = self.max_nameable_universe.min(other.max_nameable_universe);
163        match (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}
170
171/// 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) {
178    let 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.
182    let mut definitions = IndexVec::with_capacity(var_infos.len());
183    let mut has_placeholders = false;
184
185    for info in var_infos.iter() {
186        let origin = match info.origin {
187            RegionVariableOrigin::Nll(origin) => origin,
188            _ => NllRegionVariableOrigin::Existential { name: None },
189        };
190
191        let definition = RegionDefinition { origin, universe: info.universe, external_name: None };
192
193        has_placeholders |= #[allow(non_exhaustive_omitted_patterns)] match origin {
    NllRegionVariableOrigin::Placeholder(_) => true,
    _ => false,
}matches!(origin, NllRegionVariableOrigin::Placeholder(_));
194        definitions.push(definition);
195    }
196
197    // 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.
199    for (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}
205
206/// 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> {
239    let universal_regions = &universal_region_relations.universal_regions;
240    let (definitions, has_placeholders) = region_definitions(infcx, universal_regions);
241
242    let MirTypeckRegionConstraints {
243        placeholder_indices,
244        placeholder_index_to_region: _,
245        liveness_constraints,
246        mut outlives_constraints,
247        universe_causes,
248        type_tests,
249    } = constraints;
250
251    let fr_static = universal_regions.fr_static;
252    let compute_sccs =
253        |constraints: &OutlivesConstraintSet<'tcx>,
254         annotations: &mut SccAnnotations<'_, 'tcx, RegionTracker>| {
255            ConstraintSccs::new_with_annotation(
256                &constraints.graph(definitions.len()).region_graph(constraints, fr_static),
257                annotations,
258            )
259        };
260
261    let mut scc_annotations = SccAnnotations::init(&definitions);
262    let constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations);
263
264    // 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.
267    if !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!");
269
270        return LoweredConstraints {
271            type_tests,
272            constraint_sccs,
273            scc_annotations: scc_annotations.scc_to_annotation,
274            definitions,
275            outlives_constraints: Frozen::freeze(outlives_constraints),
276            liveness_constraints,
277            universe_causes,
278            placeholder_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!");
282
283    let added_constraints = rewrite_placeholder_outlives(
284        &constraint_sccs,
285        &scc_annotations,
286        fr_static,
287        &mut outlives_constraints,
288    );
289
290    let (constraint_sccs, scc_annotations) = if added_constraints {
291        let mut annotations = SccAnnotations::init(&definitions);
292
293        // 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    };
303
304    LoweredConstraints {
305        constraint_sccs,
306        definitions,
307        scc_annotations,
308        outlives_constraints: Frozen::freeze(outlives_constraints),
309        type_tests,
310        liveness_constraints,
311        universe_causes,
312        placeholder_indices,
313    }
314}
315
316pub(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.
324    let mut added_constraints = false;
325
326    let annotations = &annotations.scc_to_annotation;
327
328    for scc in sccs.all_sccs() {
329        // No point in adding 'static: 'static!
330        // This micro-optimisation makes somewhat sense
331        // because static outlives *everything*.
332        if scc == sccs.scc(fr_static) {
333            continue;
334        }
335
336        let annotation = annotations[scc];
337
338        let Some((max_u, max_u_rvid)) = annotation.unnameable_placeholder() else {
339            continue;
340        };
341
342        {
    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        );
346
347        // 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.
355        let 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!
357
358            // The SCC's representative is not nameable from some region
359            // that ends up in the SCC.
360            let 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.
368            max_u_rvid
369        };
370
371        // FIXME: if we can extract a useful blame span here, future error
372        // reporting and constraint search can be simplified.
373
374        added_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    }
385    added_constraints
386}