Skip to content

Commit 98fb8c6

Browse files
Handle cycles in RPITIT computation
Cycles can occur in malformed code (this is only a conjecture) or from Chalk bugs (for this I have a test).
1 parent b96c6e0 commit 98fb8c6

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

crates/hir-ty/src/chalk_db.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use chalk_ir::{
1313
cast::{Cast, Caster},
1414
fold::shift::Shift,
1515
};
16-
use chalk_solve::rust_ir::{self, AssociatedTyDatumBound, OpaqueTyDatumBound, WellKnownTrait};
16+
use chalk_solve::rust_ir::{
17+
self, AssociatedTyDatumBound, AssociatedTyValueBound, OpaqueTyDatumBound, WellKnownTrait,
18+
};
1719

1820
use base_db::Crate;
1921
use hir_def::{
@@ -1008,6 +1010,31 @@ pub(crate) fn associated_ty_value_query(
10081010
}
10091011
}
10101012

1013+
/// We need cycle recovery because RPITITs can cause cycles.
1014+
pub(crate) fn associated_ty_value_cycle(
1015+
db: &dyn HirDatabase,
1016+
krate: Crate,
1017+
id: AssociatedTyValueId,
1018+
) -> Arc<AssociatedTyValue> {
1019+
match from_assoc_type_value_id(db, id) {
1020+
AnyImplAssocType::Normal(type_alias) => {
1021+
type_alias_associated_ty_value(db, krate, type_alias)
1022+
}
1023+
AnyImplAssocType::Rpitit(assoc_type_id) => {
1024+
let assoc = assoc_type_id.loc(db);
1025+
let trait_assoc = assoc.trait_assoc.loc(db);
1026+
Arc::new(AssociatedTyValue {
1027+
associated_ty_id: to_assoc_type_id_rpitit(assoc.trait_assoc),
1028+
impl_id: assoc.impl_id.to_chalk(db),
1029+
value: trait_assoc
1030+
.bounds
1031+
.as_ref()
1032+
.map(|_| AssociatedTyValueBound { ty: TyKind::Error.intern(Interner) }),
1033+
})
1034+
}
1035+
}
1036+
}
1037+
10111038
fn rpitit_associated_ty_value(
10121039
db: &dyn HirDatabase,
10131040
assoc_type_id: RpititImplAssocTyId,

crates/hir-ty/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug {
290290
fn variances_of(&self, def: GenericDefId) -> Option<Arc<[crate::variance::Variance]>>;
291291

292292
#[salsa::invoke(chalk_db::associated_ty_value_query)]
293+
#[salsa::cycle(cycle_result = chalk_db::associated_ty_value_cycle)]
293294
fn associated_ty_value(
294295
&self,
295296
krate: Crate,

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5141,7 +5141,10 @@ impl<T, U> Trait<(Foo<()>, U)> for Foo<T> {}
51415141
}
51425142

51435143
#[test]
5144-
fn check_foo() {
5144+
fn rpitit_cycle() {
5145+
// This shouldn't cause a cycle, but it does due to Chalk shortcomings. It should be
5146+
// fixed when we switch to the new trait solver. However, I believe it will still possible
5147+
// to cause cycles with malformed code, so we still need the cycle handlers.
51455148
check_rpitit(
51465149
r#"
51475150
//- minicore: future, send, sized
@@ -5153,6 +5156,10 @@ trait DesugaredAsyncTrait {
51535156
51545157
impl DesugaredAsyncTrait for () {}
51555158
"#,
5156-
expect![[r#""#]],
5159+
expect![[r#"
5160+
type __foo_rpitit: Future<Output = usize> + Send;
5161+
5162+
type __foo_rpitit = {unknown};
5163+
"#]],
51575164
);
51585165
}

0 commit comments

Comments
 (0)