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.rs44
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