diff options
Diffstat (limited to 'src/tools/rust-analyzer')
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<_> + "#]], + ); +} |
