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.rs73
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());
}
}