Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lower.rs')
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 61329f6c88..2c41b568d3 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -39,7 +39,7 @@ use la_arena::{Arena, ArenaMap, Idx}; use path::{PathDiagnosticCallback, PathLoweringContext}; use rustc_abi::ExternAbi; use rustc_ast_ir::Mutability; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashSet; use rustc_type_ir::{ AliasTyKind, BoundVarIndexKind, DebruijnIndex, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, Interner, OutlivesPredicate, TermKind, TyKind, TypeFoldable, @@ -185,10 +185,15 @@ pub(crate) enum ForbidParamsAfterReason { ConstParamTy, } -pub(crate) struct TyLoweringInferVarsCtx<'a, 'db> { - // Technically we can just put an `&InferCtxt` here, but borrowck constraints requires us to put this: - pub(crate) table: &'a mut InferenceTable<'db>, - pub(crate) type_of_placeholder: &'a mut FxHashMap<TypeRefId, StoredTy>, +pub trait TyLoweringInferVarsCtx<'db> { + fn next_ty_var(&mut self, span: Span) -> Ty<'db>; + fn next_const_var(&mut self, span: Span) -> Const<'db>; + fn next_region_var(&mut self, span: Span) -> Region<'db>; + + #[expect(private_interfaces)] + fn as_table(&mut self) -> Option<&mut InferenceTable<'db>> { + None + } } pub struct TyLoweringContext<'db, 'a> { @@ -210,7 +215,7 @@ pub struct TyLoweringContext<'db, 'a> { forbid_params_after: Option<u32>, forbid_params_after_reason: ForbidParamsAfterReason, pub(crate) defined_anon_consts: ThinVec<AnonConstId>, - infer_vars: Option<TyLoweringInferVarsCtx<'a, 'db>>, + infer_vars: Option<&'a mut dyn TyLoweringInferVarsCtx<'db>>, } impl<'db, 'a> TyLoweringContext<'db, 'a> { @@ -286,9 +291,9 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { self.forbid_params_after_reason = reason; } - pub(crate) fn with_infer_vars_behavior( + pub fn with_infer_vars_behavior( mut self, - behavior: Option<TyLoweringInferVarsCtx<'a, 'db>>, + behavior: Option<&'a mut dyn TyLoweringInferVarsCtx<'db>>, ) -> Self { self.infer_vars = behavior; self @@ -300,26 +305,12 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { #[track_caller] pub(crate) fn expect_table(&mut self) -> &mut InferenceTable<'db> { - self.infer_vars.as_mut().unwrap().table - } - - fn next_ty_var(&mut self, type_ref: TypeRefId) -> Ty<'db> { - match &mut self.infer_vars { - Some(infer_vars) => { - let var = infer_vars.table.next_ty_var(type_ref.into()); - infer_vars.type_of_placeholder.insert(type_ref, var.store()); - var - } - None => { - // FIXME: Emit an error: no infer vars allowed here. - self.types.types.error - } - } + self.infer_vars.as_mut().unwrap().as_table().unwrap() } - fn next_ty_var_no_placeholder(&mut self, span: Span) -> Ty<'db> { + fn next_ty_var(&mut self, span: Span) -> Ty<'db> { match &mut self.infer_vars { - Some(infer_vars) => infer_vars.table.next_ty_var(span), + Some(infer_vars) => infer_vars.next_ty_var(span), None => { // FIXME: Emit an error: no infer vars allowed here. self.types.types.error @@ -329,7 +320,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { fn next_const_var(&mut self, span: Span) -> Const<'db> { match &mut self.infer_vars { - Some(infer_vars) => infer_vars.table.next_const_var(span), + Some(infer_vars) => infer_vars.next_const_var(span), None => { // FIXME: Emit an error: no infer vars allowed here. self.types.consts.error @@ -339,7 +330,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { fn next_region_var(&mut self, span: Span) -> Region<'db> { match &mut self.infer_vars { - Some(infer_vars) => infer_vars.table.next_region_var(span), + Some(infer_vars) => infer_vars.next_region_var(span), None => { // FIXME: Emit an error: no infer vars allowed here. self.types.regions.error @@ -366,6 +357,13 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> { + #[expect(clippy::manual_map, reason = "a `map()` here generates a borrowck error")] + let create_var = match &mut self.infer_vars { + Some(infer_vars) => Some( + (&mut |span| infer_vars.next_const_var(span)) as &mut dyn FnMut(Span) -> Const<'db>, + ), + None => None, + }; let konst = create_anon_const( self.interner, self.def, @@ -373,8 +371,8 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { const_ref.expr, self.resolver, const_type, - &|| self.generics(), - self.infer_vars.as_ref().map(|vars_ctx| &vars_ctx.table.infer_ctxt), + &|| self.generics.get_or_init(|| generics(self.db, self.generic_def)), + create_var, self.forbid_params_after, ); @@ -470,7 +468,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { ref_.lifetime.map_or(self.types.regions.error, |lr| self.lower_lifetime(lr)); Ty::new_ref(interner, lifetime, inner_ty, lower_mutability(ref_.mutability)) } - TypeRef::Placeholder => self.next_ty_var(type_ref_id), + TypeRef::Placeholder => self.next_ty_var(type_ref_id.into()), TypeRef::Fn(fn_) => self.lower_fn_ptr(fn_), TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds), TypeRef::ImplTrait(bounds) => { |