aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-03-20 14:26:42 +0000
committerFlorian Diebold <[email protected]>2021-03-21 12:33:06 +0000
commit0623bb4d71725d6b07e8cef5665094581f951fc0 (patch)
tree748724d956efcb09be31d299dcecb90e1830142b /crates
parent0d40ff5e623b3670ce3e0e324ecbab3e5197aaeb (diff)
Test for a Salsa bug
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/lib.rs4
-rw-r--r--crates/hir_ty/src/tests.rs69
-rw-r--r--crates/hir_ty/src/tests/traits.rs51
3 files changed, 124 insertions, 0 deletions
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 {
106 } 106 }
107 } 107 }
108 108
109 pub fn self_type_parameter(&self) -> &Ty {
110 &self.substitution[0]
111 }
112
109 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 113 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
110 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { 114 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
111 AssocContainerId::TraitId(it) => it, 115 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) {
369 actual.push('\n'); 369 actual.push('\n');
370 expect.assert_eq(&actual); 370 expect.assert_eq(&actual);
371} 371}
372
373#[test]
374fn salsa_bug() {
375 let (mut db, pos) = TestDB::with_position(
376 "
377 //- /lib.rs
378 trait Index {
379 type Output;
380 }
381
382 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
383
384 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
385 type Key;
386
387 fn len(&self) -> usize;
388 }
389
390 pub trait UnificationStoreMut: UnificationStoreBase {
391 fn push(&mut self, value: Self::Key);
392 }
393
394 fn main() {
395 let x = 1;
396 x.push(1);$0
397 }
398 ",
399 );
400
401 let module = db.module_for_file(pos.file_id);
402 let crate_def_map = module.def_map(&db);
403 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
404 db.infer(def);
405 });
406
407 let new_text = "
408 //- /lib.rs
409 trait Index {
410 type Output;
411 }
412
413 type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
414
415 pub trait UnificationStoreBase: Index<Output = Key<Self>> {
416 type Key;
417
418 fn len(&self) -> usize;
419 }
420
421 pub trait UnificationStoreMut: UnificationStoreBase {
422 fn push(&mut self, value: Self::Key);
423 }
424
425 fn main() {
426
427 let x = 1;
428 x.push(1);
429 }
430 "
431 .to_string();
432
433 db.set_file_text(pos.file_id, Arc::new(new_text));
434
435 let module = db.module_for_file(pos.file_id);
436 let crate_def_map = module.def_map(&db);
437 visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
438 db.infer(def);
439 });
440}
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
@@ -2272,6 +2272,57 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
2272} 2272}
2273 2273
2274#[test] 2274#[test]
2275fn unselected_projection_in_trait_env_cycle_3() {
2276 // this is a cycle, although it would be possible to handle if we didn't go
2277 // into bindings when looking for traits
2278 check_types(
2279 r#"
2280//- /main.rs
2281trait Trait {
2282 type Item;
2283 type OtherItem;
2284}
2285
2286fn test<T>() where T: Trait<OtherItem = T::Item> {
2287 let x: T::Item = no_matter;
2288} //^ {unknown}
2289"#,
2290 );
2291}
2292
2293#[test]
2294fn unselected_projection_in_trait_env_no_cycle() {
2295 // this is not a cycle
2296 check_types(
2297 r#"
2298//- /main.rs
2299trait Index {
2300 type Output;
2301}
2302
2303type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
2304
2305pub trait UnificationStoreBase: Index<Output = Key<Self>> {
2306 type Key;
2307
2308 fn len(&self) -> usize;
2309}
2310
2311pub trait UnificationStoreMut: UnificationStoreBase {
2312 fn push(&mut self, value: Self::Key);
2313}
2314
2315fn test<T>(t: T) where T: UnificationStoreMut {
2316 let x;
2317 t.push(x);
2318 let y: Key<T>;
2319 (x, y);
2320} //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
2321"#,
2322 );
2323}
2324
2325#[test]
2275fn inline_assoc_type_bounds_1() { 2326fn inline_assoc_type_bounds_1() {
2276 check_types( 2327 check_types(
2277 r#" 2328 r#"