Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer.rs')
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index bd00da84ca..c838fcc3a7 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -99,7 +99,7 @@ use crate::{ }, method_resolution::CandidateId, next_solver::{ - AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, + AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, StoredFnSig, StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys, abi::Safety, infer::{InferCtxt, ObligationInspector, traits::ObligationCause}, @@ -820,7 +820,7 @@ pub struct InferenceResult<'db> { defined_anon_consts: ThinVec<AnonConstId<'db>>, } -#[derive(Clone, PartialEq, Eq, Debug, Default)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct ClosureData { /// Tracks the minimum captures required for a closure; /// see `MinCaptureInformationMap` for more details. @@ -849,6 +849,42 @@ pub struct ClosureData { /// information on `t` in order to create place `t.0` and `t.1`. We can solve this /// issue by fake reading `t`. pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>, + + /// For each fn, records the "liberated" types of its arguments + /// and return type. Liberated means that all bound regions + /// (including late-bound regions) are replaced with free + /// equivalents. This table is not used in codegen (since regions + /// are erased there) and hence is not serialized to metadata. + /// + /// This table also contains the "revealed" values for any `impl Trait` + /// that appear in the signature and whose values are being inferred + /// by this function. + /// + /// # Example + /// + /// ```rust + /// # use std::fmt::Debug; + /// fn foo(x: &u32) -> impl Debug { *x } + /// ``` + /// + /// The function signature here would be: + /// + /// ```ignore (illustrative) + /// for<'a> fn(&'a u32) -> Foo + /// ``` + /// + /// where `Foo` is an opaque type created for this function. + /// + /// + /// The *liberated* form of this would be + /// + /// ```ignore (illustrative) + /// fn(&'a u32) -> u32 + /// ``` + /// + /// Note that `'a` is not bound (it would be an `ReLateParam`) and + /// that the `Foo` opaque type is replaced by its hidden type. + pub liberated_sig: StoredFnSig, } /// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`. @@ -1677,7 +1713,7 @@ impl<'db> InferenceContext<'db> { } pat_adjustments.shrink_to_fit(); for closure_data in closures_data.values_mut() { - let ClosureData { min_captures, fake_reads } = closure_data; + let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data; let dummy_place = || Place { base_ty: types.types.error.store(), base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue, @@ -1706,6 +1742,8 @@ impl<'db> InferenceContext<'db> { min_capture.shrink_to_fit(); } min_captures.shrink_to_fit(); + + resolver.resolve_completely(liberated_sig); } closures_data.shrink_to_fit(); *tuple_field_access_types = tuple_field_accesses_rev |