mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 11:20:54 +00:00
fix: Cycle handlers for `HirDatabase::infer, const_param_ty_with_diagnostics
This commit is contained in:
parent
25808c1ba1
commit
fefe86732d
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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>> {
|
||||
|
@ -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);
|
||||
|
@ -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<_>
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user