Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/tests/traits.rs')
| -rw-r--r-- | crates/hir-ty/src/tests/traits.rs | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 555b6972fb..2b8468e85a 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -3963,3 +3963,123 @@ fn g(t: &(dyn T + Send)) { "#, ); } + +#[test] +fn gats_in_path() { + check_infer_with_mismatches( + r#" +//- minicore: deref +use core::ops::Deref; +trait PointerFamily { + type Pointer<T>: Deref<Target = T>; +} + +fn f<P: PointerFamily>(p: P::Pointer<i32>) { + let a = *p; +} +fn g<P: PointerFamily>(p: <P as PointerFamily>::Pointer<i32>) { + let a = *p; +} + "#, + expect![[r#" + 110..111 'p': PointerFamily::Pointer<i32, P> + 130..149 '{ ... *p; }': () + 140..141 'a': i32 + 144..146 '*p': i32 + 145..146 'p': PointerFamily::Pointer<i32, P> + 173..174 'p': PointerFamily::Pointer<i32, P> + 212..231 '{ ... *p; }': () + 222..223 'a': i32 + 226..228 '*p': i32 + 227..228 'p': PointerFamily::Pointer<i32, P> + "#]], + ); +} + +#[test] +fn gats_with_impl_trait() { + // FIXME: the last function (`fn h()`) is not valid Rust as of this writing because you cannot + // specify the same associated type multiple times even if their arguments are different. + // Reconsider how to treat these invalid types. + check_infer_with_mismatches( + r#" +//- minicore: deref +use core::ops::Deref; + +trait Trait { + type Assoc<T>: Deref<Target = T>; + fn get<U>(&self) -> Self::Assoc<U>; +} + +fn f<T>(v: impl Trait) { + v.get::<i32>().deref(); + v.get::<T>().deref(); +} +fn g<T>(v: impl Trait<Assoc<T> = &'a T>) { + let a = v.get::<T>(); + let a = v.get::<()>(); +} +fn h(v: impl Trait<Assoc<i32> = &'a i32, Assoc<i64> = &'a i64> { + let a = v.get::<i32>(); + let a = v.get::<i64>(); +} + "#, + expect![[r#" + 90..94 'self': &Self + 126..127 'v': impl Trait + 141..198 '{ ...f(); }': () + 147..148 'v': impl Trait + 147..161 'v.get::<i32>()': Trait::Assoc<i32, impl Trait> + 147..169 'v.get:...eref()': &i32 + 175..176 'v': impl Trait + 175..187 'v.get::<T>()': Trait::Assoc<T, impl Trait> + 175..195 'v.get:...eref()': &T + 207..208 'v': impl Trait<Assoc<T> = &T> + 240..296 '{ ...>(); }': () + 250..251 'a': &T + 254..255 'v': impl Trait<Assoc<T> = &T> + 254..266 'v.get::<T>()': &T + 276..277 'a': Trait::Assoc<(), impl Trait<Assoc<T> = &T>> + 280..281 'v': impl Trait<Assoc<T> = &T> + 280..293 'v.get::<()>()': Trait::Assoc<(), impl Trait<Assoc<T> = &T>> + 302..303 'v': impl Trait<Assoc<i32> = &i32, Assoc<i64> = &i64> + 360..419 '{ ...>(); }': () + 370..371 'a': &i32 + 374..375 'v': impl Trait<Assoc<i32> = &i32, Assoc<i64> = &i64> + 374..388 'v.get::<i32>()': &i32 + 398..399 'a': &i64 + 402..403 'v': impl Trait<Assoc<i32> = &i32, Assoc<i64> = &i64> + 402..416 'v.get::<i64>()': &i64 + "#]], + ); +} + +#[test] +fn gats_with_dyn() { + // This test is here to keep track of how we infer things despite traits with GATs being not + // object-safe currently. + // FIXME: reconsider how to treat these invalid types. + check_infer_with_mismatches( + r#" +//- minicore: deref +use core::ops::Deref; + +trait Trait { + type Assoc<T>: Deref<Target = T>; + fn get<U>(&self) -> Self::Assoc<U>; +} + +fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) { + v.get::<i32>().deref(); +} + "#, + expect![[r#" + 90..94 'self': &Self + 127..128 'v': &(dyn Trait<Assoc<i32> = &i32>) + 164..195 '{ ...f(); }': () + 170..171 'v': &(dyn Trait<Assoc<i32> = &i32>) + 170..184 'v.get::<i32>()': &i32 + 170..192 'v.get:...eref()': &i32 + "#]], + ); +} |