Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/diagnostics.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/diagnostics.rs | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/crates/hir-ty/src/infer/diagnostics.rs b/crates/hir-ty/src/infer/diagnostics.rs index 2bdc6f9491..dd0efea4d7 100644 --- a/crates/hir-ty/src/infer/diagnostics.rs +++ b/crates/hir-ty/src/infer/diagnostics.rs @@ -2,22 +2,28 @@ //! and a wrapper around [`TyLoweringContext`] ([`InferenceTyLoweringContext`]) that replaces //! it and takes care of diagnostics in inference. -use std::cell::RefCell; +use std::cell::{OnceCell, RefCell}; use std::ops::{Deref, DerefMut}; use either::Either; -use hir_def::GenericDefId; -use hir_def::expr_store::ExpressionStore; use hir_def::expr_store::path::Path; +use hir_def::{ExpressionStoreOwnerId, GenericDefId}; +use hir_def::{expr_store::ExpressionStore, type_ref::TypeRefId}; use hir_def::{hir::ExprOrPatId, resolver::Resolver}; use la_arena::{Idx, RawIdx}; +use rustc_hash::FxHashMap; use thin_vec::ThinVec; use crate::{ - InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringDiagnostic, - db::HirDatabase, - lower::path::{PathDiagnosticCallback, PathLoweringContext}, - lower::{LifetimeElisionKind, TyLoweringContext}, + InferenceDiagnostic, InferenceTyDiagnosticSource, Span, TyLoweringDiagnostic, + db::{AnonConstId, HirDatabase}, + generics::Generics, + infer::unify::InferenceTable, + lower::{ + ForbidParamsAfterReason, LifetimeElisionKind, TyLoweringContext, TyLoweringInferVarsCtx, + path::{PathDiagnosticCallback, PathLoweringContext}, + }, + next_solver::{Const, Region, StoredTy, Ty}, }; // Unfortunately, this struct needs to use interior mutability (but we encapsulate it) @@ -35,7 +41,7 @@ impl Diagnostics { fn push_ty_diagnostics( &self, source: InferenceTyDiagnosticSource, - diagnostics: Vec<TyLoweringDiagnostic>, + diagnostics: ThinVec<TyLoweringDiagnostic>, ) { self.0.borrow_mut().extend( diagnostics.into_iter().map(|diag| InferenceDiagnostic::TyDiagnostic { source, diag }), @@ -52,10 +58,38 @@ pub(crate) struct PathDiagnosticCallbackData<'a> { diagnostics: &'a Diagnostics, } +pub(super) struct InferenceTyLoweringVarsCtx<'a, 'db> { + pub(super) table: &'a mut InferenceTable<'db>, + pub(super) type_of_type_placeholder: &'a mut FxHashMap<TypeRefId, StoredTy>, +} + +impl<'db> TyLoweringInferVarsCtx<'db> for InferenceTyLoweringVarsCtx<'_, 'db> { + fn next_ty_var(&mut self, span: Span) -> Ty<'db> { + let ty = self.table.infer_ctxt.next_ty_var(span); + + if let Span::TypeRefId(type_ref) = span { + self.type_of_type_placeholder.insert(type_ref, ty.store()); + } + + ty + } + fn next_const_var(&mut self, span: Span) -> Const<'db> { + self.table.infer_ctxt.next_const_var(span) + } + fn next_region_var(&mut self, span: Span) -> Region<'db> { + self.table.infer_ctxt.next_region_var(span) + } + + fn as_table(&mut self) -> Option<&mut InferenceTable<'db>> { + Some(self.table) + } +} + pub(super) struct InferenceTyLoweringContext<'db, 'a> { ctx: TyLoweringContext<'db, 'a>, diagnostics: &'a Diagnostics, source: InferenceTyDiagnosticSource, + defined_anon_consts: &'a RefCell<ThinVec<AnonConstId>>, } impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { @@ -66,14 +100,28 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { store: &'a ExpressionStore, diagnostics: &'a Diagnostics, source: InferenceTyDiagnosticSource, + def: ExpressionStoreOwnerId, generic_def: GenericDefId, + generics: &'a OnceCell<Generics<'db>>, lifetime_elision: LifetimeElisionKind<'db>, + allow_using_generic_params: bool, + infer_vars: Option<&'a mut dyn TyLoweringInferVarsCtx<'db>>, + defined_anon_consts: &'a RefCell<ThinVec<AnonConstId>>, ) -> Self { - Self { - ctx: TyLoweringContext::new(db, resolver, store, generic_def, lifetime_elision), - diagnostics, - source, + let mut ctx = TyLoweringContext::new( + db, + resolver, + store, + def, + generic_def, + generics, + lifetime_elision, + ) + .with_infer_vars_behavior(infer_vars); + if !allow_using_generic_params { + ctx.forbid_params_after(0, ForbidParamsAfterReason::AnonConst); } + Self { ctx, diagnostics, source, defined_anon_consts } } #[inline] @@ -135,5 +183,6 @@ impl Drop for InferenceTyLoweringContext<'_, '_> { fn drop(&mut self) { self.diagnostics .push_ty_diagnostics(self.source, std::mem::take(&mut self.ctx.diagnostics)); + self.defined_anon_consts.borrow_mut().extend(self.ctx.defined_anon_consts.iter().copied()); } } |