Skip to main content

rustc_borrowck/diagnostics/
bound_region_errors.rs

1use std::fmt;
2use std::rc::Rc;
3
4use rustc_errors::Diag;
5use rustc_hir::def_id::LocalDefId;
6use rustc_infer::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};
7use rustc_infer::infer::{
8    InferCtxt, RegionResolutionError, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt as _,
9};
10use rustc_infer::traits::ObligationCause;
11use rustc_infer::traits::query::{
12    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpNormalizeGoal,
13    CanonicalTypeOpProvePredicateGoal,
14};
15use rustc_middle::ty::error::TypeError;
16use rustc_middle::ty::{
17    self, RePlaceholder, Region, RegionExt, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex,
18};
19use rustc_span::Span;
20use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
21use rustc_trait_selection::error_reporting::infer::nice_region_error::NiceRegionError;
22use rustc_trait_selection::traits::ObligationCtxt;
23use rustc_trait_selection::traits::query::type_op::ascribe_user_type::type_op_ascribe_user_type_with_span;
24use rustc_trait_selection::traits::query::type_op::prove_predicate::type_op_prove_predicate_with_cause;
25use tracing::{debug, instrument};
26
27use crate::MirBorrowckCtxt;
28use crate::session_diagnostics::{
29    HigherRankedErrorCause, HigherRankedLifetimeError, HigherRankedSubtypeError,
30};
31
32/// What operation a universe was created for.
33#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for UniverseInfo<'tcx> {
    #[inline]
    fn clone(&self) -> UniverseInfo<'tcx> {
        match self {
            UniverseInfo::RelateTys { expected: __self_0, found: __self_1 } =>
                UniverseInfo::RelateTys {
                    expected: ::core::clone::Clone::clone(__self_0),
                    found: ::core::clone::Clone::clone(__self_1),
                },
            UniverseInfo::TypeOp(__self_0) =>
                UniverseInfo::TypeOp(::core::clone::Clone::clone(__self_0)),
            UniverseInfo::Other => UniverseInfo::Other,
        }
    }
}Clone)]
34pub(crate) enum UniverseInfo<'tcx> {
35    /// Relating two types which have binders.
36    RelateTys { expected: Ty<'tcx>, found: Ty<'tcx> },
37    /// Created from performing a `TypeOp`.
38    TypeOp(Rc<dyn TypeOpInfo<'tcx> + 'tcx>),
39    /// Any other reason.
40    Other,
41}
42
43impl<'tcx> UniverseInfo<'tcx> {
44    pub(crate) fn other() -> UniverseInfo<'tcx> {
45        UniverseInfo::Other
46    }
47
48    pub(crate) fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx> {
49        UniverseInfo::RelateTys { expected, found }
50    }
51
52    /// Report an error where an element erroneously made its way into `placeholder`.
53    pub(crate) fn report_erroneous_element(
54        &self,
55        mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
56        placeholder: ty::PlaceholderRegion<'tcx>,
57        error_element: Option<ty::PlaceholderRegion<'tcx>>,
58        cause: ObligationCause<'tcx>,
59    ) {
60        match *self {
61            UniverseInfo::RelateTys { expected, found } => {
62                let err = mbcx.infcx.err_ctxt().report_mismatched_types(
63                    &cause,
64                    mbcx.infcx.param_env,
65                    expected,
66                    found,
67                    TypeError::RegionsPlaceholderMismatch,
68                );
69                mbcx.buffer_error(err);
70            }
71            UniverseInfo::TypeOp(ref type_op_info) => {
72                type_op_info.report_erroneous_element(mbcx, placeholder, error_element, cause);
73            }
74            UniverseInfo::Other => {
75                // FIXME: This error message isn't great, but it doesn't show
76                // up in the existing UI tests. Consider investigating this
77                // some more.
78                mbcx.buffer_error(
79                    mbcx.dcx().create_err(HigherRankedSubtypeError { span: cause.span }),
80                );
81            }
82        }
83    }
84}
85
86pub(crate) trait ToUniverseInfo<'tcx> {
87    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx>;
88}
89
90impl<'tcx> ToUniverseInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
91    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
92        UniverseInfo::TypeOp(Rc::new(crate::type_check::InstantiateOpaqueType {
93            base_universe: Some(base_universe),
94            ..self
95        }))
96    }
97}
98
99impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpProvePredicateGoal<'tcx> {
100    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
101        UniverseInfo::TypeOp(Rc::new(PredicateQuery { canonical_query: self, base_universe }))
102    }
103}
104
105impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUniverseInfo<'tcx>
106    for CanonicalTypeOpNormalizeGoal<'tcx, T>
107{
108    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
109        UniverseInfo::TypeOp(Rc::new(NormalizeQuery { canonical_query: self, base_universe }))
110    }
111}
112
113impl<'tcx> ToUniverseInfo<'tcx> for CanonicalTypeOpAscribeUserTypeGoal<'tcx> {
114    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
115        UniverseInfo::TypeOp(Rc::new(AscribeUserTypeQuery { canonical_query: self, base_universe }))
116    }
117}
118
119impl<'tcx> ToUniverseInfo<'tcx> for ! {
120    fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
121        self
122    }
123}
124
125#[allow(unused_lifetimes)]
126pub(crate) trait TypeOpInfo<'tcx> {
127    /// Returns an error to be reported if rerunning the type op fails to
128    /// recover the error's cause.
129    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx>;
130
131    fn base_universe(&self) -> ty::UniverseIndex;
132
133    fn nice_error<'diag>(
134        &self,
135        mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>,
136        cause: ObligationCause<'tcx>,
137        placeholder_region: ty::Region<'tcx>,
138        error_region: Option<ty::Region<'tcx>>,
139    ) -> Option<Diag<'diag>>;
140
141    /// Constraints require that `error_element` appear in the
142    /// values of `placeholder`, but this cannot be proven to
143    /// hold. Report an error.
144    #[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("report_erroneous_element",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(144u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("placeholder")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("placeholder");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("error_element")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("error_element");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("cause")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("cause");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&error_element)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cause)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = mbcx.infcx.tcx;
            let base_universe = self.base_universe();
            {
                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/diagnostics/bound_region_errors.rs:154",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(154u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("base_universe")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("base_universe");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&base_universe)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let Some(adjusted_universe) =
                placeholder.universe.as_u32().checked_sub(base_universe.as_u32()) else {
                    mbcx.buffer_error(self.fallback_error(tcx, cause.span));
                    return;
                };
            let placeholder_region =
                ty::Region::new_placeholder(tcx,
                    ty::PlaceholderRegion::new(adjusted_universe.into(),
                        placeholder.bound));
            let error_region =
                error_element.and_then(|e|
                        {
                            let adjusted_universe =
                                e.universe.as_u32().checked_sub(base_universe.as_u32());
                            adjusted_universe.map(|adjusted|
                                    {
                                        ty::Region::new_placeholder(tcx,
                                            ty::PlaceholderRegion::new(adjusted.into(), e.bound))
                                    })
                        });
            {
                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/diagnostics/bound_region_errors.rs:180",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(180u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("placeholder_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("placeholder_region");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder_region)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let span = cause.span;
            let nice_error =
                self.nice_error(mbcx, cause, placeholder_region,
                    error_region);
            {
                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/diagnostics/bound_region_errors.rs:185",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(185u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("nice_error")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("nice_error");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&nice_error)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            mbcx.buffer_error(nice_error.unwrap_or_else(||
                        self.fallback_error(tcx, span)));
        }
    }
}#[instrument(level = "debug", skip(self, mbcx))]
145    fn report_erroneous_element(
146        &self,
147        mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
148        placeholder: ty::PlaceholderRegion<'tcx>,
149        error_element: Option<ty::PlaceholderRegion<'tcx>>,
150        cause: ObligationCause<'tcx>,
151    ) {
152        let tcx = mbcx.infcx.tcx;
153        let base_universe = self.base_universe();
154        debug!(?base_universe);
155
156        let Some(adjusted_universe) =
157            placeholder.universe.as_u32().checked_sub(base_universe.as_u32())
158        else {
159            mbcx.buffer_error(self.fallback_error(tcx, cause.span));
160            return;
161        };
162
163        let placeholder_region = ty::Region::new_placeholder(
164            tcx,
165            ty::PlaceholderRegion::new(adjusted_universe.into(), placeholder.bound),
166        );
167
168        // FIXME: one day this should just be error_element,
169        // and this method shouldn't do anything.
170        let error_region = error_element.and_then(|e| {
171            let adjusted_universe = e.universe.as_u32().checked_sub(base_universe.as_u32());
172            adjusted_universe.map(|adjusted| {
173                ty::Region::new_placeholder(
174                    tcx,
175                    ty::PlaceholderRegion::new(adjusted.into(), e.bound),
176                )
177            })
178        });
179
180        debug!(?placeholder_region);
181
182        let span = cause.span;
183        let nice_error = self.nice_error(mbcx, cause, placeholder_region, error_region);
184
185        debug!(?nice_error);
186        mbcx.buffer_error(nice_error.unwrap_or_else(|| self.fallback_error(tcx, span)));
187    }
188}
189
190struct PredicateQuery<'tcx> {
191    canonical_query: CanonicalTypeOpProvePredicateGoal<'tcx>,
192    base_universe: ty::UniverseIndex,
193}
194
195impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
196    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> {
197        tcx.dcx().create_err(HigherRankedLifetimeError {
198            cause: Some(HigherRankedErrorCause::CouldNotProve {
199                predicate: self.canonical_query.canonical.value.value.predicate.to_string(),
200            }),
201            span,
202        })
203    }
204
205    fn base_universe(&self) -> ty::UniverseIndex {
206        self.base_universe
207    }
208
209    fn nice_error<'diag>(
210        &self,
211        mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>,
212        cause: ObligationCause<'tcx>,
213        placeholder_region: ty::Region<'tcx>,
214        error_region: Option<ty::Region<'tcx>>,
215    ) -> Option<Diag<'diag>> {
216        let (infcx, key, _) =
217            mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
218        let ocx = ObligationCtxt::new(&infcx);
219        type_op_prove_predicate_with_cause(&ocx, key, cause);
220        let diag = try_extract_error_from_fulfill_cx(
221            &ocx,
222            mbcx.mir_def_id(),
223            placeholder_region,
224            error_region,
225        )?
226        .with_dcx(mbcx.dcx());
227        Some(diag)
228    }
229}
230
231struct NormalizeQuery<'tcx, T> {
232    canonical_query: CanonicalTypeOpNormalizeGoal<'tcx, T>,
233    base_universe: ty::UniverseIndex,
234}
235
236impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T>
237where
238    T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx,
239{
240    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> {
241        tcx.dcx().create_err(HigherRankedLifetimeError {
242            cause: Some(HigherRankedErrorCause::CouldNotNormalize {
243                value: self
244                    .canonical_query
245                    .canonical
246                    .value
247                    .value
248                    .value
249                    .skip_normalization()
250                    .to_string(),
251            }),
252            span,
253        })
254    }
255
256    fn base_universe(&self) -> ty::UniverseIndex {
257        self.base_universe
258    }
259
260    fn nice_error<'diag>(
261        &self,
262        mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>,
263        cause: ObligationCause<'tcx>,
264        placeholder_region: ty::Region<'tcx>,
265        error_region: Option<ty::Region<'tcx>>,
266    ) -> Option<Diag<'diag>> {
267        let (infcx, key, _) =
268            mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
269        let ocx = ObligationCtxt::new(&infcx);
270
271        // FIXME(lqd): Unify and de-duplicate the following with the actual
272        // `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
273        // `ObligationCause`. The normalization results are currently different between
274        // `QueryNormalizeExt::query_normalize` used in the query and `normalize` called below:
275        // the former fails to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs`
276        // test. Check after #85499 lands to see if its fixes have erased this difference.
277        let ty::ParamEnvAnd { param_env, value } = key;
278        let _ = ocx.normalize(&cause, param_env, value.value);
279
280        let diag = try_extract_error_from_fulfill_cx(
281            &ocx,
282            mbcx.mir_def_id(),
283            placeholder_region,
284            error_region,
285        )?
286        .with_dcx(mbcx.dcx());
287        Some(diag)
288    }
289}
290
291struct AscribeUserTypeQuery<'tcx> {
292    canonical_query: CanonicalTypeOpAscribeUserTypeGoal<'tcx>,
293    base_universe: ty::UniverseIndex,
294}
295
296impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
297    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> {
298        // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
299        // and is only the fallback when the nice error fails. Consider improving this some more.
300        tcx.dcx().create_err(HigherRankedLifetimeError { cause: None, span })
301    }
302
303    fn base_universe(&self) -> ty::UniverseIndex {
304        self.base_universe
305    }
306
307    fn nice_error<'diag>(
308        &self,
309        mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>,
310        cause: ObligationCause<'tcx>,
311        placeholder_region: ty::Region<'tcx>,
312        error_region: Option<ty::Region<'tcx>>,
313    ) -> Option<Diag<'diag>> {
314        let (infcx, key, _) =
315            mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
316        let ocx = ObligationCtxt::new(&infcx);
317        type_op_ascribe_user_type_with_span(&ocx, key, cause.span).ok()?;
318        let diag = try_extract_error_from_fulfill_cx(
319            &ocx,
320            mbcx.mir_def_id(),
321            placeholder_region,
322            error_region,
323        )?
324        .with_dcx(mbcx.dcx());
325        Some(diag)
326    }
327}
328
329impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
330    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> Diag<'tcx> {
331        // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
332        // and is only the fallback when the nice error fails. Consider improving this some more.
333        tcx.dcx().create_err(HigherRankedLifetimeError { cause: None, span })
334    }
335
336    fn base_universe(&self) -> ty::UniverseIndex {
337        self.base_universe.unwrap()
338    }
339
340    fn nice_error<'diag>(
341        &self,
342        mbcx: &mut MirBorrowckCtxt<'_, 'diag, 'tcx>,
343        _cause: ObligationCause<'tcx>,
344        placeholder_region: ty::Region<'tcx>,
345        error_region: Option<ty::Region<'tcx>>,
346    ) -> Option<Diag<'diag>> {
347        try_extract_error_from_region_constraints(
348            mbcx.infcx,
349            mbcx.mir_def_id(),
350            placeholder_region,
351            error_region,
352            self.region_constraints.as_ref().unwrap(),
353            // We're using the original `InferCtxt` that we
354            // started MIR borrowchecking with, so the region
355            // constraints have already been taken. Use the data from
356            // our `mbcx` instead.
357            |vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin),
358            |vid| mbcx.regioncx.definitions[vid].universe,
359        )
360        .map(|d| d.with_dcx(mbcx.dcx()))
361    }
362}
363
364#[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("try_extract_error_from_fulfill_cx",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(364u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("generic_param_scope")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("generic_param_scope");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("placeholder_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("placeholder_region");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("error_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("error_region");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&generic_param_scope)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder_region)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&error_region)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Option<Diag<'a>> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let _errors = ocx.evaluate_obligations_error_on_ambiguity();
            let region_constraints =
                ocx.infcx.with_region_constraints(|r| r.clone());
            try_extract_error_from_region_constraints(ocx.infcx,
                generic_param_scope, placeholder_region, error_region,
                &region_constraints, |vid| ocx.infcx.region_var_origin(vid),
                |vid|
                    ocx.infcx.universe_of_region(ty::Region::new_var(ocx.infcx.tcx,
                            vid)))
        }
    }
}#[instrument(skip(ocx), level = "debug")]
365fn try_extract_error_from_fulfill_cx<'a, 'tcx>(
366    ocx: &ObligationCtxt<'a, 'tcx>,
367    generic_param_scope: LocalDefId,
368    placeholder_region: ty::Region<'tcx>,
369    error_region: Option<ty::Region<'tcx>>,
370) -> Option<Diag<'a>> {
371    // We generally shouldn't have errors here because the query was
372    // already run, but there's no point using `span_delayed_bug`
373    // when we're going to emit an error here anyway.
374    let _errors = ocx.evaluate_obligations_error_on_ambiguity();
375    let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
376    try_extract_error_from_region_constraints(
377        ocx.infcx,
378        generic_param_scope,
379        placeholder_region,
380        error_region,
381        &region_constraints,
382        |vid| ocx.infcx.region_var_origin(vid),
383        |vid| ocx.infcx.universe_of_region(ty::Region::new_var(ocx.infcx.tcx, vid)),
384    )
385}
386
387#[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("try_extract_error_from_region_constraints",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(387u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("generic_param_scope")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("generic_param_scope");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("placeholder_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("placeholder_region");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("error_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("error_region");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("region_constraints")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("region_constraints");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&generic_param_scope)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&placeholder_region)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&error_region)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&region_constraints)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Option<Diag<'a>> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let placeholder_universe =
                match placeholder_region.kind() {
                    ty::RePlaceholder(p) => p.universe,
                    ty::ReVar(vid) => universe_of_region(vid),
                    _ => ty::UniverseIndex::ROOT,
                };
            let regions_the_same =
                |a_region: Region<'tcx>, b_region: Region<'tcx>|
                    match (a_region.kind(), b_region.kind()) {
                        (RePlaceholder(a_p), RePlaceholder(b_p)) =>
                            a_p.bound == b_p.bound,
                        _ => a_region == b_region,
                    };
            let mut check =
                |c: Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact|
                    match c.kind {
                        ConstraintKind::RegSubReg if
                            ((exact && c.sup == placeholder_region) ||
                                        (!exact && regions_the_same(c.sup, placeholder_region))) &&
                                c.sup != c.sub => {
                            Some((c.sub, cause.clone()))
                        }
                        ConstraintKind::VarSubReg if
                            (exact && c.sup == placeholder_region &&
                                        !universe_of_region(c.sub.as_var()).can_name(placeholder_universe))
                                || (!exact && regions_the_same(c.sup, placeholder_region))
                            => {
                            Some((c.sub, cause.clone()))
                        }
                        ConstraintKind::VarSubVar | ConstraintKind::RegSubVar |
                            ConstraintKind::VarSubReg | ConstraintKind::RegSubReg =>
                            None,
                        ConstraintKind::VarEqVar | ConstraintKind::VarEqReg |
                            ConstraintKind::RegEqReg => {
                            ::core::panicking::panic("internal error: entered unreachable code")
                        }
                    };
            let mut find_culprit =
                |exact_match: bool|
                    {
                        region_constraints.constraints.iter().flat_map(|(constraint,
                                        cause)|
                                    {
                                        constraint.iter_outlives().map(move |constraint|
                                                (constraint, cause))
                                    }).find_map(|(constraint, cause)|
                                check(constraint, cause, exact_match))
                    };
            let (sub_region, cause) =
                find_culprit(true).or_else(|| find_culprit(false))?;
            {
                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/diagnostics/bound_region_errors.rs:446",
                                    "rustc_borrowck::diagnostics::bound_region_errors",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs"),
                                    ::tracing_core::__macro_support::Option::Some(446u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::diagnostics::bound_region_errors"),
                                    ::tracing_core::field::FieldSet::new(&["message",
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("sub_region")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("sub_region");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("cause = {0:#?}",
                                                                cause) as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sub_region)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            let error =
                match (error_region, sub_region.kind()) {
                    (Some(error_region), ty::ReVar(vid)) =>
                        RegionResolutionError::SubSupConflict(vid,
                            region_var_origin(vid), cause.clone(), error_region,
                            cause.clone(), placeholder_region,
                            ::alloc::vec::Vec::new()),
                    (Some(error_region), _) => {
                        RegionResolutionError::ConcreteFailure(cause.clone(),
                            error_region, placeholder_region)
                    }
                    (None, ty::ReVar(vid)) =>
                        RegionResolutionError::UpperBoundUniverseConflict(vid,
                            region_var_origin(vid), universe_of_region(vid),
                            cause.clone(), placeholder_region),
                    (None, _) => {
                        RegionResolutionError::ConcreteFailure(cause.clone(),
                            sub_region, placeholder_region)
                    }
                };
            NiceRegionError::new(&infcx.err_ctxt(), generic_param_scope,
                        error).try_report_from_nll().or_else(||
                    {
                        if let SubregionOrigin::Subtype(trace) = cause {
                            Some(infcx.err_ctxt().report_and_explain_type_error(*trace,
                                    infcx.tcx.param_env(generic_param_scope),
                                    TypeError::RegionsPlaceholderMismatch))
                        } else { None }
                    })
        }
    }
}#[instrument(level = "debug", skip(infcx, region_var_origin, universe_of_region))]
388fn try_extract_error_from_region_constraints<'a, 'tcx>(
389    infcx: &'a InferCtxt<'tcx>,
390    generic_param_scope: LocalDefId,
391    placeholder_region: ty::Region<'tcx>,
392    error_region: Option<ty::Region<'tcx>>,
393    region_constraints: &RegionConstraintData<'tcx>,
394    mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin<'tcx>,
395    mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
396) -> Option<Diag<'a>> {
397    let placeholder_universe = match placeholder_region.kind() {
398        ty::RePlaceholder(p) => p.universe,
399        ty::ReVar(vid) => universe_of_region(vid),
400        _ => ty::UniverseIndex::ROOT,
401    };
402    // Are the two regions the same?
403    let regions_the_same =
404        |a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
405            (RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
406            _ => a_region == b_region,
407        };
408    let mut check = |c: Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match c.kind {
409        ConstraintKind::RegSubReg
410            if ((exact && c.sup == placeholder_region)
411                || (!exact && regions_the_same(c.sup, placeholder_region)))
412                && c.sup != c.sub =>
413        {
414            Some((c.sub, cause.clone()))
415        }
416        ConstraintKind::VarSubReg
417            if (exact
418                && c.sup == placeholder_region
419                && !universe_of_region(c.sub.as_var()).can_name(placeholder_universe))
420                || (!exact && regions_the_same(c.sup, placeholder_region)) =>
421        {
422            Some((c.sub, cause.clone()))
423        }
424        ConstraintKind::VarSubVar
425        | ConstraintKind::RegSubVar
426        | ConstraintKind::VarSubReg
427        | ConstraintKind::RegSubReg => None,
428
429        ConstraintKind::VarEqVar | ConstraintKind::VarEqReg | ConstraintKind::RegEqReg => {
430            unreachable!()
431        }
432    };
433
434    let mut find_culprit = |exact_match: bool| {
435        region_constraints
436            .constraints
437            .iter()
438            .flat_map(|(constraint, cause)| {
439                constraint.iter_outlives().map(move |constraint| (constraint, cause))
440            })
441            .find_map(|(constraint, cause)| check(constraint, cause, exact_match))
442    };
443
444    let (sub_region, cause) = find_culprit(true).or_else(|| find_culprit(false))?;
445
446    debug!(?sub_region, "cause = {:#?}", cause);
447    let error = match (error_region, sub_region.kind()) {
448        (Some(error_region), ty::ReVar(vid)) => RegionResolutionError::SubSupConflict(
449            vid,
450            region_var_origin(vid),
451            cause.clone(),
452            error_region,
453            cause.clone(),
454            placeholder_region,
455            vec![],
456        ),
457        (Some(error_region), _) => {
458            RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region)
459        }
460        // Note universe here is wrong...
461        (None, ty::ReVar(vid)) => RegionResolutionError::UpperBoundUniverseConflict(
462            vid,
463            region_var_origin(vid),
464            universe_of_region(vid),
465            cause.clone(),
466            placeholder_region,
467        ),
468        (None, _) => {
469            RegionResolutionError::ConcreteFailure(cause.clone(), sub_region, placeholder_region)
470        }
471    };
472    NiceRegionError::new(&infcx.err_ctxt(), generic_param_scope, error)
473        .try_report_from_nll()
474        .or_else(|| {
475            if let SubregionOrigin::Subtype(trace) = cause {
476                Some(infcx.err_ctxt().report_and_explain_type_error(
477                    *trace,
478                    infcx.tcx.param_env(generic_param_scope),
479                    TypeError::RegionsPlaceholderMismatch,
480                ))
481            } else {
482                None
483            }
484        })
485}