Skip to main content

rustc_borrowck/region_infer/opaque_types/
mod.rs

1use std::iter;
2use std::rc::Rc;
3
4use rustc_data_structures::frozen::Frozen;
5use rustc_data_structures::fx::FxIndexMap;
6use rustc_hir::def_id::{DefId, LocalDefId};
7use rustc_infer::infer::outlives::env::RegionBoundPairs;
8use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries};
9use rustc_infer::traits::ObligationCause;
10use rustc_macros::extension;
11use rustc_middle::mir::{Body, ConstraintCategory};
12use rustc_middle::ty::{
13    self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, Flags, GenericArg,
14    GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionExt, RegionUtilitiesExt,
15    RegionVid, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized,
16    fold_regions,
17};
18use rustc_mir_dataflow::points::DenseLocationMap;
19use rustc_span::Span;
20use rustc_trait_selection::opaque_types::{
21    NonDefiningUseReason, opaque_type_has_defining_use_args,
22};
23use rustc_trait_selection::solve::NoSolution;
24use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
25use tracing::{debug, instrument};
26
27use super::reverse_sccs::ReverseSccGraph;
28use crate::consumers::RegionInferenceContext;
29use crate::session_diagnostics::LifetimeMismatchOpaqueParam;
30use crate::type_check::canonical::fully_perform_op_raw;
31use crate::type_check::free_region_relations::UniversalRegionRelations;
32use crate::type_check::{Locations, MirTypeckRegionConstraints};
33use crate::universal_regions::{RegionClassification, UniversalRegions};
34use crate::{BorrowckInferCtxt, CollectRegionConstraintsResult};
35
36mod member_constraints;
37mod region_ctxt;
38
39use member_constraints::apply_member_constraints;
40use region_ctxt::RegionCtxt;
41
42/// We defer errors from [fn handle_opaque_type_uses] and only report them
43/// if there are no `RegionErrors`. If there are region errors, it's likely
44/// that errors here are caused by them and don't need to be handled separately.
45pub(crate) enum DeferredOpaqueTypeError<'tcx> {
46    InvalidOpaqueTypeArgs(NonDefiningUseReason<'tcx>),
47    LifetimeMismatchOpaqueParam(LifetimeMismatchOpaqueParam<'tcx>),
48    UnexpectedHiddenRegion {
49        /// The opaque type.
50        opaque_type_key: OpaqueTypeKey<'tcx>,
51        /// The hidden type containing the member region.
52        hidden_type: ProvisionalHiddenType<'tcx>,
53        /// The unexpected region.
54        member_region: Region<'tcx>,
55    },
56    NonDefiningUseInDefiningScope {
57        span: Span,
58        opaque_type_key: OpaqueTypeKey<'tcx>,
59    },
60}
61
62/// We eagerly map all regions to NLL vars here, as we need to make sure we've
63/// introduced nll vars for all used placeholders.
64///
65/// We need to resolve inference vars as even though we're in MIR typeck, we may still
66/// encounter inference variables, e.g. when checking user types.
67pub(crate) fn clone_and_resolve_opaque_types<'tcx>(
68    infcx: &BorrowckInferCtxt<'tcx>,
69    universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
70    constraints: &mut MirTypeckRegionConstraints<'tcx>,
71) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>) {
72    let opaque_types = infcx.clone_opaque_types();
73    let opaque_types_storage_num_entries = infcx.inner.borrow_mut().opaque_types().num_entries();
74    let opaque_types = opaque_types
75        .into_iter()
76        .map(|entry| {
77            fold_regions(infcx.tcx, infcx.resolve_vars_if_possible(entry), |r, _| {
78                let vid = if let ty::RePlaceholder(placeholder) = r.kind() {
79                    constraints.placeholder_region(infcx, placeholder).as_var()
80                } else {
81                    universal_region_relations.universal_regions.to_region_vid(r)
82                };
83                Region::new_var(infcx.tcx, vid)
84            })
85        })
86        .collect::<Vec<_>>();
87    (opaque_types_storage_num_entries, opaque_types)
88}
89
90/// Maps an NLL var to a deterministically chosen equal universal region.
91///
92/// See the corresponding [rustc-dev-guide chapter] for more details. This
93/// ignores changes to the region values due to member constraints. Applying
94/// member constraints does not impact the result of this function.
95///
96/// [rustc-dev-guide chapter]: https://rustc-dev-guide.rust-lang.org/borrow_check/opaque-types-region-inference-restrictions.html
97fn nll_var_to_universal_region<'tcx>(
98    rcx: &RegionCtxt<'_, 'tcx>,
99    r: RegionVid,
100) -> Option<Region<'tcx>> {
101    // Use the SCC representative instead of directly using `region`.
102    // See [rustc-dev-guide chapter] § "Strict lifetime equality".
103    let vid = rcx.representative(r).rvid();
104    match rcx.definitions[vid].origin {
105        // Iterate over all universal regions in a consistent order and find the
106        // *first* equal region. This makes sure that equal lifetimes will have
107        // the same name and simplifies subsequent handling.
108        // See [rustc-dev-guide chapter] § "Semantic lifetime equality".
109        NllRegionVariableOrigin::FreeRegion => rcx
110            .universal_regions()
111            .universal_regions_iter()
112            .filter(|&ur| {
113                // See [rustc-dev-guide chapter] § "Closure restrictions".
114                !#[allow(non_exhaustive_omitted_patterns)] match rcx.universal_regions().region_classification(ur)
    {
    Some(RegionClassification::External) => true,
    _ => false,
}matches!(
115                    rcx.universal_regions().region_classification(ur),
116                    Some(RegionClassification::External)
117                )
118            })
119            .find(|&ur| rcx.universal_region_relations.equal(vid, ur))
120            .map(|ur| rcx.definitions[ur].external_name.unwrap()),
121        NllRegionVariableOrigin::Placeholder(placeholder) => {
122            Some(ty::Region::new_placeholder(rcx.infcx.tcx, placeholder))
123        }
124        // If `r` were equal to any universal region, its SCC representative
125        // would have been set to a free region.
126        NllRegionVariableOrigin::Existential { .. } => None,
127    }
128}
129
130/// Record info needed to report the same name error later.
131#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for UnexpectedHiddenRegion<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for UnexpectedHiddenRegion<'tcx> {
    #[inline]
    fn clone(&self) -> UnexpectedHiddenRegion<'tcx> {
        let _: ::core::clone::AssertParamIsClone<LocalDefId>;
        let _: ::core::clone::AssertParamIsClone<OpaqueTypeKey<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<ProvisionalHiddenType<'tcx>>;
        let _: ::core::clone::AssertParamIsClone<Region<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UnexpectedHiddenRegion<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "UnexpectedHiddenRegion", "def_id", &self.def_id,
            "opaque_type_key", &self.opaque_type_key, "hidden_type",
            &self.hidden_type, "member_region", &&self.member_region)
    }
}Debug)]
132pub(crate) struct UnexpectedHiddenRegion<'tcx> {
133    // The def_id of the body where this error occurs.
134    // Needed to handle region vars with their corresponding `infcx`.
135    def_id: LocalDefId,
136    opaque_type_key: OpaqueTypeKey<'tcx>,
137    hidden_type: ProvisionalHiddenType<'tcx>,
138    member_region: Region<'tcx>,
139}
140
141impl<'tcx> UnexpectedHiddenRegion<'tcx> {
142    pub(crate) fn to_error(self) -> (LocalDefId, DeferredOpaqueTypeError<'tcx>) {
143        let UnexpectedHiddenRegion { def_id, opaque_type_key, hidden_type, member_region } = self;
144        (
145            def_id,
146            DeferredOpaqueTypeError::UnexpectedHiddenRegion {
147                opaque_type_key,
148                hidden_type,
149                member_region,
150            },
151        )
152    }
153}
154
155/// Collect all defining uses of opaque types inside of this typeck root. This
156/// expects the hidden type to be mapped to the definition parameters of the opaque
157/// and errors if we end up with distinct hidden types.
158fn add_hidden_type<'tcx>(
159    tcx: TyCtxt<'tcx>,
160    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
161    def_id: LocalDefId,
162    hidden_ty: ty::DefinitionSiteHiddenType<'tcx>,
163) {
164    // Sometimes two opaque types are the same only after we remap the generic parameters
165    // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
166    // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
167    // only know that once we convert the generic parameters to those of the opaque type.
168    if let Some(prev) = hidden_types.get_mut(&def_id) {
169        if prev.ty == hidden_ty.ty {
170            // Pick a better span if there is one.
171            // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
172            prev.span = prev.span.substitute_dummy(hidden_ty.span);
173        } else {
174            let (Ok(guar) | Err(guar)) =
175                prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
176            *prev = ty::DefinitionSiteHiddenType::new_error(tcx, guar);
177        }
178    } else {
179        hidden_types.insert(def_id, hidden_ty);
180    }
181}
182
183#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for DefiningUse<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "DefiningUse",
            "opaque_type_key", &self.opaque_type_key, "arg_regions",
            &self.arg_regions, "hidden_type", &&self.hidden_type)
    }
}Debug)]
184struct DefiningUse<'tcx> {
185    /// The opaque type using non NLL vars. This uses the actual
186    /// free regions and placeholders. This is necessary
187    /// to interact with code outside of `rustc_borrowck`.
188    opaque_type_key: OpaqueTypeKey<'tcx>,
189    arg_regions: Vec<RegionVid>,
190    hidden_type: ProvisionalHiddenType<'tcx>,
191}
192
193/// This computes the actual hidden types of the opaque types and maps them to their
194/// definition sites. Outside of registering the computed hidden types this function
195/// does not mutate the current borrowck state.
196///
197/// While it may fail to infer the hidden type and return errors, we always apply
198/// the computed hidden type to all opaque type uses to check whether they
199/// are correct. This is necessary to support non-defining uses of opaques in their
200/// defining scope.
201///
202/// It also means that this whole function is not really soundness critical as we
203/// recheck all uses of the opaques regardless.
204pub(crate) fn compute_definition_site_hidden_types<'tcx>(
205    def_id: LocalDefId,
206    infcx: &BorrowckInferCtxt<'tcx>,
207    universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
208    constraints: &MirTypeckRegionConstraints<'tcx>,
209    location_map: Rc<DenseLocationMap>,
210    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
211    unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
212    opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
213) -> Vec<DeferredOpaqueTypeError<'tcx>> {
214    let mut errors = Vec::new();
215    // When computing the hidden type we need to track member constraints.
216    // We don't mutate the region graph used by `fn compute_regions` but instead
217    // manually track region information via a `RegionCtxt`. We discard this
218    // information at the end of this function.
219    let mut rcx = RegionCtxt::new(infcx, universal_region_relations, location_map, constraints);
220
221    // We start by checking each use of an opaque type during type check and
222    // check whether the generic arguments of the opaque type are fully
223    // universal, if so, it's a defining use.
224    let defining_uses = collect_defining_uses(&mut rcx, hidden_types, opaque_types, &mut errors);
225
226    // We now compute and apply member constraints for all regions in the hidden
227    // types of each defining use. This mutates the region values of the `rcx` which
228    // is used when mapping the defining uses to the definition site.
229    apply_member_constraints(&mut rcx, &defining_uses);
230
231    // After applying member constraints, we now check whether all member regions ended
232    // up equal to one of their choice regions and compute the actual hidden type of
233    // the opaque type definition. This is stored in the `root_cx`.
234    compute_definition_site_hidden_types_from_defining_uses(
235        def_id,
236        &rcx,
237        hidden_types,
238        unconstrained_hidden_type_errors,
239        &defining_uses,
240        &mut errors,
241    );
242    errors
243}
244
245x;#[instrument(level = "debug", skip_all, ret)]
246fn collect_defining_uses<'tcx>(
247    rcx: &mut RegionCtxt<'_, 'tcx>,
248    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
249    opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
250    errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
251) -> Vec<DefiningUse<'tcx>> {
252    let infcx = rcx.infcx;
253    let mut defining_uses = vec![];
254    for &(opaque_type_key, hidden_type) in opaque_types {
255        let non_nll_opaque_type_key = opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |r| {
256            nll_var_to_universal_region(&rcx, r.as_var()).unwrap_or(r)
257        });
258        if let Err(err) = opaque_type_has_defining_use_args(
259            infcx,
260            non_nll_opaque_type_key,
261            hidden_type.span,
262            DefiningScopeKind::MirBorrowck,
263        ) {
264            // A non-defining use. This is a hard error on stable and gets ignored
265            // with `TypingMode::PostTypeckUntilBorrowck`.
266            if infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
267                match err {
268                    NonDefiningUseReason::Tainted(guar) => add_hidden_type(
269                        infcx.tcx,
270                        hidden_types,
271                        opaque_type_key.def_id,
272                        DefinitionSiteHiddenType::new_error(infcx.tcx, guar),
273                    ),
274                    _ => debug!(?non_nll_opaque_type_key, ?err, "ignoring non-defining use"),
275                }
276            } else {
277                errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err));
278                debug!(
279                    "collect_defining_uses: InvalidOpaqueTypeArgs for {:?} := {:?}",
280                    non_nll_opaque_type_key, hidden_type
281                );
282            }
283            continue;
284        }
285
286        // We use the original `opaque_type_key` to compute the `arg_regions`.
287        let arg_regions = iter::once(rcx.universal_regions().fr_static)
288            .chain(
289                opaque_type_key
290                    .iter_captured_args(infcx.tcx)
291                    .filter_map(|(_, arg)| arg.as_region())
292                    .map(Region::as_var),
293            )
294            .collect();
295        defining_uses.push(DefiningUse {
296            opaque_type_key: non_nll_opaque_type_key,
297            arg_regions,
298            hidden_type,
299        });
300    }
301
302    defining_uses
303}
304
305#[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("compute_definition_site_hidden_types_from_defining_uses",
                                    "rustc_borrowck::region_infer::opaque_types",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs"),
                                    ::tracing_core::__macro_support::Option::Some(305u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("def_id")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("def_id");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("unconstrained_hidden_type_errors")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("unconstrained_hidden_type_errors");
                                                        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(&def_id)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&unconstrained_hidden_type_errors)
                                                            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 infcx = rcx.infcx;
            let tcx = infcx.tcx;
            let mut decls_modulo_regions:
                    FxIndexMap<OpaqueTypeKey<'tcx>,
                    (OpaqueTypeKey<'tcx>, Span)> = FxIndexMap::default();
            for &DefiningUse { opaque_type_key, ref arg_regions, hidden_type }
                in defining_uses {
                {
                    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/region_infer/opaque_types/mod.rs:319",
                                        "rustc_borrowck::region_infer::opaque_types",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs"),
                                        ::tracing_core::__macro_support::Option::Some(319u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types"),
                                        ::tracing_core::field::FieldSet::new(&[{
                                                            const NAME:
                                                                ::tracing::__macro_support::FieldName<{
                                                                    ::tracing::__macro_support::FieldName::len("opaque_type_key")
                                                                }> =
                                                                ::tracing::__macro_support::FieldName::new("opaque_type_key");
                                                            NAME.as_str()
                                                        },
                                                        {
                                                            const NAME:
                                                                ::tracing::__macro_support::FieldName<{
                                                                    ::tracing::__macro_support::FieldName::len("arg_regions")
                                                                }> =
                                                                ::tracing::__macro_support::FieldName::new("arg_regions");
                                                            NAME.as_str()
                                                        },
                                                        {
                                                            const NAME:
                                                                ::tracing::__macro_support::FieldName<{
                                                                    ::tracing::__macro_support::FieldName::len("hidden_type")
                                                                }> =
                                                                ::tracing::__macro_support::FieldName::new("hidden_type");
                                                            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(&opaque_type_key)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&arg_regions)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_type)
                                                            as &dyn ::tracing::field::Value))])
                            });
                    } else { ; }
                };
                let hidden_type =
                    match hidden_type.try_fold_with(&mut ToArgRegionsFolder::new(rcx,
                                    arg_regions)) {
                        Ok(hidden_type) => hidden_type,
                        Err(r) => {
                            {
                                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/region_infer/opaque_types/mod.rs:327",
                                                    "rustc_borrowck::region_infer::opaque_types",
                                                    ::tracing::Level::DEBUG,
                                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs"),
                                                    ::tracing_core::__macro_support::Option::Some(327u32),
                                                    ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types"),
                                                    ::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!("UnexpectedHiddenRegion: {0:?}",
                                                                                r) as &dyn ::tracing::field::Value))])
                                        });
                                } else { ; }
                            };
                            if rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck()
                                {
                                unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion {
                                        def_id,
                                        hidden_type,
                                        opaque_type_key,
                                        member_region: ty::Region::new_var(tcx, r),
                                    });
                                continue;
                            } else {
                                errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
                                        hidden_type,
                                        opaque_type_key,
                                        member_region: ty::Region::new_var(tcx, r),
                                    });
                                let guar =
                                    tcx.dcx().span_delayed_bug(hidden_type.span,
                                        "opaque type with non-universal region args");
                                ty::ProvisionalHiddenType::new_error(tcx, guar)
                            }
                        }
                    };
                let hidden_type =
                    infcx.infer_opaque_definition_from_instantiation(opaque_type_key,
                            hidden_type).unwrap_or_else(|_|
                            {
                                let guar =
                                    tcx.dcx().span_delayed_bug(hidden_type.span,
                                        "deferred invalid opaque type args");
                                DefinitionSiteHiddenType::new_error(tcx, guar)
                            });
                if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck()
                    {
                    if let &ty::Alias(_, ty::AliasTy {
                                    kind: ty::Opaque { def_id }, args, .. }) =
                                    hidden_type.ty.skip_binder().kind() &&
                                def_id == opaque_type_key.def_id.to_def_id() &&
                            args == opaque_type_key.args {
                        continue;
                    }
                }
                if let Some((prev_decl_key, prev_span)) =
                            decls_modulo_regions.insert(rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key),
                                (opaque_type_key, hidden_type.span)) &&
                        let Some((arg1, arg2)) =
                            std::iter::zip(prev_decl_key.iter_captured_args(infcx.tcx).map(|(_,
                                                arg)| arg),
                                    opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)|
                                            arg)).find(|(arg1, arg2)| arg1 != arg2) {
                    errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(LifetimeMismatchOpaqueParam {
                                arg: arg1,
                                prev: arg2,
                                span: prev_span,
                                prev_span: hidden_type.span,
                            }));
                }
                add_hidden_type(tcx, hidden_types, opaque_type_key.def_id,
                    hidden_type);
            }
        }
    }
}#[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))]
306fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
307    def_id: LocalDefId,
308    rcx: &RegionCtxt<'_, 'tcx>,
309    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
310    unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
311    defining_uses: &[DefiningUse<'tcx>],
312    errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
313) {
314    let infcx = rcx.infcx;
315    let tcx = infcx.tcx;
316    let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> =
317        FxIndexMap::default();
318    for &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses {
319        debug!(?opaque_type_key, ?arg_regions, ?hidden_type);
320        // After applying member constraints, we now map all regions in the hidden type
321        // to the `arg_regions` of this defining use. In case a region in the hidden type
322        // ended up not being equal to any such region, we error.
323        let hidden_type =
324            match hidden_type.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions)) {
325                Ok(hidden_type) => hidden_type,
326                Err(r) => {
327                    debug!("UnexpectedHiddenRegion: {:?}", r);
328                    // If we're using the next solver, the unconstrained region may be resolved by a
329                    // fully defining use from another body.
330                    // So we don't generate error eagerly here.
331                    if rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
332                        unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion {
333                            def_id,
334                            hidden_type,
335                            opaque_type_key,
336                            member_region: ty::Region::new_var(tcx, r),
337                        });
338                        continue;
339                    } else {
340                        errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion {
341                            hidden_type,
342                            opaque_type_key,
343                            member_region: ty::Region::new_var(tcx, r),
344                        });
345                        let guar = tcx.dcx().span_delayed_bug(
346                            hidden_type.span,
347                            "opaque type with non-universal region args",
348                        );
349                        ty::ProvisionalHiddenType::new_error(tcx, guar)
350                    }
351                }
352            };
353
354        // Now that we mapped the member regions to their final value,
355        // map the arguments of the opaque type key back to the parameters
356        // of the opaque type definition.
357        let hidden_type = infcx
358            .infer_opaque_definition_from_instantiation(opaque_type_key, hidden_type)
359            .unwrap_or_else(|_| {
360                let guar = tcx
361                    .dcx()
362                    .span_delayed_bug(hidden_type.span, "deferred invalid opaque type args");
363                DefinitionSiteHiddenType::new_error(tcx, guar)
364            });
365
366        // Sometimes, when the hidden type is an inference variable, it can happen that
367        // the hidden type becomes the opaque type itself. In this case, this was an opaque
368        // usage of the opaque type and we can ignore it. This check is mirrored in typeck's
369        // writeback.
370        if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
371            if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
372                hidden_type.ty.skip_binder().kind()
373                && def_id == opaque_type_key.def_id.to_def_id()
374                && args == opaque_type_key.args
375            {
376                continue;
377            }
378        }
379
380        // Check that all opaque types have the same region parameters if they have the same
381        // non-region parameters. This is necessary because within the new solver we perform
382        // various query operations modulo regions, and thus could unsoundly select some impls
383        // that don't hold.
384        //
385        // FIXME(-Znext-solver): This isn't necessary after all. We can remove this check again.
386        if let Some((prev_decl_key, prev_span)) = decls_modulo_regions.insert(
387            rcx.infcx.tcx.erase_and_anonymize_regions(opaque_type_key),
388            (opaque_type_key, hidden_type.span),
389        ) && let Some((arg1, arg2)) = std::iter::zip(
390            prev_decl_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
391            opaque_type_key.iter_captured_args(infcx.tcx).map(|(_, arg)| arg),
392        )
393        .find(|(arg1, arg2)| arg1 != arg2)
394        {
395            errors.push(DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(
396                LifetimeMismatchOpaqueParam {
397                    arg: arg1,
398                    prev: arg2,
399                    span: prev_span,
400                    prev_span: hidden_type.span,
401                },
402            ));
403        }
404        add_hidden_type(tcx, hidden_types, opaque_type_key.def_id, hidden_type);
405    }
406}
407
408/// A folder to map the regions in the hidden type to their corresponding `arg_regions`.
409///
410/// This folder has to differentiate between member regions and other regions in the hidden
411/// type. Member regions have to be equal to one of the `arg_regions` while other regions simply
412/// get treated as an existential region in the opaque if they are not. Existential
413/// regions are currently represented using `'erased`.
414struct ToArgRegionsFolder<'a, 'tcx> {
415    rcx: &'a RegionCtxt<'a, 'tcx>,
416    // When folding closure args or bivariant alias arguments, we simply
417    // ignore non-member regions. However, we still need to map member
418    // regions to their arg region even if its in a closure argument.
419    //
420    // See tests/ui/type-alias-impl-trait/closure_wf_outlives.rs for an example.
421    erase_unknown_regions: bool,
422    arg_regions: &'a [RegionVid],
423}
424
425impl<'a, 'tcx> ToArgRegionsFolder<'a, 'tcx> {
426    fn new(
427        rcx: &'a RegionCtxt<'a, 'tcx>,
428        arg_regions: &'a [RegionVid],
429    ) -> ToArgRegionsFolder<'a, 'tcx> {
430        ToArgRegionsFolder { rcx, erase_unknown_regions: false, arg_regions }
431    }
432
433    fn fold_non_member_arg(&mut self, arg: GenericArg<'tcx>) -> GenericArg<'tcx> {
434        let prev = self.erase_unknown_regions;
435        self.erase_unknown_regions = true;
436        let res = arg.try_fold_with(self).unwrap();
437        self.erase_unknown_regions = prev;
438        res
439    }
440
441    fn fold_closure_args(
442        &mut self,
443        def_id: DefId,
444        args: GenericArgsRef<'tcx>,
445    ) -> Result<GenericArgsRef<'tcx>, RegionVid> {
446        let generics = self.cx().generics_of(def_id);
447        self.cx().mk_args_from_iter(args.iter().enumerate().map(|(index, arg)| {
448            if index < generics.parent_count {
449                Ok(self.fold_non_member_arg(arg))
450            } else {
451                arg.try_fold_with(self)
452            }
453        }))
454    }
455}
456impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
457    type Error = RegionVid;
458    fn cx(&self) -> TyCtxt<'tcx> {
459        self.rcx.infcx.tcx
460    }
461
462    fn try_fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, RegionVid> {
463        match r.kind() {
464            // ignore bound regions, keep visiting
465            ty::ReBound(_, _) => Ok(r),
466            _ => {
467                let r = r.as_var();
468                if let Some(arg_region) = self
469                    .arg_regions
470                    .iter()
471                    .copied()
472                    .find(|&arg_vid| self.rcx.eval_equal(r, arg_vid))
473                    .and_then(|r| nll_var_to_universal_region(self.rcx, r))
474                {
475                    Ok(arg_region)
476                } else if self.erase_unknown_regions {
477                    Ok(self.cx().lifetimes.re_erased)
478                } else {
479                    Err(r)
480                }
481            }
482        }
483    }
484
485    fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, RegionVid> {
486        if !ty.flags().intersects(ty::TypeFlags::HAS_FREE_REGIONS) {
487            return Ok(ty);
488        }
489
490        let tcx = self.cx();
491        Ok(match *ty.kind() {
492            ty::Closure(def_id, args) => {
493                Ty::new_closure(tcx, def_id, self.fold_closure_args(def_id, args)?)
494            }
495
496            ty::CoroutineClosure(def_id, args) => {
497                Ty::new_coroutine_closure(tcx, def_id, self.fold_closure_args(def_id, args)?)
498            }
499
500            ty::Coroutine(def_id, args) => {
501                Ty::new_coroutine(tcx, def_id, self.fold_closure_args(def_id, args)?)
502            }
503
504            ty::Alias(_, ty::AliasTy { kind, args, .. })
505                if let Some(variances) = tcx.opt_alias_variances(kind) =>
506            {
507                let args = tcx.mk_args_from_iter(std::iter::zip(variances, args.iter()).map(
508                    |(&v, s)| {
509                        if v == ty::Bivariant {
510                            Ok(self.fold_non_member_arg(s))
511                        } else {
512                            s.try_fold_with(self)
513                        }
514                    },
515                ))?;
516                ty::AliasTy::new_from_args(tcx, kind, args).to_ty(tcx, ty::IsRigid::No)
517            }
518
519            _ => ty.try_super_fold_with(self)?,
520        })
521    }
522}
523
524/// This function is what actually applies member constraints to the borrowck
525/// state. It is also responsible to check all uses of the opaques in their
526/// defining scope.
527///
528/// It does this by equating the hidden type of each use with the instantiated final
529/// hidden type of the opaque.
530pub(crate) fn apply_definition_site_hidden_types<'tcx>(
531    infcx: &BorrowckInferCtxt<'tcx>,
532    body: &Body<'tcx>,
533    universal_regions: &UniversalRegions<'tcx>,
534    region_bound_pairs: &RegionBoundPairs<'tcx>,
535    known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
536    constraints: &mut MirTypeckRegionConstraints<'tcx>,
537    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
538    opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)],
539) -> Vec<DeferredOpaqueTypeError<'tcx>> {
540    let tcx = infcx.tcx;
541    let mut errors = Vec::new();
542    for &(key, hidden_type) in opaque_types {
543        let Some(expected) = hidden_types.get(&key.def_id) else {
544            if !tcx.use_typing_mode_post_typeck_until_borrowck() {
545                if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
546                    hidden_type.ty.kind()
547                    && def_id == key.def_id.to_def_id()
548                    && args == key.args
549                {
550                    continue;
551                } else {
552                    {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("non-defining use in defining scope")));
};unreachable!("non-defining use in defining scope");
553                }
554            }
555            errors.push(DeferredOpaqueTypeError::NonDefiningUseInDefiningScope {
556                span: hidden_type.span,
557                opaque_type_key: key,
558            });
559            let guar = tcx.dcx().span_delayed_bug(
560                hidden_type.span,
561                "non-defining use in the defining scope with no defining uses",
562            );
563            add_hidden_type(
564                tcx,
565                hidden_types,
566                key.def_id,
567                DefinitionSiteHiddenType::new_error(tcx, guar),
568            );
569            continue;
570        };
571
572        // We erase all non-member region of the opaque and need to treat these as existentials.
573        let expected_ty = ty::fold_regions(
574            tcx,
575            expected.ty.instantiate(tcx, key.args).skip_norm_wip(),
576            |re, _dbi| match re.kind() {
577                ty::ReErased => infcx.next_nll_region_var(
578                    NllRegionVariableOrigin::Existential { name: None },
579                    || crate::RegionCtxt::Existential(None),
580                ),
581                _ => re,
582            },
583        );
584
585        // We now simply equate the expected with the actual hidden type.
586        let locations = Locations::All(hidden_type.span);
587        if let Err(guar) = fully_perform_op_raw(
588            infcx,
589            body,
590            universal_regions,
591            region_bound_pairs,
592            known_type_outlives_obligations,
593            constraints,
594            locations,
595            ConstraintCategory::OpaqueType,
596            CustomTypeOp::new(
597                |ocx| {
598                    let cause = ObligationCause::misc(
599                        hidden_type.span,
600                        body.source.def_id().expect_local(),
601                    );
602                    // We need to normalize both types in the old solver before equatingt them.
603                    let actual_ty = ocx.normalize(
604                        &cause,
605                        infcx.param_env,
606                        Unnormalized::new_wip(hidden_type.ty),
607                    );
608                    let expected_ty =
609                        ocx.normalize(&cause, infcx.param_env, Unnormalized::new_wip(expected_ty));
610                    ocx.eq(&cause, infcx.param_env, actual_ty, expected_ty).map_err(|_| NoSolution)
611                },
612                "equating opaque types",
613            ),
614        ) {
615            add_hidden_type(
616                tcx,
617                hidden_types,
618                key.def_id,
619                DefinitionSiteHiddenType::new_error(tcx, guar),
620            );
621        }
622    }
623    errors
624}
625
626/// We handle `UnexpectedHiddenRegion` error lazily in the next solver as
627/// there may be a fully defining use in another body.
628///
629/// In case such a defining use does not exist, we register an error here.
630pub(crate) fn handle_unconstrained_hidden_type_errors<'tcx>(
631    tcx: TyCtxt<'tcx>,
632    hidden_types: &mut FxIndexMap<LocalDefId, ty::DefinitionSiteHiddenType<'tcx>>,
633    unconstrained_hidden_type_errors: &mut Vec<UnexpectedHiddenRegion<'tcx>>,
634    collect_region_constraints_results: &mut FxIndexMap<
635        LocalDefId,
636        CollectRegionConstraintsResult<'tcx>,
637    >,
638) {
639    let mut unconstrained_hidden_type_errors = std::mem::take(unconstrained_hidden_type_errors);
640    unconstrained_hidden_type_errors
641        .retain(|unconstrained| !hidden_types.contains_key(&unconstrained.opaque_type_key.def_id));
642
643    unconstrained_hidden_type_errors.iter().for_each(|t| {
644        tcx.dcx()
645            .span_delayed_bug(t.hidden_type.span, "opaque type with non-universal region args");
646    });
647
648    // `UnexpectedHiddenRegion` error contains region var which only makes sense in the
649    // corresponding `infcx`.
650    // So we need to insert the error to the body where it originates from.
651    for error in unconstrained_hidden_type_errors {
652        let (def_id, error) = error.to_error();
653        let Some(result) = collect_region_constraints_results.get_mut(&def_id) else {
654            {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("the body should depend on opaques type if it has opaque use")));
};unreachable!("the body should depend on opaques type if it has opaque use");
655        };
656        result.deferred_opaque_type_errors.push(error);
657    }
658}
659
660/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types.
661/// We do not check these new uses so this could be unsound.
662///
663/// We detect any new uses and simply delay a bug if they occur. If this results in
664/// an ICE we can properly handle this, but we haven't encountered any such test yet.
665///
666/// See the related comment in `FnCtxt::detect_opaque_types_added_during_writeback`.
667pub(crate) fn detect_opaque_types_added_while_handling_opaque_types<'tcx>(
668    infcx: &InferCtxt<'tcx>,
669    opaque_types_storage_num_entries: OpaqueTypeStorageEntries,
670) {
671    for (key, hidden_type) in infcx
672        .inner
673        .borrow_mut()
674        .opaque_types()
675        .opaque_types_added_since(opaque_types_storage_num_entries)
676    {
677        let opaque_type_string = infcx.tcx.def_path_str(key.def_id);
678        let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unexpected cyclic definition of `{0}`",
                opaque_type_string))
    })format!("unexpected cyclic definition of `{opaque_type_string}`");
679        infcx.dcx().span_delayed_bug(hidden_type.span, msg);
680    }
681
682    let _ = infcx.take_opaque_types();
683}
684
685impl<'tcx> RegionInferenceContext<'tcx> {
686    /// Map the regions in the type to named regions. This is similar to what
687    /// `infer_opaque_types` does, but can infer any universal region, not only
688    /// ones from the args for the opaque type. It also doesn't double check
689    /// that the regions produced are in fact equal to the named region they are
690    /// replaced with. This is fine because this function is only to improve the
691    /// region names in error messages.
692    ///
693    /// This differs from `MirBorrowckCtxt::name_regions` since it is particularly
694    /// lax with mapping region vids that are *shorter* than a universal region to
695    /// that universal region. This is useful for member region constraints since
696    /// we want to suggest a universal region name to capture even if it's technically
697    /// not equal to the error region.
698    pub(crate) fn name_regions_for_member_constraint<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T
699    where
700        T: TypeFoldable<TyCtxt<'tcx>>,
701    {
702        fold_regions(tcx, ty, |region, _| match region.kind() {
703            ty::ReVar(vid) => {
704                let scc = self.constraint_sccs.scc(vid);
705
706                // Special handling of higher-ranked regions.
707                if !self.max_nameable_universe(scc).is_root() {
708                    match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
709                        // If the region contains a single placeholder then they're equal.
710                        Some((0, placeholder)) => {
711                            return ty::Region::new_placeholder(tcx, placeholder);
712                        }
713
714                        // Fallback: this will produce a cryptic error message.
715                        _ => return region,
716                    }
717                }
718
719                // Find something that we can name
720                let upper_bound = self.approx_universal_upper_bound(vid);
721                if let Some(universal_region) = self.definitions[upper_bound].external_name {
722                    return universal_region;
723                }
724
725                // Nothing exact found, so we pick a named upper bound, if there's only one.
726                // If there's >1 universal region, then we probably are dealing w/ an intersection
727                // region which cannot be mapped back to a universal.
728                // FIXME: We could probably compute the LUB if there is one.
729                let scc = self.constraint_sccs.scc(vid);
730                let rev_scc_graph =
731                    ReverseSccGraph::compute(&self.constraint_sccs, self.universal_regions());
732                let upper_bounds: Vec<_> = rev_scc_graph
733                    .upper_bounds(scc)
734                    .filter_map(|vid| self.definitions[vid].external_name)
735                    .filter(|r| !r.is_static())
736                    .collect();
737                match &upper_bounds[..] {
738                    [universal_region] => *universal_region,
739                    _ => region,
740                }
741            }
742            _ => region,
743        })
744    }
745}
746
747impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
    #[doc = " Given the fully resolved, instantiated type for an opaque"]
    #[doc = " type, i.e., the value of an inference variable like C1 or C2"]
    #[doc = " (*), computes the \"definition type\" for an opaque type"]
    #[doc = " definition -- that is, the inferred value of `Foo1<\'x>` or"]
    #[doc = " `Foo2<\'x>` that we would conceptually use in its definition:"]
    #[doc = " ```ignore (illustrative)"]
    #[doc = " type Foo1<\'x> = impl Bar<\'x> = AAA;  // <-- this type AAA"]
    #[doc = " type Foo2<\'x> = impl Bar<\'x> = BBB;  // <-- or this type BBB"]
    #[doc = " fn foo<\'a, \'b>(..) -> (Foo1<\'a>, Foo2<\'b>) { .. }"]
    #[doc = " ```"]
    #[doc =
    " Note that these values are defined in terms of a distinct set of"]
    #[doc =
    " generic parameters (`\'x` instead of `\'a`) from C1 or C2. The main"]
    #[doc = " purpose of this function is to do that translation."]
    #[doc = ""]
    #[doc = " (*) C1 and C2 were introduced in the comments on"]
    #[doc =
    " `register_member_constraints`. Read that comment for more context."]
    fn infer_opaque_definition_from_instantiation(&self,
        opaque_type_key: OpaqueTypeKey<'tcx>,
        instantiated_ty: ProvisionalHiddenType<'tcx>)
        ->
            Result<ty::DefinitionSiteHiddenType<'tcx>,
            NonDefiningUseReason<'tcx>> {
        {}

        #[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("infer_opaque_definition_from_instantiation",
                                            "rustc_borrowck::region_infer::opaque_types",
                                            ::tracing::Level::DEBUG,
                                            ::tracing_core::__macro_support::Option::Some("compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs"),
                                            ::tracing_core::__macro_support::Option::Some(765u32),
                                            ::tracing_core::__macro_support::Option::Some("rustc_borrowck::region_infer::opaque_types"),
                                            ::tracing_core::field::FieldSet::new(&[{
                                                                const NAME:
                                                                    ::tracing::__macro_support::FieldName<{
                                                                        ::tracing::__macro_support::FieldName::len("opaque_type_key")
                                                                    }> =
                                                                    ::tracing::__macro_support::FieldName::new("opaque_type_key");
                                                                NAME.as_str()
                                                            },
                                                            {
                                                                const NAME:
                                                                    ::tracing::__macro_support::FieldName<{
                                                                        ::tracing::__macro_support::FieldName::len("instantiated_ty")
                                                                    }> =
                                                                    ::tracing::__macro_support::FieldName::new("instantiated_ty");
                                                                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(&opaque_type_key)
                                                                    as &dyn ::tracing::field::Value)),
                                                        (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&instantiated_ty)
                                                                    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:
                            Result<ty::DefinitionSiteHiddenType<'tcx>,
                            NonDefiningUseReason<'tcx>> = loop {};
                    return __tracing_attr_fake_return;
                }
                {
                    opaque_type_has_defining_use_args(self, opaque_type_key,
                            instantiated_ty.span, DefiningScopeKind::MirBorrowck)?;
                    let definition_ty =
                        instantiated_ty.remap_generic_params_to_declaration_params(opaque_type_key,
                            self.tcx, DefiningScopeKind::MirBorrowck);
                    definition_ty.ty.skip_binder().error_reported()?;
                    Ok(definition_ty)
                }
            }
        }
    }
}#[extension(pub trait InferCtxtExt<'tcx>)]
748impl<'tcx> InferCtxt<'tcx> {
749    /// Given the fully resolved, instantiated type for an opaque
750    /// type, i.e., the value of an inference variable like C1 or C2
751    /// (*), computes the "definition type" for an opaque type
752    /// definition -- that is, the inferred value of `Foo1<'x>` or
753    /// `Foo2<'x>` that we would conceptually use in its definition:
754    /// ```ignore (illustrative)
755    /// type Foo1<'x> = impl Bar<'x> = AAA;  // <-- this type AAA
756    /// type Foo2<'x> = impl Bar<'x> = BBB;  // <-- or this type BBB
757    /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. }
758    /// ```
759    /// Note that these values are defined in terms of a distinct set of
760    /// generic parameters (`'x` instead of `'a`) from C1 or C2. The main
761    /// purpose of this function is to do that translation.
762    ///
763    /// (*) C1 and C2 were introduced in the comments on
764    /// `register_member_constraints`. Read that comment for more context.
765    #[instrument(level = "debug", skip(self))]
766    fn infer_opaque_definition_from_instantiation(
767        &self,
768        opaque_type_key: OpaqueTypeKey<'tcx>,
769        instantiated_ty: ProvisionalHiddenType<'tcx>,
770    ) -> Result<ty::DefinitionSiteHiddenType<'tcx>, NonDefiningUseReason<'tcx>> {
771        opaque_type_has_defining_use_args(
772            self,
773            opaque_type_key,
774            instantiated_ty.span,
775            DefiningScopeKind::MirBorrowck,
776        )?;
777
778        let definition_ty = instantiated_ty.remap_generic_params_to_declaration_params(
779            opaque_type_key,
780            self.tcx,
781            DefiningScopeKind::MirBorrowck,
782        );
783        definition_ty.ty.skip_binder().error_reported()?;
784        Ok(definition_ty)
785    }
786}