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.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 555b6972fb..7995f6446d 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -3963,3 +3963,160 @@ 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
+ "#]],
+ );
+}
+
+#[test]
+fn gats_in_associated_type_binding() {
+ check_infer_with_mismatches(
+ r#"
+trait Trait {
+ type Assoc<T>;
+ fn get<U>(&self) -> Self::Assoc<U>;
+}
+
+fn f<T>(t: T)
+where
+ T: Trait<Assoc<i32> = u32>,
+ T: Trait<Assoc<isize> = usize>,
+{
+ let a = t.get::<i32>();
+ let a = t.get::<isize>();
+ let a = t.get::<()>();
+}
+
+ "#,
+ expect![[r#"
+ 48..52 'self': &Self
+ 84..85 't': T
+ 164..252 '{ ...>(); }': ()
+ 174..175 'a': u32
+ 178..179 't': T
+ 178..192 't.get::<i32>()': u32
+ 202..203 'a': usize
+ 206..207 't': T
+ 206..222 't.get:...ize>()': usize
+ 232..233 'a': Trait::Assoc<(), T>
+ 236..237 't': T
+ 236..249 't.get::<()>()': Trait::Assoc<(), T>
+ "#]],
+ )
+}