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 | 188 |
1 files changed, 107 insertions, 81 deletions
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 41f8d4ed55..677e35775d 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; @@ -85,7 +84,6 @@ async fn test() { } #[test] -#[ignore = "FIXME(next-solver): fix async closures"] fn infer_async_closure() { check_types( r#" @@ -93,7 +91,7 @@ fn infer_async_closure() { async fn test() { let f = async move |x: i32| x + 42; f; -// ^ impl Fn(i32) -> impl Future<Output = i32> +// ^ impl AsyncFn(i32) -> i32 let a = f(4); a; // ^ impl Future<Output = i32> @@ -102,7 +100,7 @@ async fn test() { // ^ i32 let f = async move || 42; f; -// ^ impl Fn() -> impl Future<Output = i32> +// ^ impl AsyncFn() -> i32 let a = f(); a; // ^ impl Future<Output = i32> @@ -119,7 +117,7 @@ async fn test() { }; let _: Option<u64> = c().await; c; -// ^ impl Fn() -> impl Future<Output = Option<u64>> +// ^ impl AsyncFn() -> Option<u64> } "#, ); @@ -279,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; } @@ -292,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; - } -} "#, ); } @@ -309,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; } @@ -322,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; - } -} "#, ); } @@ -369,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 { @@ -1374,11 +1353,11 @@ fn test() { expect![[r#" 49..53 'self': &'? mut Self 101..105 'self': &'? Self - 184..195 '{ loop {} }': ({unknown}, {unknown}) + 184..195 '{ loop {} }': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) 186..193 'loop {}': ! 191..193 '{}': () 206..207 't': T - 268..279 '{ loop {} }': ({unknown}, {unknown}) + 268..279 '{ loop {} }': (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) 270..277 'loop {}': ! 275..277 '{}': () 291..413 '{ ...o(); }': () @@ -1420,7 +1399,7 @@ fn foo<const C: u8, T>() -> (impl FnOnce(&str, T), impl Trait<u8>) { } "#, expect![[r#" - 134..165 '{ ...(C)) }': (impl FnOnce(&'? str, T), Bar<u8>) + 134..165 '{ ...(C)) }': (impl FnOnce(&'? str, T), impl Trait<u8>) 140..163 '(|inpu...ar(C))': (impl FnOnce(&'? str, T), Bar<u8>) 141..154 '|input, t| {}': impl FnOnce(&'? str, T) 142..147 'input': &'? str @@ -1442,7 +1421,7 @@ fn return_pos_impl_trait_in_projection() { trait Future { type Output; } impl Future for () { type Output = i32; } type Foo<F> = (<F as Future>::Output, F); -fn foo<X>() -> Foo<impl Future<Output = ()>> { +fn foo<X>() -> Foo<impl Future<Output = i32>> { (0, ()) } "#, @@ -1480,24 +1459,24 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) { expect![[r#" 29..33 'self': &'? Self 54..58 'self': &'? Self - 206..208 '{}': Box<dyn Trait<u64> + '?> - 218..219 'x': Box<dyn Trait<u64> + '?> - 242..243 'y': &'? (dyn Trait<u64> + '?) + 206..208 '{}': Box<dyn Trait<u64> + 'static> + 218..219 'x': Box<dyn Trait<u64> + 'static> + 242..243 'y': &'? (dyn Trait<u64> + 'static) 262..379 '{ ...2(); }': () - 268..269 'x': Box<dyn Trait<u64> + '?> - 275..276 'y': &'? (dyn Trait<u64> + '?) + 268..269 'x': Box<dyn Trait<u64> + 'static> + 275..276 'y': &'? (dyn Trait<u64> + 'static) 286..287 'z': Box<dyn Trait<u64> + '?> - 290..293 'bar': fn bar() -> Box<dyn Trait<u64> + '?> - 290..295 'bar()': Box<dyn Trait<u64> + '?> - 301..302 'x': Box<dyn Trait<u64> + '?> + 290..293 'bar': fn bar() -> Box<dyn Trait<u64> + 'static> + 290..295 'bar()': Box<dyn Trait<u64> + 'static> + 301..302 'x': Box<dyn Trait<u64> + 'static> 301..308 'x.foo()': u64 - 314..315 'y': &'? (dyn Trait<u64> + '?) + 314..315 'y': &'? (dyn Trait<u64> + 'static) 314..321 'y.foo()': u64 327..328 'z': Box<dyn Trait<u64> + '?> 327..334 'z.foo()': u64 - 340..341 'x': Box<dyn Trait<u64> + '?> + 340..341 'x': Box<dyn Trait<u64> + 'static> 340..348 'x.foo2()': i64 - 354..355 'y': &'? (dyn Trait<u64> + '?) + 354..355 'y': &'? (dyn Trait<u64> + 'static) 354..362 'y.foo2()': i64 368..369 'z': Box<dyn Trait<u64> + '?> 368..376 'z.foo2()': i64 @@ -1528,14 +1507,14 @@ 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> + '?) + 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> + '?) + 273..280 's.bar()': &'? (dyn Trait<u32, i32> + 'static) 273..286 's.bar().baz()': (u32, i32) "#]], ); @@ -1561,18 +1540,18 @@ fn test(x: Trait, y: &Trait) -> u64 { }"#, expect![[r#" 26..30 'self': &'? Self - 60..62 '{}': dyn Trait + '? - 72..73 'x': dyn Trait + '? - 82..83 'y': &'? (dyn Trait + '?) + 60..62 '{}': dyn Trait + 'static + 72..73 'x': dyn Trait + 'static + 82..83 'y': &'? (dyn Trait + 'static) 100..175 '{ ...o(); }': u64 - 106..107 'x': dyn Trait + '? - 113..114 'y': &'? (dyn Trait + '?) + 106..107 'x': dyn Trait + 'static + 113..114 'y': &'? (dyn Trait + 'static) 124..125 'z': dyn Trait + '? - 128..131 'bar': fn bar() -> dyn Trait + '? - 128..133 'bar()': dyn Trait + '? - 139..140 'x': dyn Trait + '? + 128..131 'bar': fn bar() -> dyn Trait + 'static + 128..133 'bar()': dyn Trait + 'static + 139..140 'x': dyn Trait + 'static 139..146 'x.foo()': u64 - 152..153 'y': &'? (dyn Trait + '?) + 152..153 'y': &'? (dyn Trait + 'static) 152..159 'y.foo()': u64 165..166 'z': dyn Trait + '? 165..172 'z.foo()': u64 @@ -1594,10 +1573,10 @@ fn main() { expect![[r#" 31..35 'self': &'? S 37..39 '{}': () - 47..48 '_': &'? (dyn Fn(S) + '?) + 47..48 '_': &'? (dyn Fn(S) + 'static) 58..60 '{}': () 71..105 '{ ...()); }': () - 77..78 'f': fn f(&'? (dyn Fn(S) + '?)) + 77..78 'f': fn f(&'? (dyn Fn(S) + 'static)) 77..102 'f(&|nu...foo())': () 79..101 '&|numb....foo()': &'? impl Fn(S) 80..101 '|numbe....foo()': impl Fn(S) @@ -2948,13 +2927,13 @@ fn test(x: &dyn Foo) { foo(x); }"#, expect![[r#" - 21..22 'x': &'? (dyn Foo + '?) + 21..22 'x': &'? (dyn Foo + 'static) 34..36 '{}': () - 46..47 'x': &'? (dyn Foo + '?) + 46..47 'x': &'? (dyn Foo + 'static) 59..74 '{ foo(x); }': () - 65..68 'foo': fn foo(&'? (dyn Foo + '?)) + 65..68 'foo': fn foo(&'? (dyn Foo + 'static)) 65..71 'foo(x)': () - 69..70 'x': &'? (dyn Foo + '?) + 69..70 'x': &'? (dyn Foo + 'static) "#]], ); } @@ -2983,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 "#]], @@ -3082,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) @@ -3090,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 @@ -3230,13 +3209,13 @@ fn foo() { 218..324 '{ ...&s); }': () 228..229 's': Option<i32> 232..236 'None': Option<i32> - 246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + '?> - 281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + '?> + 246..247 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static> + 281..310 'Box { ... {}) }': Box<dyn FnOnce(&'? Option<i32>) + 'static> 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option<i32>) 300..307 '|ps| {}': impl FnOnce(&'? Option<i32>) 301..303 'ps': &'? Option<i32> 305..307 '{}': () - 316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + '?> + 316..317 'f': Box<dyn FnOnce(&'? Option<i32>) + 'static> 316..321 'f(&s)': () 318..320 '&s': &'? Option<i32> 319..320 's': Option<i32> @@ -3945,7 +3924,6 @@ fn test() { #[test] fn foreign_trait_with_local_trait_impl() { - check!(block_local_impls); check( r#" mod module { @@ -3956,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 } "#, ); @@ -4024,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 "#]], ); } @@ -4155,7 +4134,7 @@ trait Trait { } fn f(t: &dyn Trait<T = (), T = ()>) {} - //^&'? {unknown} + //^&'? (dyn Trait<T = ()> + 'static) "#, ); } @@ -4272,10 +4251,10 @@ fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) { "#, expect![[r#" 90..94 'self': &'? Self - 127..128 '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> + '?) - 170..184 'v.get::<i32>()': <dyn Trait<Assoc<i32> = &'a i32> + '? as Trait>::Assoc<i32> + 170..171 'v': &'? (dyn Trait<Assoc<i32> = &'a i32> + 'static) + 170..184 'v.get::<i32>()': <{unknown} as Trait>::Assoc<i32> 170..192 'v.get:...eref()': {unknown} "#]], ); @@ -4930,7 +4909,6 @@ fn main() { #[test] fn async_fn_return_type() { - // FIXME(next-solver): Async closures are lowered as closures currently. We should fix that. check_infer( r#" //- minicore: async_fn @@ -4948,9 +4926,9 @@ fn main() { 46..53 'loop {}': ! 51..53 '{}': () 67..97 '{ ...()); }': () - 73..76 'foo': fn foo<impl Fn(), ()>(impl Fn()) + 73..76 'foo': fn foo<impl AsyncFn(), ()>(impl AsyncFn()) 73..94 'foo(as...|| ())': () - 77..93 'async ... || ()': impl Fn() + 77..93 'async ... || ()': impl AsyncFn() 91..93 '()': () "#]], ); @@ -5053,3 +5031,51 @@ 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 +} + "#, + ); +} |