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.rs148
1 files changed, 98 insertions, 50 deletions
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index c0e439310e..38591f486e 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -1,4 +1,3 @@
-use cov_mark::check;
use expect_test::expect;
use crate::tests::infer_with_mismatches;
@@ -278,11 +277,11 @@ pub mod collections {
fn infer_ops_neg() {
check_types(
r#"
-//- /main.rs crate:main deps:std
+//- minicore:unary_ops
struct Bar;
struct Foo;
-impl std::ops::Neg for Bar {
+impl core::ops::Neg for Bar {
type Output = Foo;
}
@@ -291,15 +290,6 @@ fn test() {
let b = -a;
b;
} //^ Foo
-
-//- /std.rs crate:std
-#[prelude_import] use ops::*;
-mod ops {
- #[lang = "neg"]
- pub trait Neg {
- type Output;
- }
-}
"#,
);
}
@@ -308,11 +298,11 @@ mod ops {
fn infer_ops_not() {
check_types(
r#"
-//- /main.rs crate:main deps:std
+//- minicore:unary_ops
struct Bar;
struct Foo;
-impl std::ops::Not for Bar {
+impl core::ops::Not for Bar {
type Output = Foo;
}
@@ -321,15 +311,6 @@ fn test() {
let b = !a;
b;
} //^ Foo
-
-//- /std.rs crate:std
-#[prelude_import] use ops::*;
-mod ops {
- #[lang = "not"]
- pub trait Not {
- type Output;
- }
-}
"#,
);
}
@@ -368,7 +349,6 @@ fn test() {
#[test]
fn trait_default_method_self_bound_implements_trait() {
- cov_mark::check!(trait_self_implements_self);
check(
r#"
trait Trait {
@@ -871,7 +851,7 @@ struct S;
trait Trait<T> {}
impl Trait<&str> for S {}
-struct O<T>;
+struct O<T>(T);
impl<U, T: Trait<U>> O<T> {
fn foo(&self) -> U { loop {} }
}
@@ -1211,7 +1191,7 @@ fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
expect![[r#"
29..33 'self': &'? Self
54..58 'self': &'? Self
- 98..100 '{}': impl Trait<u64>
+ 98..100 '{}': ()
110..111 'x': impl Trait<u64>
130..131 'y': &'? impl Trait<u64>
151..268 '{ ...2(); }': ()
@@ -1512,7 +1492,7 @@ fn dyn_trait_in_impl() {
trait Trait<T, U> {
fn foo(&self) -> (T, U);
}
-struct S<T, U> {}
+struct S<T, U>(T, U);
impl<T, U> S<T, U> {
fn bar(&self) -> &dyn Trait<T, U> { loop {} }
}
@@ -1526,16 +1506,16 @@ fn test(s: S<u32, i32>) {
}"#,
expect![[r#"
32..36 'self': &'? Self
- 102..106 'self': &'? S<T, U>
- 128..139 '{ loop {} }': &'? (dyn Trait<T, U> + 'static)
- 130..137 'loop {}': !
- 135..137 '{}': ()
- 175..179 'self': &'? Self
- 251..252 's': S<u32, i32>
- 267..289 '{ ...z(); }': ()
- 273..274 's': S<u32, i32>
- 273..280 's.bar()': &'? (dyn Trait<u32, i32> + 'static)
- 273..286 's.bar().baz()': (u32, i32)
+ 106..110 'self': &'? S<T, U>
+ 132..143 '{ loop {} }': &'? (dyn Trait<T, U> + 'static)
+ 134..141 'loop {}': !
+ 139..141 '{}': ()
+ 179..183 'self': &'? Self
+ 255..256 's': S<u32, i32>
+ 271..293 '{ ...z(); }': ()
+ 277..278 's': S<u32, i32>
+ 277..284 's.bar()': &'? (dyn Trait<u32, i32> + 'static)
+ 277..290 's.bar().baz()': (u32, i32)
"#]],
);
}
@@ -2982,13 +2962,13 @@ fn test() {
140..146 'IsCopy': IsCopy
140..153 'IsCopy.test()': bool
159..166 'NotCopy': NotCopy
- 159..173 'NotCopy.test()': {unknown}
+ 159..173 'NotCopy.test()': bool
179..195 '(IsCop...sCopy)': (IsCopy, IsCopy)
179..202 '(IsCop...test()': bool
180..186 'IsCopy': IsCopy
188..194 'IsCopy': IsCopy
208..225 '(IsCop...tCopy)': (IsCopy, NotCopy)
- 208..232 '(IsCop...test()': {unknown}
+ 208..232 '(IsCop...test()': bool
209..215 'IsCopy': IsCopy
217..224 'NotCopy': NotCopy
"#]],
@@ -3081,7 +3061,7 @@ fn test() {
79..194 '{ ...ized }': ()
85..88 '1u8': u8
85..95 '1u8.test()': bool
- 101..116 '(*"foo").test()': {unknown}
+ 101..116 '(*"foo").test()': bool
102..108 '*"foo"': str
103..108 '"foo"': &'static str
135..145 '(1u8, 1u8)': (u8, u8)
@@ -3089,7 +3069,7 @@ fn test() {
136..139 '1u8': u8
141..144 '1u8': u8
158..171 '(1u8, *"foo")': (u8, str)
- 158..178 '(1u8, ...test()': {unknown}
+ 158..178 '(1u8, ...test()': bool
159..162 '1u8': u8
164..170 '*"foo"': str
165..170 '"foo"': &'static str
@@ -3944,7 +3924,6 @@ fn test() {
#[test]
fn foreign_trait_with_local_trait_impl() {
- check!(block_local_impls);
check(
r#"
mod module {
@@ -3955,15 +3934,16 @@ mod module {
}
fn f() {
+ struct Foo;
use module::T;
- impl T for usize {
+ impl T for Foo {
const C: usize = 0;
fn f(&self) {}
}
- 0usize.f();
- //^^^^^^^^^^ type: ()
- usize::C;
- //^^^^^^^^type: usize
+ Foo.f();
+ //^^^^^^^ type: ()
+ Foo::C;
+ //^^^^^^ type: usize
}
"#,
);
@@ -4023,7 +4003,7 @@ fn f<F: Foo>() {
212..295 '{ ...ZED; }': ()
218..239 'F::Exp..._SIZED': Yes
245..266 'F::Imp..._SIZED': Yes
- 272..292 'F::Rel..._SIZED': {unknown}
+ 272..292 'F::Rel..._SIZED': Yes
"#]],
);
}
@@ -4154,7 +4134,7 @@ trait Trait {
}
fn f(t: &dyn Trait<T = (), T = ()>) {}
- //^&'? {unknown}
+ //^&'? (dyn Trait<T = ()> + 'static)
"#,
);
}
@@ -4274,7 +4254,7 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
127..128 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
164..195 '{ ...f(); }': ()
170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static)
- 170..184 'v.get::<i32>()': <dyn Trait<Assoc<i32> = &'a i32> + 'static as Trait>::Assoc<i32>
+ 170..184 'v.get::<i32>()': <{unknown} as Trait>::Assoc<i32>
170..192 'v.get:...eref()': {unknown}
"#]],
);
@@ -5051,3 +5031,71 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn implicit_sized_bound_on_param() {
+ check(
+ r#"
+//- minicore: sized
+struct PBox<T, A>(T, A);
+
+impl<T, A> PBox<T, A> {
+ fn token_with(self) {}
+}
+
+trait MoveMessage {
+ fn token<A>(self, alloc: A)
+ where
+ Self: Sized,
+ {
+ let b = PBox::<Self, A>(self, alloc);
+ b.token_with();
+ // ^^^^^^^^^^^^^^ type: ()
+ }
+}
+ "#,
+ );
+}
+
+#[test]
+fn dyn_trait_supertrait_projections_are_elaborated() {
+ check_types(
+ r#"
+//- minicore: deref, sized, unsize, coerce_unsized, dispatch_from_dyn
+use core::ops::Deref;
+
+struct Base;
+
+impl Base {
+ fn func(&self) -> i32 { 111 }
+}
+
+trait BaseLayerOne: Deref<Target = Base>{}
+
+fn foo(base_layer_two: &dyn BaseLayerOne) {
+ let _r = base_layer_two.func();
+ // ^^ i32
+}
+ "#,
+ );
+}
+
+#[test]
+fn default_assoc_types() {
+ check_types(
+ r#"
+trait Trait<T> {
+ type Assoc<U> = (T, U);
+ fn method(self) -> Self::Assoc<i32> { loop {} }
+}
+
+struct Struct<T>(T);
+impl<T> Trait<((), T)> for Struct<T> {}
+
+fn foo(v: Struct<f32>) {
+ v.method();
+ // ^^^^^^^^^^ (((), f32), i32)
+}
+ "#,
+ );
+}