Skip to main content

rustc_borrowck/region_infer/
mod.rs

1use std::fmt;
2
3pub(crate) use region_context::*;
4use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
5use rustc_data_structures::graph::scc::Sccs;
6use rustc_hir::def_id::CRATE_DEF_ID;
7use rustc_index::IndexVec;
8use rustc_infer::infer::NllRegionVariableOrigin;
9use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
10use rustc_middle::mir::{ConstraintCategory, Local, Location};
11use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
12use rustc_middle::ty::{self, RegionVid, TyCtxt};
13use rustc_span::Span;
14use tracing::{Level, debug, enabled, instrument};
15
16use crate::BorrowckInferCtxt;
17use crate::constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet};
18use crate::handle_placeholders::RegionTracker;
19use crate::type_check::Locations;
20
21mod dump_mir;
22mod graphviz;
23pub(crate) mod opaque_types;
24mod region_context;
25mod reverse_sccs;
26
27pub(crate) mod values;
28
29/// The representative region variable for an SCC, tagged by its origin.
30/// We prefer placeholders over existentially quantified variables, otherwise
31/// it's the one with the smallest Region Variable ID. In other words,
32/// the order of this enumeration really matters!
33#[derive(#[automatically_derived]
impl ::core::marker::Copy for Representative { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Representative {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::FreeRegion(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FreeRegion", &__self_0),
            Self::Placeholder(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Placeholder", &__self_0),
            Self::Existential(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Existential", &__self_0),
        }
    }
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Representative { }
#[automatically_derived]
impl ::core::clone::Clone for Representative {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<RegionVid>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Representative { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Representative {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::FreeRegion(__self_0), Self::FreeRegion(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Placeholder(__self_0), Self::Placeholder(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::Existential(__self_0), Self::Existential(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Representative {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Representative {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<RegionVid>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Representative {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        match (self, other) {
            (Self::FreeRegion(__self_0), Self::FreeRegion(__arg1_0)) =>
                ::core::cmp::Ord::cmp(__self_0, __arg1_0),
            (Self::Placeholder(__self_0), Self::Placeholder(__arg1_0)) =>
                ::core::cmp::Ord::cmp(__self_0, __arg1_0),
            (Self::Existential(__self_0), Self::Existential(__arg1_0)) =>
                ::core::cmp::Ord::cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::Ord::cmp(&::core::intrinsics::discriminant_value(self),
                    &::core::intrinsics::discriminant_value(other)),
        }
    }
}Ord)]
34pub(crate) enum Representative {
35    FreeRegion(RegionVid),
36    Placeholder(RegionVid),
37    Existential(RegionVid),
38}
39
40impl Representative {
41    pub(crate) fn rvid(self) -> RegionVid {
42        match self {
43            Representative::FreeRegion(region_vid)
44            | Representative::Placeholder(region_vid)
45            | Representative::Existential(region_vid) => region_vid,
46        }
47    }
48
49    pub(crate) fn new(r: RegionVid, definition: &RegionDefinition<'_>) -> Self {
50        match definition.origin {
51            NllRegionVariableOrigin::FreeRegion => Representative::FreeRegion(r),
52            NllRegionVariableOrigin::Placeholder(_) => Representative::Placeholder(r),
53            NllRegionVariableOrigin::Existential { .. } => Representative::Existential(r),
54        }
55    }
56}
57
58pub(crate) type ConstraintSccs = Sccs<RegionVid, ConstraintSccIndex>;
59
60#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for RegionDefinition<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "RegionDefinition", "origin", &self.origin, "universe",
            &self.universe, "external_name", &&self.external_name)
    }
}Debug)]
61pub(crate) struct RegionDefinition<'tcx> {
62    /// What kind of variable is this -- a free region? existential
63    /// variable? etc. (See the `NllRegionVariableOrigin` for more
64    /// info.)
65    pub(crate) origin: NllRegionVariableOrigin<'tcx>,
66
67    /// Which universe is this region variable defined in? This is
68    /// most often `ty::UniverseIndex::ROOT`, but when we encounter
69    /// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
70    /// the variable for `'a` in a fresh universe that extends ROOT.
71    pub(crate) universe: ty::UniverseIndex,
72
73    /// If this is 'static or an early-bound region, then this is
74    /// `Some(X)` where `X` is the name of the region.
75    pub(crate) external_name: Option<ty::Region<'tcx>>,
76}
77
78/// N.B., the variants in `Cause` are intentionally ordered. Lower
79/// values are preferred when it comes to error messages. Do not
80/// reorder willy nilly.
81#[derive(#[automatically_derived]
impl ::core::marker::Copy for Cause { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Cause { }
#[automatically_derived]
impl ::core::clone::Clone for Cause {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Local>;
        let _: ::core::clone::AssertParamIsClone<Location>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Cause {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::LiveVar(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "LiveVar", __self_0, &__self_1),
            Self::DropVar(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_tuple_field2_finish(f,
                    "DropVar", __self_0, &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialOrd for Cause {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Cause {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        match (self, other) {
            (Self::LiveVar(__self_0, __self_1),
                Self::LiveVar(__arg1_0, __arg1_1)) =>
                match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(__self_1, __arg1_1),
                    cmp => cmp,
                },
            (Self::DropVar(__self_0, __self_1),
                Self::DropVar(__arg1_0, __arg1_1)) =>
                match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(__self_1, __arg1_1),
                    cmp => cmp,
                },
            _ =>
                ::core::cmp::Ord::cmp(&::core::intrinsics::discriminant_value(self),
                    &::core::intrinsics::discriminant_value(other)),
        }
    }
}Ord, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Cause { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Cause {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::LiveVar(__self_0, __self_1),
                    Self::LiveVar(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (Self::DropVar(__self_0, __self_1),
                    Self::DropVar(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Cause {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Local>;
        let _: ::core::cmp::AssertParamIsEq<Location>;
    }
}Eq)]
82pub(crate) enum Cause {
83    /// point inserted because Local was live at the given Location
84    LiveVar(Local, Location),
85
86    /// point inserted because Local was dropped at the given Location
87    DropVar(Local, Location),
88}
89
90/// A "type test" corresponds to an outlives constraint between a type
91/// and a lifetime, like `T: 'x` or `<T as Foo>::Bar: 'x`. They are
92/// translated from the `Verify` region constraints in the ordinary
93/// inference context.
94///
95/// These sorts of constraints are handled differently than ordinary
96/// constraints, at least at present. During type checking, the
97/// `InferCtxt::process_registered_region_obligations` method will
98/// attempt to convert a type test like `T: 'x` into an ordinary
99/// outlives constraint when possible (for example, `&'a T: 'b` will
100/// be converted into `'a: 'b` and registered as a `Constraint`).
101///
102/// In some cases, however, there are outlives relationships that are
103/// not converted into a region constraint, but rather into one of
104/// these "type tests". The distinction is that a type test does not
105/// influence the inference result, but instead just examines the
106/// values that we ultimately inferred for each region variable and
107/// checks that they meet certain extra criteria. If not, an error
108/// can be issued.
109///
110/// One reason for this is that these type tests typically boil down
111/// to a check like `'a: 'x` where `'a` is a universally quantified
112/// region -- and therefore not one whose value is really meant to be
113/// *inferred*, precisely (this is not always the case: one can have a
114/// type test like `<Foo as Trait<'?0>>::Bar: 'x`, where `'?0` is an
115/// inference variable). Another reason is that these type tests can
116/// involve *disjunction* -- that is, they can be satisfied in more
117/// than one way.
118///
119/// For more information about this translation, see
120/// `InferCtxt::process_registered_region_obligations` and
121/// `InferCtxt::type_must_outlive` in `rustc_infer::infer::InferCtxt`.
122#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for TypeTest<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        TypeTest {
            generic_kind: ::core::clone::Clone::clone(&self.generic_kind),
            lower_bound: ::core::clone::Clone::clone(&self.lower_bound),
            span: ::core::clone::Clone::clone(&self.span),
            verify_bound: ::core::clone::Clone::clone(&self.verify_bound),
        }
    }
}Clone)]
123pub(crate) struct TypeTest<'tcx> {
124    /// The type `T` that must outlive the region.
125    pub generic_kind: GenericKind<'tcx>,
126
127    /// The region `'x` that the type must outlive.
128    pub lower_bound: RegionVid,
129
130    /// The span to blame.
131    pub span: Span,
132
133    /// A test which, if met by the region `'x`, proves that this type
134    /// constraint is satisfied.
135    pub verify_bound: VerifyBound<'tcx>,
136}
137
138impl fmt::Debug for TypeTest<'_> {
139    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140        fn fmt_bound(
141            f: &mut fmt::Formatter<'_>,
142            generic_kind: GenericKind<'_>,
143            lower: RegionVid,
144            bound: &VerifyBound<'_>,
145        ) -> fmt::Result {
146            let fmt_bounds =
147                |f: &mut fmt::Formatter<'_>, bounds: &[VerifyBound<'_>]| -> fmt::Result {
148                    let mut it = bounds.iter().peekable();
149                    while let Some(bound) = it.next() {
150                        fmt_bound(f, generic_kind, lower, bound)?;
151                        if it.peek().is_some() {
152                            f.write_fmt(format_args!(", "))write!(f, ", ")?
153                        }
154                    }
155                    Ok(())
156                };
157            match bound {
158                VerifyBound::IfEq(binder) => f.write_fmt(format_args!("{0:?} == {1:?}", generic_kind, binder))write!(f, "{:?} == {:?}", generic_kind, binder),
159                VerifyBound::OutlivedBy(region) => f.write_fmt(format_args!("{0:?}: {1:?}", region, lower))write!(f, "{region:?}: {lower:?}"),
160                VerifyBound::AnyBound(verify_bounds) => {
161                    f.write_fmt(format_args!("Any["))write!(f, "Any[")?;
162                    fmt_bounds(f, verify_bounds)?;
163                    f.write_fmt(format_args!("]"))write!(f, "]")
164                }
165                VerifyBound::AllBounds(verify_bounds) => {
166                    f.write_fmt(format_args!("All["))write!(f, "All[")?;
167                    fmt_bounds(f, verify_bounds)?;
168                    f.write_fmt(format_args!("]"))write!(f, "]")
169                }
170                VerifyBound::IsEmpty => f.write_fmt(format_args!("Empty({0:?})", lower))write!(f, "Empty({lower:?})"),
171            }
172        }
173        f.write_fmt(format_args!("TypeTest from {0:?}[", self.span))write!(f, "TypeTest from {:?}[", self.span)?;
174        fmt_bound(f, self.generic_kind, self.lower_bound, &self.verify_bound)?;
175        f.write_fmt(format_args!("] ⊢ {0:?}: {1:?}", self.generic_kind,
        self.lower_bound))write!(f, "] ⊢ {:?}: {:?}", self.generic_kind, self.lower_bound)
176    }
177}
178
179/// When we have an unmet lifetime constraint, we try to propagate it outward (e.g. to a closure
180/// environment). If we can't, it is an error.
181#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for RegionRelationCheckResult { }
#[automatically_derived]
impl ::core::clone::Clone for RegionRelationCheckResult {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for RegionRelationCheckResult { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for RegionRelationCheckResult {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                RegionRelationCheckResult::Ok => "Ok",
                RegionRelationCheckResult::Propagated => "Propagated",
                RegionRelationCheckResult::Error => "Error",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for RegionRelationCheckResult { }Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for RegionRelationCheckResult { }
#[automatically_derived]
impl ::core::cmp::PartialEq for RegionRelationCheckResult {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq)]
182enum RegionRelationCheckResult {
183    Ok,
184    Propagated,
185    Error,
186}
187
188#[derive(#[automatically_derived]
impl<'a, 'tcx> ::core::clone::Clone for Trace<'a, 'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::StartRegion => Trace::StartRegion,
            Self::FromGraph(__self_0) =>
                Trace::FromGraph(::core::clone::Clone::clone(__self_0)),
            Self::FromStatic(__self_0) =>
                Trace::FromStatic(::core::clone::Clone::clone(__self_0)),
            Self::NotVisited => Trace::NotVisited,
        }
    }
}Clone, #[automatically_derived]
impl<'a, 'tcx> ::core::marker::StructuralPartialEq for Trace<'a, 'tcx> { }
#[automatically_derived]
impl<'a, 'tcx> ::core::cmp::PartialEq for Trace<'a, 'tcx> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::FromGraph(__self_0), Self::FromGraph(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Self::FromStatic(__self_0), Self::FromStatic(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl<'a, 'tcx> ::core::cmp::Eq for Trace<'a, 'tcx> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<&'a OutlivesConstraint<'tcx>>;
        let _: ::core::cmp::AssertParamIsEq<RegionVid>;
    }
}Eq, #[automatically_derived]
impl<'a, 'tcx> ::core::fmt::Debug for Trace<'a, 'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::StartRegion =>
                ::core::fmt::Formatter::write_str(f, "StartRegion"),
            Self::FromGraph(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FromGraph", &__self_0),
            Self::FromStatic(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FromStatic", &__self_0),
            Self::NotVisited =>
                ::core::fmt::Formatter::write_str(f, "NotVisited"),
        }
    }
}Debug)]
189enum Trace<'a, 'tcx> {
190    StartRegion,
191    FromGraph(&'a OutlivesConstraint<'tcx>),
192    FromStatic(RegionVid),
193    NotVisited,
194}
195
196{}
#[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("sccs_info",
                                    "rustc_borrowck::region_infer", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(196u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                    ::tracing_core::field::FieldSet::new(&[],
                                        ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::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,
                        &{ meta.fields().value_set_all(&[]) })
                } 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;
        }
        {
            use crate::renumber::RegionCtxt;
            let var_to_origin = infcx.reg_var_to_origin.borrow();
            let mut var_to_origin_sorted =
                var_to_origin.clone().into_iter().collect::<Vec<_>>();
            var_to_origin_sorted.sort_by_key(|vto| vto.0);
            if {
                    if Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("enabled /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs:205",
                                            "rustc_borrowck::region_infer", Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(205u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                            ::tracing_core::field::FieldSet::new(&[],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::HINT.hint())
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let interest = __CALLSITE.interest();
                        if !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest) {
                            let meta = __CALLSITE.metadata();
                            ::tracing::dispatcher::get_default(|current|
                                    current.enabled(meta))
                        } else { false }
                    } else { false }
                } {
                let mut reg_vars_to_origins_str =
                    "region variables to origins:\n".to_string();
                for (reg_var, origin) in var_to_origin_sorted.into_iter() {
                    reg_vars_to_origins_str.push_str(&::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0:?}: {1:?}\n", reg_var,
                                            origin))
                                }));
                }
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs:210",
                                        "rustc_borrowck::region_infer", ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                        ::tracing_core::__macro_support::Option::Some(210u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                        ::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!("{0}",
                                                                    reg_vars_to_origins_str) as &dyn ::tracing::field::Value))])
                            });
                    } else { ; }
                };
            }
            let num_components = sccs.num_sccs();
            let mut components =
                ::alloc::vec::from_elem(FxIndexSet::default(),
                    num_components);
            for (reg_var, scc_idx) in sccs.scc_indices().iter_enumerated() {
                let origin =
                    var_to_origin.get(&reg_var).unwrap_or(&RegionCtxt::Unknown);
                components[scc_idx.as_usize()].insert((reg_var, *origin));
            }
            if {
                    if Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() {
                        use ::tracing::__macro_support::Callsite as _;
                        static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                            {
                                static META: ::tracing::Metadata<'static> =
                                    {
                                        ::tracing_core::metadata::Metadata::new("enabled /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs:221",
                                            "rustc_borrowck::region_infer", Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(221u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                            ::tracing_core::field::FieldSet::new(&[],
                                                ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                            ::tracing::metadata::Kind::HINT.hint())
                                    };
                                ::tracing::callsite::DefaultCallsite::new(&META)
                            };
                        let interest = __CALLSITE.interest();
                        if !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest) {
                            let meta = __CALLSITE.metadata();
                            ::tracing::dispatcher::get_default(|current|
                                    current.enabled(meta))
                        } else { false }
                    } else { false }
                } {
                let mut components_str =
                    "strongly connected components:".to_string();
                for (scc_idx, reg_vars_origins) in
                    components.iter().enumerate() {
                    let regions_info =
                        reg_vars_origins.clone().into_iter().collect::<Vec<_>>();
                    components_str.push_str(&::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0:?}: {1:?},\n)",
                                            ConstraintSccIndex::from_usize(scc_idx), regions_info))
                                }))
                }
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs:231",
                                        "rustc_borrowck::region_infer", ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                        ::tracing_core::__macro_support::Option::Some(231u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                        ::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!("{0}",
                                                                    components_str) as &dyn ::tracing::field::Value))])
                            });
                    } else { ; }
                };
            }
            let components_representatives =
                components.into_iter().enumerate().map(|(scc_idx,
                                region_ctxts)|
                            {
                                let repr =
                                    region_ctxts.into_iter().map(|reg_var_origin|
                                                    reg_var_origin.1).max_by(|x, y|
                                                x.preference_value().cmp(&y.preference_value())).unwrap();
                                (ConstraintSccIndex::from_usize(scc_idx), repr)
                            }).collect::<FxIndexMap<_, _>>();
            let mut scc_node_to_edges = FxIndexMap::default();
            for (scc_idx, repr) in components_representatives.iter() {
                let edge_representatives =
                    sccs.successors(*scc_idx).iter().map(|scc_idx|
                                components_representatives[scc_idx]).collect::<Vec<_>>();
                scc_node_to_edges.insert((scc_idx, repr),
                    edge_representatives);
            }
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs:259",
                                    "rustc_borrowck::region_infer", ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/080cc27146389dbb5c8772c476b1937be9c6110f/compiler/rustc_borrowck/src/region_infer/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(259u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer"),
                                    ::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!("SCC edges {0:#?}",
                                                                scc_node_to_edges) as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
        }
    }
}#[instrument(skip(infcx, sccs), level = "debug")]
197fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
198    use crate::renumber::RegionCtxt;
199
200    let var_to_origin = infcx.reg_var_to_origin.borrow();
201
202    let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>();
203    var_to_origin_sorted.sort_by_key(|vto| vto.0);
204
205    if enabled!(Level::DEBUG) {
206        let mut reg_vars_to_origins_str = "region variables to origins:\n".to_string();
207        for (reg_var, origin) in var_to_origin_sorted.into_iter() {
208            reg_vars_to_origins_str.push_str(&format!("{reg_var:?}: {origin:?}\n"));
209        }
210        debug!("{}", reg_vars_to_origins_str);
211    }
212
213    let num_components = sccs.num_sccs();
214    let mut components = vec![FxIndexSet::default(); num_components];
215
216    for (reg_var, scc_idx) in sccs.scc_indices().iter_enumerated() {
217        let origin = var_to_origin.get(&reg_var).unwrap_or(&RegionCtxt::Unknown);
218        components[scc_idx.as_usize()].insert((reg_var, *origin));
219    }
220
221    if enabled!(Level::DEBUG) {
222        let mut components_str = "strongly connected components:".to_string();
223        for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
224            let regions_info = reg_vars_origins.clone().into_iter().collect::<Vec<_>>();
225            components_str.push_str(&format!(
226                "{:?}: {:?},\n)",
227                ConstraintSccIndex::from_usize(scc_idx),
228                regions_info,
229            ))
230        }
231        debug!("{}", components_str);
232    }
233
234    // calculate the best representative for each component
235    let components_representatives = components
236        .into_iter()
237        .enumerate()
238        .map(|(scc_idx, region_ctxts)| {
239            let repr = region_ctxts
240                .into_iter()
241                .map(|reg_var_origin| reg_var_origin.1)
242                .max_by(|x, y| x.preference_value().cmp(&y.preference_value()))
243                .unwrap();
244
245            (ConstraintSccIndex::from_usize(scc_idx), repr)
246        })
247        .collect::<FxIndexMap<_, _>>();
248
249    let mut scc_node_to_edges = FxIndexMap::default();
250    for (scc_idx, repr) in components_representatives.iter() {
251        let edge_representatives = sccs
252            .successors(*scc_idx)
253            .iter()
254            .map(|scc_idx| components_representatives[scc_idx])
255            .collect::<Vec<_>>();
256        scc_node_to_edges.insert((scc_idx, repr), edge_representatives);
257    }
258
259    debug!("SCC edges {:#?}", scc_node_to_edges);
260}
261
262#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for BestBlame<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        BestBlame {
            path: ::core::clone::Clone::clone(&self.path),
            idx: ::core::clone::Clone::clone(&self.idx),
        }
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for BestBlame<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "BestBlame",
            "path", &self.path, "idx", &&self.idx)
    }
}Debug)]
263pub(crate) struct BestBlame<'tcx> {
264    /// See docs on [`RegionInferenceContextInner::best_blame_constraint`] for what this is.
265    path: Vec<OutlivesConstraint<'tcx>>,
266    /// Index into `path` of the constraint most relevant to report to users.
267    idx: usize,
268}
269
270impl<'tcx> BestBlame<'tcx> {
271    pub(crate) fn to_obligation_cause(&self) -> ObligationCause<'tcx> {
272        // FIXME - determine what we should do if we encounter multiple
273        // `ConstraintCategory::Predicate` constraints. Currently, we just pick the first one.
274        let cause_code = self
275            .path
276            .iter()
277            .find_map(|constraint| {
278                if let ConstraintCategory::Predicate(predicate_span, def_id) = constraint.category {
279                    // We currently do not store the `DefId` in the `ConstraintCategory`
280                    // for performances reasons. The error reporting code used by NLL only
281                    // uses the span, so this doesn't cause any problems at the moment.
282                    Some(ObligationCauseCode::WhereClause(def_id, predicate_span))
283                } else {
284                    None
285                }
286            })
287            .unwrap_or_else(|| ObligationCauseCode::Misc);
288
289        ObligationCause::new(self.constraint().span, CRATE_DEF_ID, cause_code.clone())
290    }
291
292    pub(crate) fn constraint(&self) -> &OutlivesConstraint<'tcx> {
293        &self.path[self.idx]
294    }
295
296    pub(crate) fn path(&self) -> &[OutlivesConstraint<'tcx>] {
297        &self.path
298    }
299}