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