diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index fa81fe39aa1..ccfa626b5fd 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -367,6 +367,10 @@ pub enum PointerCast { } /// The result of type inference: A mapping from expressions and patterns to types. +/// +/// When you add a field that stores types (including `Substitution` and the like), don't forget +/// `resolve_completely()`'ing them in `InferenceContext::resolve_all()`. Inference variables must +/// not appear in the final inference result. #[derive(Clone, PartialEq, Eq, Debug, Default)] pub struct InferenceResult { /// For each method call expr, records the function it resolves to. @@ -575,6 +579,8 @@ fn new( // used this function for another workaround, mention it here. If you really need this function and believe that // there is no problem in it being `pub(crate)`, remove this comment. pub(crate) fn resolve_all(self) -> InferenceResult { + // NOTE: `InferenceResult::closure_info` is `resolve_completely()`'d during + // `InferenceContext::infer_closures()` (in `HirPlace::ty()` specifically). let InferenceContext { mut table, mut result, .. } = self; table.fallback_if_possible(); diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index e98905f4eee..23189f383e0 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -236,6 +236,24 @@ pub(crate) struct CapturedItemWithoutTy { impl CapturedItemWithoutTy { fn with_ty(self, ctx: &mut InferenceContext<'_>) -> CapturedItem { + let ty = self.place.ty(ctx).clone(); + let ty = match &self.kind { + CaptureKind::ByValue => ty, + CaptureKind::ByRef(bk) => { + let m = match bk { + BorrowKind::Mut { .. } => Mutability::Mut, + _ => Mutability::Not, + }; + TyKind::Ref(m, static_lifetime(), ty).intern(Interner) + } + }; + return CapturedItem { + place: self.place, + kind: self.kind, + span: self.span, + ty: replace_placeholder_with_binder(ctx.db, ctx.owner, ty), + }; + fn replace_placeholder_with_binder( db: &dyn HirDatabase, owner: DefWithBodyId, @@ -281,36 +299,13 @@ fn try_fold_free_placeholder_ty( Ok(BoundVar::new(outer_binder, idx).to_ty(Interner)) } } - let g_def = match owner { - DefWithBodyId::FunctionId(f) => Some(f.into()), - DefWithBodyId::StaticId(_) => None, - DefWithBodyId::ConstId(f) => Some(f.into()), - DefWithBodyId::VariantId(f) => Some(f.into()), - }; - let Some(generics) = g_def.map(|g_def| generics(db.upcast(), g_def)) else { + let Some(generic_def) = owner.as_generic_def_id() else { return Binders::empty(Interner, ty); }; - let filler = &mut Filler { db, generics }; + let filler = &mut Filler { db, generics: generics(db.upcast(), generic_def) }; let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty); make_binders(db, &filler.generics, result) } - let ty = self.place.ty(ctx).clone(); - let ty = match &self.kind { - CaptureKind::ByValue => ty, - CaptureKind::ByRef(bk) => { - let m = match bk { - BorrowKind::Mut { .. } => Mutability::Mut, - _ => Mutability::Not, - }; - TyKind::Ref(m, static_lifetime(), ty).intern(Interner) - } - }; - CapturedItem { - place: self.place, - kind: self.kind, - span: self.span, - ty: replace_placeholder_with_binder(ctx.db, ctx.owner, ty), - } } } diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs index b17ac583656..ce3f7a8e510 100644 --- a/crates/hir-ty/src/mir/monomorphization.rs +++ b/crates/hir-ty/src/mir/monomorphization.rs @@ -303,13 +303,7 @@ pub fn monomorphized_mir_body_query( subst: Substitution, trait_env: Arc, ) -> Result, MirLowerError> { - let g_def = match owner { - DefWithBodyId::FunctionId(f) => Some(f.into()), - DefWithBodyId::StaticId(_) => None, - DefWithBodyId::ConstId(f) => Some(f.into()), - DefWithBodyId::VariantId(f) => Some(f.into()), - }; - let generics = g_def.map(|g_def| generics(db.upcast(), g_def)); + let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def)); let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner }; let body = db.mir_body(owner)?; let mut body = (*body).clone(); @@ -334,13 +328,7 @@ pub fn monomorphized_mir_body_for_closure_query( trait_env: Arc, ) -> Result, MirLowerError> { let (owner, _) = db.lookup_intern_closure(closure.into()); - let g_def = match owner { - DefWithBodyId::FunctionId(f) => Some(f.into()), - DefWithBodyId::StaticId(_) => None, - DefWithBodyId::ConstId(f) => Some(f.into()), - DefWithBodyId::VariantId(f) => Some(f.into()), - }; - let generics = g_def.map(|g_def| generics(db.upcast(), g_def)); + let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def)); let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner }; let body = db.mir_body_for_closure(closure)?; let mut body = (*body).clone(); @@ -356,13 +344,7 @@ pub fn monomorphize_mir_body_bad( trait_env: Arc, ) -> Result { let owner = body.owner; - let g_def = match owner { - DefWithBodyId::FunctionId(f) => Some(f.into()), - DefWithBodyId::StaticId(_) => None, - DefWithBodyId::ConstId(f) => Some(f.into()), - DefWithBodyId::VariantId(f) => Some(f.into()), - }; - let generics = g_def.map(|g_def| generics(db.upcast(), g_def)); + let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def)); let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner }; filler.fill_body(&mut body)?; Ok(body)