Skip to content

Commit 0623bb4

Browse files
committed
Test for a Salsa bug
1 parent 0d40ff5 commit 0623bb4

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

crates/hir_ty/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ impl ProjectionTy {
106106
}
107107
}
108108

109+
pub fn self_type_parameter(&self) -> &Ty {
110+
&self.substitution[0]
111+
}
112+
109113
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
110114
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
111115
AssocContainerId::TraitId(it) => it,

crates/hir_ty/src/tests.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,72 @@ fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
369369
actual.push('\n');
370370
expect.assert_eq(&actual);
371371
}
372+
373+
#[test]
374+
fn 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+
}

crates/hir_ty/src/tests/traits.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,57 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
22712271
);
22722272
}
22732273

2274+
#[test]
2275+
fn 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
2281+
trait Trait {
2282+
type Item;
2283+
type OtherItem;
2284+
}
2285+
2286+
fn test<T>() where T: Trait<OtherItem = T::Item> {
2287+
let x: T::Item = no_matter;
2288+
} //^ {unknown}
2289+
"#,
2290+
);
2291+
}
2292+
2293+
#[test]
2294+
fn unselected_projection_in_trait_env_no_cycle() {
2295+
// this is not a cycle
2296+
check_types(
2297+
r#"
2298+
//- /main.rs
2299+
trait Index {
2300+
type Output;
2301+
}
2302+
2303+
type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
2304+
2305+
pub trait UnificationStoreBase: Index<Output = Key<Self>> {
2306+
type Key;
2307+
2308+
fn len(&self) -> usize;
2309+
}
2310+
2311+
pub trait UnificationStoreMut: UnificationStoreBase {
2312+
fn push(&mut self, value: Self::Key);
2313+
}
2314+
2315+
fn 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+
22742325
#[test]
22752326
fn inline_assoc_type_bounds_1() {
22762327
check_types(

0 commit comments

Comments
 (0)