From 0623bb4d71725d6b07e8cef5665094581f951fc0 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 20 Mar 2021 15:26:42 +0100 Subject: Test for a Salsa bug --- crates/hir_ty/src/lib.rs | 4 +++ crates/hir_ty/src/tests.rs | 69 +++++++++++++++++++++++++++++++++++++++ crates/hir_ty/src/tests/traits.rs | 51 +++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index c46529879..815bb8418 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -106,6 +106,10 @@ impl ProjectionTy { } } + pub fn self_type_parameter(&self) -> &Ty { + &self.substitution[0] + } + fn trait_(&self, db: &dyn HirDatabase) -> TraitId { match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { AssocContainerId::TraitId(it) => it, diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 0a4141e69..ad283c1e0 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs @@ -369,3 +369,72 @@ fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) { actual.push('\n'); expect.assert_eq(&actual); } + +#[test] +fn salsa_bug() { + let (mut db, pos) = TestDB::with_position( + " + //- /lib.rs + trait Index { + type Output; + } + + type Key = ::Key; + + pub trait UnificationStoreBase: Index> { + type Key; + + fn len(&self) -> usize; + } + + pub trait UnificationStoreMut: UnificationStoreBase { + fn push(&mut self, value: Self::Key); + } + + fn main() { + let x = 1; + x.push(1);$0 + } + ", + ); + + let module = db.module_for_file(pos.file_id); + let crate_def_map = module.def_map(&db); + visit_module(&db, &crate_def_map, module.local_id, &mut |def| { + db.infer(def); + }); + + let new_text = " + //- /lib.rs + trait Index { + type Output; + } + + type Key = ::Key; + + pub trait UnificationStoreBase: Index> { + type Key; + + fn len(&self) -> usize; + } + + pub trait UnificationStoreMut: UnificationStoreBase { + fn push(&mut self, value: Self::Key); + } + + fn main() { + + let x = 1; + x.push(1); + } + " + .to_string(); + + db.set_file_text(pos.file_id, Arc::new(new_text)); + + let module = db.module_for_file(pos.file_id); + let crate_def_map = module.def_map(&db); + visit_module(&db, &crate_def_map, module.local_id, &mut |def| { + db.infer(def); + }); +} diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 8f2bdffc0..1bb6dff95 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -2271,6 +2271,57 @@ fn test() where T: Trait, U: Trait { ); } +#[test] +fn unselected_projection_in_trait_env_cycle_3() { + // this is a cycle, although it would be possible to handle if we didn't go + // into bindings when looking for traits + check_types( + r#" +//- /main.rs +trait Trait { + type Item; + type OtherItem; +} + +fn test() where T: Trait { + let x: T::Item = no_matter; +} //^ {unknown} +"#, + ); +} + +#[test] +fn unselected_projection_in_trait_env_no_cycle() { + // this is not a cycle + check_types( + r#" +//- /main.rs +trait Index { + type Output; +} + +type Key = ::Key; + +pub trait UnificationStoreBase: Index> { + type Key; + + fn len(&self) -> usize; +} + +pub trait UnificationStoreMut: UnificationStoreBase { + fn push(&mut self, value: Self::Key); +} + +fn test(t: T) where T: UnificationStoreMut { + let x; + t.push(x); + let y: Key; + (x, y); +} //^ (UnificationStoreBase::Key, UnificationStoreBase::Key) +"#, + ); +} + #[test] fn inline_assoc_type_bounds_1() { check_types( -- cgit v1.2.3