Skip to content

Commit f9536b4

Browse files
committed
fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics
1 parent 6feb662 commit f9536b4

File tree

7 files changed

+61
-7
lines changed

7 files changed

+61
-7
lines changed

crates/hir-ty/src/db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::{
3131
#[query_group::query_group]
3232
pub trait HirDatabase: DefDatabase + std::fmt::Debug {
3333
#[salsa::invoke(crate::infer::infer_query)]
34+
#[salsa::cycle(cycle_result = crate::infer::infer_cycle_result)]
3435
fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
3536

3637
// region:mir
@@ -132,6 +133,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
132133

133134
// FIXME: Make this a non-interned query.
134135
#[salsa::invoke_interned(crate::lower::const_param_ty_with_diagnostics_query)]
136+
#[salsa::cycle(cycle_result = crate::lower::const_param_ty_with_diagnostics_cycle_result)]
135137
fn const_param_ty_with_diagnostics(&self, def: ConstParamId) -> (Ty, Diagnostics);
136138

137139
#[salsa::invoke(crate::lower::const_param_ty_query)]

crates/hir-ty/src/infer.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
135135
Arc::new(ctx.resolve_all())
136136
}
137137

138+
pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
139+
Arc::new(InferenceResult { has_errors: true, ..Default::default() })
140+
}
141+
138142
/// Fully normalize all the types found within `ty` in context of `owner` body definition.
139143
///
140144
/// This is appropriate to use only after type-check: it assumes
@@ -558,6 +562,9 @@ impl InferenceResult {
558562
ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
559563
}
560564
}
565+
pub fn is_erroneous(&self) -> bool {
566+
self.has_errors && self.type_of_expr.iter().count() == 0
567+
}
561568
}
562569

563570
impl Index<ExprId> for InferenceResult {

crates/hir-ty/src/lower.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,14 @@ pub(crate) fn impl_self_ty_with_diagnostics_query(
16041604
)
16051605
}
16061606

1607+
pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
1608+
db: &dyn HirDatabase,
1609+
impl_id: ImplId,
1610+
) -> (Binders<Ty>, Diagnostics) {
1611+
let generics = generics(db, impl_id.into());
1612+
(make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
1613+
}
1614+
16071615
pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
16081616
db.const_param_ty_with_diagnostics(def).0
16091617
}
@@ -1633,12 +1641,12 @@ pub(crate) fn const_param_ty_with_diagnostics_query(
16331641
(ty, create_diagnostics(ctx.diagnostics))
16341642
}
16351643

1636-
pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
1637-
db: &dyn HirDatabase,
1638-
impl_id: ImplId,
1639-
) -> (Binders<Ty>, Diagnostics) {
1640-
let generics = generics(db, impl_id.into());
1641-
(make_binders(db, &generics, TyKind::Error.intern(Interner)), None)
1644+
pub(crate) fn const_param_ty_with_diagnostics_cycle_result(
1645+
_: &dyn HirDatabase,
1646+
_: crate::db::HirDatabaseData,
1647+
_: ConstParamId,
1648+
) -> (Ty, Diagnostics) {
1649+
(TyKind::Error.intern(Interner), None)
16421650
}
16431651

16441652
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {

crates/hir-ty/src/mir/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2182,7 +2182,7 @@ pub fn lower_to_mir(
21822182
// need to take this input explicitly.
21832183
root_expr: ExprId,
21842184
) -> Result<MirBody> {
2185-
if infer.type_mismatches().next().is_some() {
2185+
if infer.type_mismatches().next().is_some() || infer.is_erroneous() {
21862186
return Err(MirLowerError::HasErrors);
21872187
}
21882188
let mut ctx = MirLowerCtx::new(db, owner, body, infer);

crates/hir-ty/src/tests/regression.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,3 +2301,20 @@ trait Foo {
23012301
"#]],
23022302
);
23032303
}
2304+
2305+
#[test]
2306+
fn barbaz() {
2307+
check_infer(
2308+
r#"
2309+
struct Foo<const N: usize>;
2310+
const N: Foo<N> = Foo;
2311+
2312+
fn wtf() {
2313+
let x = N;
2314+
let y = wf;
2315+
}
2316+
"#,
2317+
expect![[r#"
2318+
"#]],
2319+
);
2320+
}

crates/ide-diagnostics/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(clippy::print_stderr)]
22

33
mod overly_long_real_world_cases;
4+
mod tests_that_need_diagnostics_trigger;
45

56
use ide_db::{
67
LineIndexDatabase, RootDatabase,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use super::{check_diagnostics, check_diagnostics_with_disabled};
2+
3+
#[test]
4+
fn recursive_const_should_not_panic() {
5+
check_diagnostics_with_disabled(
6+
r#"
7+
struct Foo<const N: usize> {}
8+
impl <const N: Foo<N
9+
"#,
10+
&["syntax-error"],
11+
);
12+
13+
check_diagnostics(
14+
r#"
15+
struct Foo<const N: usize>;
16+
const N: Foo<N> = Foo;
17+
"#,
18+
);
19+
}

0 commit comments

Comments
 (0)