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.rs577
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 '{}': ()
+ "#]],
+ );
+}