diff options
| author | Lukas Wirth <me@lukaswirth.dev> | 2025-06-03 06:08:46 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-03 06:08:46 +0000 |
| commit | e179d2bdb7a4d80d9edfda2fc18fb415cfca307f (patch) | |
| tree | 595e775bbebeec8dc687f5a93d0a5d389865c279 /src/tools | |
| parent | ae8e3611fc3102cc55f5d709720966a43e9ba898 (diff) | |
| parent | ddcc1afd4de546ec4c6b2cc7d3027c6a37f23caf (diff) | |
| download | rust-e179d2bdb7a4d80d9edfda2fc18fb415cfca307f.tar.gz rust-e179d2bdb7a4d80d9edfda2fc18fb415cfca307f.zip | |
Merge pull request #19894 from ShoyuVanilla/some-query-cycles
fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics`
Diffstat (limited to 'src/tools')
5 files changed, 72 insertions, 7 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs index 980ee264b02..1e985dc604e 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index e698fb201cb..840a916c24a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index ea8e7cc2be9..0a546768dab 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs index e6caf2d8d97..99d93515303 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 47c695c6974..ff8adeef1db 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/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<_> + "#]], + ); +} |
