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 | 577 |
1 files changed, 349 insertions, 228 deletions
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index 56e31a1af1..f72ca22fd2 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -1,6 +1,8 @@ use cov_mark::check; use expect_test::expect; +use crate::tests::infer_with_mismatches; + use super::{check, check_infer, check_infer_with_mismatches, check_no_mismatches, check_types}; #[test] @@ -90,7 +92,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> @@ -99,7 +101,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> @@ -116,7 +118,7 @@ async fn test() { }; let _: Option<u64> = c().await; c; -// ^ impl Fn() -> impl Future<Output = Option<u64>> +// ^ impl AsyncFn() -> Option<u64> } "#, ); @@ -162,16 +164,16 @@ unsafe impl Allocator for Global {} #[lang = "owned_box"] #[fundamental] -pub struct Box<T: ?Sized, A: Allocator = Global>(T); +pub struct Box<T: ?Sized, A: Allocator = Global>(T, A); impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {} fn send() -> Box<dyn Future<Output = ()> + Send + 'static>{ - Box(async move {}) + Box(async move {}, Global) } fn not_send() -> Box<dyn Future<Output = ()> + 'static> { - Box(async move {}) + Box(async move {}, Global) } "#, ); @@ -246,15 +248,15 @@ fn test() { v.push("foo"); for x in v { x; - } //^ &'static str + } //^ &'? str } //- /alloc.rs crate:alloc #![no_std] pub mod collections { - pub struct Vec<T> {} + pub struct Vec<T> { p: *const T } impl<T> Vec<T> { - pub fn new() -> Self { Vec {} } + pub fn new() -> Self { Vec { p: 0 as _ } } pub fn push(&mut self, t: T) { } } @@ -408,11 +410,11 @@ fn test<T: Iterable>() { let x: <S as Iterable>::Item = 1; // ^ u32 let y: <T as Iterable>::Item = u; - // ^ Iterable::Item<T> + // ^ <T as Iterable>::Item let z: T::Item = u; - // ^ Iterable::Item<T> + // ^ <T as Iterable>::Item let a: <T>::Item = u; - // ^ Iterable::Item<T> + // ^ <T as Iterable>::Item }"#, ); } @@ -454,7 +456,7 @@ impl<T> S<T> { fn test<T: Iterable>() { let s: S<T>; s.foo(); - // ^^^^^^^ Iterable::Item<T> + // ^^^^^^^ <T as Iterable>::Item }"#, ); } @@ -470,7 +472,7 @@ trait Foo { type A; fn test(a: Self::A, _: impl Bar) { a; - //^ Foo::A<Self> + //^ <Self as Foo>::A } }"#, ); @@ -720,8 +722,8 @@ fn deref_trait_with_inference_var() { check_types( r#" //- minicore: deref -struct Arc<T: ?Sized>; -fn new_arc<T: ?Sized>() -> Arc<T> { Arc } +struct Arc<T: ?Sized>(T); +fn new_arc<T: ?Sized>() -> Arc<T> { loop {} } impl<T: ?Sized> core::ops::Deref for Arc<T> { type Target = T; } @@ -783,13 +785,15 @@ fn test(s: Arc<S>) { fn deref_trait_with_implicit_sized_requirement_on_inference_var() { check_types( r#" -//- minicore: deref -struct Foo<T>; +//- minicore: deref, phantom_data +use core::marker::PhantomData; + +struct Foo<T>(PhantomData<T>); impl<T> core::ops::Deref for Foo<T> { type Target = (); } fn test() { - let foo = Foo; + let foo = Foo(PhantomData); *foo; //^^^^ () let _: Foo<u8> = foo; @@ -969,7 +973,7 @@ impl<T> ApplyL for RefMutL<T> { fn test<T: ApplyL>() { let y: <RefMutL<T> as ApplyL>::Out = no_matter; y; -} //^ ApplyL::Out<T> +} //^ <T as ApplyL>::Out "#, ); } @@ -986,7 +990,7 @@ fn foo<T: ApplyL>(t: T) -> <T as ApplyL>::Out; fn test<T: ApplyL>(t: T) { let y = foo(t); y; -} //^ ApplyL::Out<T> +} //^ <T as ApplyL>::Out "#, ); } @@ -1454,7 +1458,7 @@ trait Trait<T> { fn foo2(&self) -> i64; } -struct Box<T: ?Sized> {} +struct Box<T: ?Sized>(*const T); impl<T: ?Sized> core::ops::Deref for Box<T> { type Target = T; } @@ -1475,27 +1479,27 @@ fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) { expect![[r#" 29..33 'self': &'? Self 54..58 'self': &'? Self - 198..200 '{}': Box<dyn Trait<u64> + '?> - 210..211 'x': Box<dyn Trait<u64> + '?> - 234..235 'y': &'? (dyn Trait<u64> + '?) - 254..371 '{ ...2(); }': () - 260..261 'x': Box<dyn Trait<u64> + '?> - 267..268 'y': &'? (dyn Trait<u64> + '?) - 278..279 'z': Box<dyn Trait<u64> + '?> - 282..285 'bar': fn bar() -> Box<dyn Trait<u64> + '?> - 282..287 'bar()': Box<dyn Trait<u64> + '?> - 293..294 'x': Box<dyn Trait<u64> + '?> - 293..300 'x.foo()': u64 - 306..307 'y': &'? (dyn Trait<u64> + '?) - 306..313 'y.foo()': u64 - 319..320 'z': Box<dyn Trait<u64> + '?> - 319..326 'z.foo()': u64 - 332..333 'x': Box<dyn Trait<u64> + '?> - 332..340 'x.foo2()': i64 - 346..347 'y': &'? (dyn Trait<u64> + '?) - 346..354 'y.foo2()': i64 - 360..361 'z': Box<dyn Trait<u64> + '?> - 360..368 'z.foo2()': i64 + 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> + 'static> + 275..276 'y': &'? (dyn Trait<u64> + 'static) + 286..287 'z': 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> + '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> + 'static> + 340..348 'x.foo2()': i64 + 354..355 'y': &'? (dyn Trait<u64> + 'static) + 354..362 'y.foo2()': i64 + 368..369 'z': Box<dyn Trait<u64> + '?> + 368..376 'z.foo2()': i64 "#]], ); } @@ -1523,14 +1527,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) "#]], ); @@ -1556,18 +1560,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 @@ -1589,10 +1593,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) @@ -1672,7 +1676,9 @@ fn test(x: (impl Trait + UnknownTrait)) { fn assoc_type_bindings() { check_infer( r#" -//- minicore: sized +//- minicore: sized, phantom_data +use core::marker::PhantomData; + trait Trait { type Type; } @@ -1681,7 +1687,7 @@ fn get<T: Trait>(t: T) -> <T as Trait>::Type {} fn get2<U, T: Trait<Type = U>>(t: T) -> U {} fn set<T: Trait<Type = u64>>(t: T) -> T {t} -struct S<T>; +struct S<T>(PhantomData<T>); impl<T> Trait for S<T> { type Type = T; } fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { @@ -1689,46 +1695,52 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { get2(x); get(y); get2(y); - get(set(S)); - get2(set(S)); - get2(S::<str>); + get(set(S(PhantomData))); + get2(set(S(PhantomData))); + get2(S::<usize>(PhantomData)); }"#, expect![[r#" - 49..50 't': T - 77..79 '{}': Trait::Type<T> - 111..112 't': T - 122..124 '{}': U - 154..155 't': T - 165..168 '{t}': T - 166..167 't': T - 256..257 'x': T - 262..263 'y': impl Trait<Type = i64> - 289..397 '{ ...r>); }': () - 295..298 'get': fn get<T>(T) -> <T as Trait>::Type - 295..301 'get(x)': u32 - 299..300 'x': T - 307..311 'get2': fn get2<u32, T>(T) -> u32 - 307..314 'get2(x)': u32 - 312..313 'x': T - 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type - 320..326 'get(y)': i64 - 324..325 'y': impl Trait<Type = i64> - 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 - 332..339 'get2(y)': i64 - 337..338 'y': impl Trait<Type = i64> - 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type - 345..356 'get(set(S))': u64 - 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> - 349..355 'set(S)': S<u64> - 353..354 'S': S<u64> - 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 - 362..374 'get2(set(S))': u64 - 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> - 367..373 'set(S)': S<u64> - 371..372 'S': S<u64> - 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str - 380..394 'get2(S::<str>)': str - 385..393 'S::<str>': S<str> + 81..82 't': T + 109..111 '{}': <T as Trait>::Type + 143..144 't': T + 154..156 '{}': U + 186..187 't': T + 197..200 '{t}': T + 198..199 't': T + 304..305 'x': T + 310..311 'y': impl Trait<Type = i64> + 337..486 '{ ...a)); }': () + 343..346 'get': fn get<T>(T) -> <T as Trait>::Type + 343..349 'get(x)': u32 + 347..348 'x': T + 355..359 'get2': fn get2<u32, T>(T) -> u32 + 355..362 'get2(x)': u32 + 360..361 'x': T + 368..371 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type + 368..374 'get(y)': i64 + 372..373 'y': impl Trait<Type = i64> + 380..384 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 + 380..387 'get2(y)': i64 + 385..386 'y': impl Trait<Type = i64> + 393..396 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type + 393..417 'get(se...ata)))': u64 + 397..400 'set': fn set<S<u64>>(S<u64>) -> S<u64> + 397..416 'set(S(...Data))': S<u64> + 401..402 'S': fn S<u64>(PhantomData<u64>) -> S<u64> + 401..415 'S(PhantomData)': S<u64> + 403..414 'PhantomData': PhantomData<u64> + 423..427 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 + 423..448 'get2(s...ata)))': u64 + 428..431 'set': fn set<S<u64>>(S<u64>) -> S<u64> + 428..447 'set(S(...Data))': S<u64> + 432..433 'S': fn S<u64>(PhantomData<u64>) -> S<u64> + 432..446 'S(PhantomData)': S<u64> + 434..445 'PhantomData': PhantomData<u64> + 454..458 'get2': fn get2<usize, S<usize>>(S<usize>) -> usize + 454..483 'get2(S...Data))': usize + 459..469 'S::<usize>': fn S<usize>(PhantomData<usize>) -> S<usize> + 459..482 'S::<us...mData)': S<usize> + 470..481 'PhantomData': PhantomData<usize> "#]], ); } @@ -1745,7 +1757,7 @@ pub enum RustLanguage {} impl Language for RustLanguage { type Kind = SyntaxKind; } -struct SyntaxNode<L> {} +struct SyntaxNode<L>(L); fn foo() -> impl Iterator<Item = SyntaxNode<RustLanguage>> {} trait Clone { @@ -1884,31 +1896,36 @@ fn super_trait_cycle() { fn super_trait_assoc_type_bounds() { check_infer( r#" +//- minicore: phantom_data +use core::marker::PhantomData; + trait SuperTrait { type Type; } trait Trait where Self: SuperTrait {} fn get2<U, T: Trait<Type = U>>(t: T) -> U {} fn set<T: Trait<Type = u64>>(t: T) -> T {t} -struct S<T>; +struct S<T>(PhantomData<T>); impl<T> SuperTrait for S<T> { type Type = T; } impl<T> Trait for S<T> {} fn test() { - get2(set(S)); + get2(set(S(PhantomData))); }"#, expect![[r#" - 102..103 't': T - 113..115 '{}': U - 145..146 't': T - 156..159 '{t}': T - 157..158 't': T - 258..279 '{ ...S)); }': () - 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 - 264..276 'get2(set(S))': u64 - 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> - 269..275 'set(S)': S<u64> - 273..274 'S': S<u64> + 134..135 't': T + 145..147 '{}': U + 177..178 't': T + 188..191 '{t}': T + 189..190 't': T + 306..340 '{ ...))); }': () + 312..316 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 + 312..337 'get2(s...ata)))': u64 + 317..320 'set': fn set<S<u64>>(S<u64>) -> S<u64> + 317..336 'set(S(...Data))': S<u64> + 321..322 'S': fn S<u64>(PhantomData<u64>) -> S<u64> + 321..335 'S(PhantomData)': S<u64> + 323..334 'PhantomData': PhantomData<u64> "#]], ); } @@ -1998,7 +2015,7 @@ impl Foo { fn foo(&self) -> usize {} } -struct Lazy<T, F = fn() -> T>(F); +struct Lazy<T, F = fn() -> T>(T, F); impl<T, F> Lazy<T, F> { pub fn new(f: F) -> Lazy<T, F> {} @@ -2012,7 +2029,7 @@ fn test() { let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); let r1 = lazy1.foo(); - fn make_foo_fn() -> Foo {} +fn make_foo_fn() -> Foo {} let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); let r2 = lazy2.foo(); @@ -2020,27 +2037,27 @@ fn test() { expect![[r#" 36..40 'self': &'? Foo 51..53 '{}': usize - 131..132 'f': F - 151..153 '{}': Lazy<T, F> - 251..497 '{ ...o(); }': () - 261..266 'lazy1': Lazy<Foo, impl Fn() -> Foo> - 283..292 'Lazy::new': fn new<Foo, impl Fn() -> Foo>(impl Fn() -> Foo) -> Lazy<Foo, impl Fn() -> Foo> - 283..300 'Lazy::...| Foo)': Lazy<Foo, impl Fn() -> Foo> - 293..299 '|| Foo': impl Fn() -> Foo - 296..299 'Foo': Foo - 310..312 'r1': usize - 315..320 'lazy1': Lazy<Foo, impl Fn() -> Foo> - 315..326 'lazy1.foo()': usize - 368..383 'make_foo_fn_ptr': fn() -> Foo - 399..410 'make_foo_fn': fn make_foo_fn() -> Foo - 420..425 'lazy2': Lazy<Foo, fn() -> Foo> - 442..451 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> - 442..468 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> - 452..467 'make_foo_fn_ptr': fn() -> Foo - 478..480 'r2': usize - 483..488 'lazy2': Lazy<Foo, fn() -> Foo> - 483..494 'lazy2.foo()': usize - 357..359 '{}': Foo + 134..135 'f': F + 154..156 '{}': Lazy<T, F> + 254..496 '{ ...o(); }': () + 264..269 'lazy1': Lazy<Foo, impl Fn() -> Foo> + 286..295 'Lazy::new': fn new<Foo, impl Fn() -> Foo>(impl Fn() -> Foo) -> Lazy<Foo, impl Fn() -> Foo> + 286..303 'Lazy::...| Foo)': Lazy<Foo, impl Fn() -> Foo> + 296..302 '|| Foo': impl Fn() -> Foo + 299..302 'Foo': Foo + 313..315 'r1': usize + 318..323 'lazy1': Lazy<Foo, impl Fn() -> Foo> + 318..329 'lazy1.foo()': usize + 367..382 'make_foo_fn_ptr': fn() -> Foo + 398..409 'make_foo_fn': fn make_foo_fn() -> Foo + 419..424 'lazy2': Lazy<Foo, fn() -> Foo> + 441..450 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> + 441..467 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> + 451..466 'make_foo_fn_ptr': fn() -> Foo + 477..479 'r2': usize + 482..487 'lazy2': Lazy<Foo, fn() -> Foo> + 482..493 'lazy2.foo()': usize + 356..358 '{}': Foo "#]], ); } @@ -2293,7 +2310,7 @@ impl Trait for S2 { }"#, expect![[r#" 40..44 'self': &'? Self - 46..47 'x': Trait::Item<Self> + 46..47 'x': <Self as Trait>::Item 126..130 'self': &'? S 132..133 'x': u32 147..161 '{ let y = x; }': () @@ -2339,7 +2356,7 @@ trait Fold<I: Interner, TI = I> { type Result; } -struct Ty<I: Interner> {} +struct Ty<I: Interner>(I); impl<I: Interner, TI: Interner> Fold<I, TI> for Ty<I> { type Result = Ty<TI>; } @@ -2381,17 +2398,20 @@ fn test() { fn trait_impl_self_ty_cycle() { check_types( r#" +//- minicore: phantom_data +use core::marker::PhantomData; + trait Trait { fn foo(&self); } -struct S<T>; +struct S<T>(T); impl Trait for S<Self> {} fn test() { - S.foo(); -} //^^^^^^^ {unknown} + S(PhantomData).foo(); +} //^^^^^^^^^^^^^^^^^^^^ {unknown} "#, ); } @@ -2410,7 +2430,7 @@ trait Trait2<T> {} fn test<T: Trait>() where T: Trait2<T::Item> { let x: T::Item = no_matter; -} //^^^^^^^^^ Trait::Item<T> +} //^^^^^^^^^ <T as Trait>::Item "#, ); } @@ -2445,7 +2465,7 @@ trait Trait { fn test<T>() where T: Trait<OtherItem = T::Item> { let x: T::Item = no_matter; -} //^^^^^^^^^ Trait::Item<T> +} //^^^^^^^^^ <T as Trait>::Item "#, ); } @@ -2460,7 +2480,7 @@ use core::ops::Index; type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key; -pub trait UnificationStoreBase: Index<Output = Key<Self>> { +pub trait UnificationStoreBase: Index<usize, Output = Key<Self>> { type Key; fn len(&self) -> usize; @@ -2475,7 +2495,7 @@ fn test<T>(t: T) where T: UnificationStoreMut { t.push(x); let y: Key<T>; (x, y); -} //^^^^^^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>) +} //^^^^^^ (<T as UnificationStoreBase>::Key, <T as UnificationStoreBase>::Key) "#, ); } @@ -2740,8 +2760,8 @@ impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> { fn dyn_trait_through_chalk() { check_types( r#" -//- minicore: deref -struct Box<T: ?Sized> {} +//- minicore: deref, unsize, dispatch_from_dyn +struct Box<T: ?Sized>(*const T); impl<T: ?Sized> core::ops::Deref for Box<T> { type Target = T; } @@ -2800,7 +2820,7 @@ pub trait IntoIterator { fn into_iter(self) -> Self::IntoIter; } -pub struct FilterMap<I, F> { } +pub struct FilterMap<I, F>(I, F); impl<B, I: Iterator, F> Iterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B>, @@ -2818,7 +2838,7 @@ impl<I: Iterator> IntoIterator for I { } } -struct Vec<T> {} +struct Vec<T>(T); impl<T> Vec<T> { fn new() -> Self { loop {} } } @@ -2828,7 +2848,7 @@ impl<T> IntoIterator for Vec<T> { type IntoIter = IntoIter<T>; } -pub struct IntoIter<T> { } +pub struct IntoIter<T>(T); impl<T> Iterator for IntoIter<T> { type Item = T; } @@ -2850,35 +2870,35 @@ fn main() { 242..249 'loop {}': ! 247..249 '{}': () 360..364 'self': Self - 689..693 'self': I - 700..720 '{ ... }': I - 710..714 'self': I - 779..790 '{ loop {} }': Vec<T> - 781..788 'loop {}': ! - 786..788 '{}': () - 977..1104 '{ ... }); }': () - 983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> - 983..1000 'Vec::<...:new()': Vec<i32> - 983..1012 'Vec::<...iter()': IntoIter<i32> - 983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, impl FnMut(i32) -> Option<u32>> - 983..1101 'Vec::<... y; })': () - 1029..1074 '|x| if...None }': impl FnMut(i32) -> Option<u32> - 1030..1031 'x': i32 - 1033..1074 'if x >...None }': Option<u32> - 1036..1037 'x': i32 - 1036..1041 'x > 0': bool - 1040..1041 '0': i32 - 1042..1060 '{ Some...u32) }': Option<u32> - 1044..1048 'Some': fn Some<u32>(u32) -> Option<u32> - 1044..1058 'Some(x as u32)': Option<u32> - 1049..1050 'x': i32 - 1049..1057 'x as u32': u32 - 1066..1074 '{ None }': Option<u32> - 1068..1072 'None': Option<u32> - 1090..1100 '|y| { y; }': impl FnMut(u32) - 1091..1092 'y': u32 - 1094..1100 '{ y; }': () - 1096..1097 'y': u32 + 692..696 'self': I + 703..723 '{ ... }': I + 713..717 'self': I + 783..794 '{ loop {} }': Vec<T> + 785..792 'loop {}': ! + 790..792 '{}': () + 981..1108 '{ ... }); }': () + 987..1002 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> + 987..1004 'Vec::<...:new()': Vec<i32> + 987..1016 'Vec::<...iter()': IntoIter<i32> + 987..1079 'Vec::<...one })': FilterMap<IntoIter<i32>, impl FnMut(i32) -> Option<u32>> + 987..1105 'Vec::<... y; })': () + 1033..1078 '|x| if...None }': impl FnMut(i32) -> Option<u32> + 1034..1035 'x': i32 + 1037..1078 'if x >...None }': Option<u32> + 1040..1041 'x': i32 + 1040..1045 'x > 0': bool + 1044..1045 '0': i32 + 1046..1064 '{ Some...u32) }': Option<u32> + 1048..1052 'Some': fn Some<u32>(u32) -> Option<u32> + 1048..1062 'Some(x as u32)': Option<u32> + 1053..1054 'x': i32 + 1053..1061 'x as u32': u32 + 1070..1078 '{ None }': Option<u32> + 1072..1076 'None': Option<u32> + 1094..1104 '|y| { y; }': impl FnMut(u32) + 1095..1096 'y': u32 + 1098..1104 '{ y; }': () + 1100..1101 'y': u32 "#]], ); } @@ -2927,13 +2947,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) "#]], ); } @@ -3132,7 +3152,6 @@ fn foo() { #[test] fn dyn_fn_param_informs_call_site_closure_signature() { - cov_mark::check!(dyn_fn_param_informs_call_site_closure_signature); check_types( r#" //- minicore: fn, coerce_unsized, dispatch_from_dyn @@ -3210,13 +3229,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> @@ -3228,7 +3247,7 @@ fn foo() { fn infer_dyn_fn_output() { check_types( r#" -//- minicore: fn +//- minicore: fn, dispatch_from_dyn fn foo() { let f: &dyn Fn() -> i32; f(); @@ -3488,7 +3507,7 @@ fn foo() { let x = <F as Bar>::boo(); }"#, expect![[r#" - 132..163 '{ ... }': Bar::Output<Self> + 132..163 '{ ... }': <Self as Bar>::Output 146..153 'loop {}': ! 151..153 '{}': () 306..358 '{ ...o(); }': () @@ -3615,7 +3634,7 @@ impl Add<&i32> for i32 { type Output = i32 } impl Add<u32> for u32 { type Output = u32 } impl Add<&u32> for u32 { type Output = u32 } -struct V<T>; +struct V<T>(T); impl<T> V<T> { fn default() -> Self { loop {} } fn get(&self, _: &T) -> &T { loop {} } @@ -3634,8 +3653,7 @@ fn minimized() { #[test] fn no_builtin_binop_expectation_for_general_ty_var() { - // FIXME: Ideally type mismatch should be reported on `take_u32(42 - p)`. - check_types( + infer_with_mismatches( r#" //- minicore: add use core::ops::Add; @@ -3645,7 +3663,7 @@ impl Add<&i32> for i32 { type Output = i32; } // fallback to integer type variable for `42`. impl Add<&()> for i32 { type Output = (); } -struct V<T>; +struct V<T>(T); impl<T> V<T> { fn default() -> Self { loop {} } fn get(&self) -> &T { loop {} } @@ -3659,6 +3677,7 @@ fn minimized() { take_u32(42 + p); } "#, + true, ); } @@ -4211,21 +4230,21 @@ fn f<T>(v: impl Trait) { } fn g<'a, T: 'a>(v: impl Trait<Assoc<T> = &'a T>) { let a = v.get::<T>(); - //^ &'a T + //^ &'? T let a = v.get::<()>(); - //^ Trait::Assoc<impl Trait<Assoc<T> = &'a T>, ()> + //^ <impl Trait<Assoc<T> = &'a T> as Trait>::Assoc<()> } fn h<'a>(v: impl Trait<Assoc<i32> = &'a i32> + Trait<Assoc<i64> = &'a i64>) { let a = v.get::<i32>(); - //^ &'a i32 + //^ &'? i32 let a = v.get::<i64>(); - //^ &'a i64 + //^ &'? i64 } fn i<'a>(v: impl Trait<Assoc<i32> = &'a i32, Assoc<i64> = &'a i64>) { let a = v.get::<i32>(); - //^ &'a i32 + //^ &'? i32 let a = v.get::<i64>(); - //^ &'a i64 + //^ &'? i64 } "#, ); @@ -4252,11 +4271,11 @@ 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>()': &'? i32 - 170..192 'v.get:...eref()': &'? i32 + 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..192 'v.get:...eref()': {unknown} "#]], ); } @@ -4280,7 +4299,7 @@ where let a = t.get::<isize>(); //^ usize let a = t.get::<()>(); - //^ Trait::Assoc<T, ()> + //^ <T as Trait>::Assoc<()> } "#, @@ -4483,7 +4502,9 @@ impl Trait for () { fn derive_macro_bounds() { check_types( r#" - //- minicore: clone, derive + //- minicore: clone, derive, phantom_data + use core::marker::PhantomData; + #[derive(Clone)] struct Copy; struct NotCopy; @@ -4506,7 +4527,7 @@ fn derive_macro_bounds() { struct AssocGeneric3<T: Tr>(Generic<T::Assoc>); #[derive(Clone)] - struct Vec<T>(); + struct Vec<T>(PhantomData<T>); #[derive(Clone)] struct R1(Vec<R2>); @@ -4530,9 +4551,9 @@ fn derive_macro_bounds() { let x: &AssocGeneric3<Copy> = &AssocGeneric3(Generic(NotCopy)); let x = x.clone(); //^ &'? AssocGeneric3<Copy> - let x = (&R1(Vec())).clone(); + let x = (&R1(Vec(PhantomData))).clone(); //^ R1 - let x = (&R2(R1(Vec()))).clone(); + let x = (&R2(R1(Vec(PhantomData)))).clone(); //^ R2 } "#, @@ -4622,8 +4643,10 @@ fn ttt() { fn infer_borrow() { check_types( r#" -//- minicore: index -pub struct SomeMap<K>; +//- minicore: index, phantom_data +use core::marker::PhantomData; + +pub struct SomeMap<K>(PhantomData<K>); pub trait Borrow<Borrowed: ?Sized> { fn borrow(&self) -> &Borrowed; @@ -4656,7 +4679,7 @@ impl<K> core::ops::IndexMut<K> for SomeMap<K> { } fn foo() { - let mut map = SomeMap; + let mut map = SomeMap(PhantomData); map["a"] = (); map; //^^^ SomeMap<&'static str> @@ -4785,30 +4808,30 @@ fn allowed2<'a>(baz: impl Baz<Assoc = &'a (impl Foo + 'a)>) {} fn allowed3(baz: impl Baz<Assoc = Qux<impl Foo>>) {} "#, expect![[r#" - 139..140 'f': impl Fn({unknown}) + ?Sized + 139..140 'f': impl Fn({unknown}) 161..193 '{ ...oo); }': () 171..174 'foo': S 177..178 'S': S - 184..185 'f': impl Fn({unknown}) + ?Sized + 184..185 'f': impl Fn({unknown}) 184..190 'f(foo)': () 186..189 'foo': S - 251..252 'f': impl Fn(&'? {unknown}) + ?Sized + 251..252 'f': impl Fn(&'? {unknown}) 274..307 '{ ...oo); }': () 284..287 'foo': S 290..291 'S': S - 297..298 'f': impl Fn(&'? {unknown}) + ?Sized + 297..298 'f': impl Fn(&'? {unknown}) 297..304 'f(&foo)': () 299..303 '&foo': &'? S 300..303 'foo': S - 325..328 'bar': impl Bar<{unknown}> + ?Sized + 325..328 'bar': impl Bar<{unknown}> 350..352 '{}': () - 405..408 'bar': impl Bar<&'? {unknown}> + ?Sized + 405..408 'bar': impl Bar<&'? {unknown}> 431..433 '{}': () - 447..450 'baz': impl Baz<Assoc = impl Foo + ?Sized> + ?Sized + 447..450 'baz': impl Baz<Assoc = impl Foo> 480..482 '{}': () - 500..503 'baz': impl Baz<Assoc = &'a impl Foo + 'a + ?Sized> + ?Sized + 500..503 'baz': impl Baz<Assoc = &'a impl Foo + 'a> 544..546 '{}': () - 560..563 'baz': impl Baz<Assoc = Qux<impl Foo + ?Sized>> + ?Sized + 560..563 'baz': impl Baz<Assoc = Qux<impl Foo>> 598..600 '{}': () "#]], ) @@ -4857,29 +4880,29 @@ async fn baz<T: AsyncFnOnce(u32) -> i32>(c: T) { 37..38 'a': T 43..83 '{ ...ait; }': () 43..83 '{ ...ait; }': impl Future<Output = ()> - 53..57 'fut1': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 53..57 'fut1': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 60..61 'a': T - 60..64 'a(0)': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 60..64 'a(0)': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 62..63 '0': u32 - 70..74 'fut1': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 70..74 'fut1': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 70..80 'fut1.await': i32 124..129 'mut b': T 134..174 '{ ...ait; }': () 134..174 '{ ...ait; }': impl Future<Output = ()> - 144..148 'fut2': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 144..148 'fut2': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 151..152 'b': T - 151..155 'b(0)': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 151..155 'b(0)': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 153..154 '0': u32 - 161..165 'fut2': AsyncFnMut::CallRefFuture<'?, T, (u32,)> + 161..165 'fut2': <T as AsyncFnMut<(u32,)>>::CallRefFuture<'?> 161..171 'fut2.await': i32 216..217 'c': T 222..262 '{ ...ait; }': () 222..262 '{ ...ait; }': impl Future<Output = ()> - 232..236 'fut3': AsyncFnOnce::CallOnceFuture<T, (u32,)> + 232..236 'fut3': <T as AsyncFnOnce<(u32,)>>::CallOnceFuture 239..240 'c': T - 239..243 'c(0)': AsyncFnOnce::CallOnceFuture<T, (u32,)> + 239..243 'c(0)': <T as AsyncFnOnce<(u32,)>>::CallOnceFuture 241..242 '0': u32 - 249..253 'fut3': AsyncFnOnce::CallOnceFuture<T, (u32,)> + 249..253 'fut3': <T as AsyncFnOnce<(u32,)>>::CallOnceFuture 249..259 'fut3.await': i32 "#]], ); @@ -4923,10 +4946,108 @@ fn main() { 46..53 'loop {}': ! 51..53 '{}': () 67..97 '{ ...()); }': () - 73..76 'foo': fn foo<impl AsyncFn() -> impl Future<Output = ()>, ()>(impl AsyncFn() -> impl Future<Output = ()>) + 73..76 'foo': fn foo<impl AsyncFn(), ()>(impl AsyncFn()) 73..94 'foo(as...|| ())': () - 77..93 'async ... || ()': impl AsyncFn() -> impl Future<Output = ()> + 77..93 'async ... || ()': impl AsyncFn() 91..93 '()': () "#]], ); } + +// FIXME(next-solver): Was `<D as Deserializer<'de>>::Error` but now getting error lifetime. +// This might be fixed once we migrate into next-solver fully without chalk-ir in lowering. +#[test] +fn new_solver_crash_1() { + check_infer( + r#" +pub trait Deserializer<'de> { + type Error; +} + +fn deserialize_abs_pathbuf<'de, D>(de: D) -> D::Error +where + D: Deserializer<'de>, +{ +} +"#, + expect![[r#" + 84..86 'de': D + 135..138 '{ }': <D as Deserializer<'de>>::Error + "#]], + ); +} + +#[test] +fn new_solver_crash_2() { + check_infer( + r#" +//- minicore: deref, send, sync +use core::ops::Deref; + +trait Error {} + +struct AnyhowError; + +impl Deref for AnyhowError { + type Target = dyn Error + Send + Sync; + + fn deref(&self) -> &Self::Target { loop {} } +} + +impl AnyhowError { + fn downcast<T>(self) {} +} + + +fn main() { + let e = AnyhowError; + e.downcast::<()>(); +} +"#, + expect![[r#" + 147..151 'self': &'? AnyhowError + 170..181 '{ loop {} }': &'? (dyn Error + Send + Sync + 'static) + 172..179 'loop {}': ! + 177..179 '{}': () + 223..227 'self': AnyhowError + 229..231 '{}': () + 246..298 '{ ...>(); }': () + 256..257 'e': AnyhowError + 260..271 'AnyhowError': AnyhowError + 277..278 'e': AnyhowError + 277..295 'e.down...<()>()': () + "#]], + ); +} + +#[test] +fn trait_object_binders() { + check_infer( + r#" +//- minicore: iterator, dispatch_from_dyn +fn main() { + struct Box<T: ?Sized>(*const T); + impl<I: Iterator + ?Sized> Iterator for Box<I> { + type Item = I::Item; + fn next(&mut self) -> Option<I::Item> { + loop {} + } + } + let iter: Box<dyn Iterator<Item = &[u8]> + 'static> = loop {}; + let _ = iter.into_iter(); +}"#, + expect![[r#" + 10..313 '{ ...r(); }': () + 223..227 'iter': Box<dyn Iterator<Item = &'? [u8]> + 'static> + 273..280 'loop {}': ! + 278..280 '{}': () + 290..291 '_': Box<dyn Iterator<Item = &'? [u8]> + '?> + 294..298 'iter': Box<dyn Iterator<Item = &'? [u8]> + 'static> + 294..310 'iter.i...iter()': Box<dyn Iterator<Item = &'? [u8]> + 'static> + 152..156 'self': &'? mut Box<I> + 177..208 '{ ... }': Option<<I as Iterator>::Item> + 191..198 'loop {}': ! + 196..198 '{}': () + "#]], + ); +} |