Skip to content

Commit ed2ae94

Browse files
authored
Merge pull request #19894 from ShoyuVanilla/some-query-cycles
fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics`
2 parents 9edac77 + fefe867 commit ed2ae94

File tree

5 files changed

+72
-7
lines changed

5 files changed

+72
-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: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,3 +2301,51 @@ trait Foo {
23012301
"#]],
23022302
);
23032303
}
2304+
2305+
#[test]
2306+
fn no_panic_on_recursive_const() {
2307+
check_infer(
2308+
r#"
2309+
struct Foo<const N: usize> {}
2310+
impl<const N: Foo<N>> Foo<N> {
2311+
fn foo(self) {}
2312+
}
2313+
2314+
fn test() {
2315+
let _ = N;
2316+
}
2317+
"#,
2318+
expect![[r#"
2319+
72..76 'self': Foo<N>
2320+
78..80 '{}': ()
2321+
94..112 '{ ...= N; }': ()
2322+
104..105 '_': {unknown}
2323+
108..109 'N': {unknown}
2324+
"#]],
2325+
);
2326+
2327+
check_infer(
2328+
r#"
2329+
struct Foo<const N: usize>;
2330+
const N: Foo<N> = Foo;
2331+
2332+
impl<const N: usize> Foo<N> {
2333+
fn foo(self) -> usize {
2334+
N
2335+
}
2336+
}
2337+
2338+
fn test() {
2339+
let _ = N;
2340+
}
2341+
"#,
2342+
expect![[r#"
2343+
93..97 'self': Foo<N>
2344+
108..125 '{ ... }': usize
2345+
118..119 'N': usize
2346+
139..157 '{ ...= N; }': ()
2347+
149..150 '_': Foo<_>
2348+
153..154 'N': Foo<_>
2349+
"#]],
2350+
);
2351+
}

0 commit comments

Comments
 (0)