Skip to main content

rustc_borrowck/region_infer/
mod.rs

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