Unnamed repository; edit this file 'description' to name the repository.
fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics
Shoyu Vanilla 11 months ago
parent 25808c1 · commit fefe867
-rw-r--r--crates/hir-ty/src/db.rs2
-rw-r--r--crates/hir-ty/src/infer.rs7
-rw-r--r--crates/hir-ty/src/lower.rs20
-rw-r--r--crates/hir-ty/src/mir/lower.rs2
-rw-r--r--crates/hir-ty/src/tests/regression.rs48
5 files changed, 72 insertions, 7 deletions
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 980ee264b0..1e985dc604 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -31,6 +31,7 @@ use crate::{
#[query_group::query_group]
pub trait HirDatabase: DefDatabase + std::fmt::Debug {
#[salsa::invoke(crate::infer::infer_query)]
+ #[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
// region:mir
@@ -132,6 +133,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
// FIXME: Make this a non-interned query.
#[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
+ #[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics);
#[salsa::invoke(crate::lower::const_param_ty_query)]
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index e698fb201c..840a916c24 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -135,6 +135,10 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
Arc::new(ctx.resolve_all())
}
+pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
+ Arc::new(InferenceResult { has_errors: true, ..Default::default() })
+}
+
/// Fully normalize all the types found within `ty` in context of `owner` body definition.
///
/// This is appropriate to use only after type-check: it assumes
@@ -558,6 +562,9 @@ impl InferenceResult {
ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
}
}
+ pub fn is_erroneous(&self) -> bool {
+ self.has_errors && self.type_of_expr.iter().count() == 0
+ }
}
impl Index<ExprId> for InferenceResult {
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index ea8e7cc2be..0a546768da 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -1604,6 +1604,14 @@ pub(crate) fn impl_self_ty_with_diagnostics_query(
)
}
+pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
+ db: &dyn HirDatabase,
+ impl_id: ImplId,
+) -> (Binders<Ty>, Diagnostics) {
+ let generics = generics(db, impl_id.into());
+ (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
+}
+
pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
db.const_param_ty_with_diagnostics(def).0
}
@@ -1633,12 +1641,12 @@ pub(crate) fn const_param_ty_with_diagnostics_query(
(ty, create_diagnostics(ctx.diagnostics))
}
-pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
- db: &dyn HirDatabase,
- impl_id: ImplId,
-) -> (Binders<Ty>, Diagnostics) {
- let generics = generics(db, impl_id.into());
- (make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
+pub(crate) fn const_param_ty_with_diagnostics_cycle_result(
+ _: &dyn HirDatabase,
+ _: crate::db::HirDatabaseData,
+ _: ConstParamId,
+) -> (Ty, Diagnostics) {
+ (TyKind::Error.intern(Interner), None)
}
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index e6caf2d8d9..99d9351530 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -2182,7 +2182,7 @@ pub fn lower_to_mir(
// need to take this input explicitly.
root_expr: ExprId,
) -> Result<MirBody> {
- if infer.type_mismatches().next().is_some() {
+ if infer.type_mismatches().next().is_some() || infer.is_erroneous() {
return Err(MirLowerError::HasErrors);
}
let mut ctx = MirLowerCtx::new(db, owner, body, infer);
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 47c695c697..ff8adeef1d 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2301,3 +2301,51 @@ trait Foo {
"#]],
);
}
+
+#[test]
+fn no_panic_on_recursive_const() {
+ check_infer(
+ r#"
+struct Foo<const N: usize> {}
+impl<const N: Foo<N>> Foo<N> {
+ fn foo(self) {}
+}
+
+fn test() {
+ let _ = N;
+}
+"#,
+ expect![[r#"
+ 72..76 'self': Foo<N>
+ 78..80 '{}': ()
+ 94..112 '{ ...= N; }': ()
+ 104..105 '_': {unknown}
+ 108..109 'N': {unknown}
+ "#]],
+ );
+
+ check_infer(
+ r#"
+struct Foo<const N: usize>;
+const N: Foo<N> = Foo;
+
+impl<const N: usize> Foo<N> {
+ fn foo(self) -> usize {
+ N
+ }
+}
+
+fn test() {
+ let _ = N;
+}
+"#,
+ expect![[r#"
+ 93..97 'self': Foo<N>
+ 108..125 '{ ... }': usize
+ 118..119 'N': usize
+ 139..157 '{ ...= N; }': ()
+ 149..150 '_': Foo<_>
+ 153..154 'N': Foo<_>
+ "#]],
+ );
+}