fn test() {
let foo: Nat = Nat::Zero;
if let Nat::Succ(x) = foo {
- x
+ x;
} //^ Nat
}
"#,
fn infer_ranges() {
check_types(
r#"
-//- /main.rs crate:main deps:core
+//- minicore: range
fn test() {
let a = ..;
let b = 1..;
let t = (a, b, c, d, e, f);
t;
} //^ (RangeFull, RangeFrom<i32>, RangeTo<u32>, Range<usize>, RangeToInclusive<i32>, RangeInclusive<char>)
-
-//- /core.rs crate:core
-#[prelude_import] use prelude::*;
-mod prelude {}
-
-pub mod ops {
- pub struct Range<Idx> {
- pub start: Idx,
- pub end: Idx,
- }
- pub struct RangeFrom<Idx> {
- pub start: Idx,
- }
- struct RangeFull;
- pub struct RangeInclusive<Idx> {
- start: Idx,
- end: Idx,
- is_empty: u8,
- }
- pub struct RangeTo<Idx> {
- pub end: Idx,
- }
- pub struct RangeToInclusive<Idx> {
- pub end: Idx,
- }
-}
"#,
);
}
fn test() {
let foo: Option<f32> = None;
while let Option::Some(x) = foo {
- x
+ x;
} //^ f32
}
"#,
fn infer_basics() {
check_infer(
r#"
- fn test(a: u32, b: isize, c: !, d: &str) {
- a;
- b;
- c;
- d;
- 1usize;
- 1isize;
- "test";
- 1.0f32;
- }"#,
+fn test(a: u32, b: isize, c: !, d: &str) {
+ a;
+ b;
+ c;
+ d;
+ 1usize;
+ 1isize;
+ "test";
+ 1.0f32;
+}
+"#,
expect![[r#"
8..9 'a': u32
16..17 'b': isize
fn infer_let() {
check_infer(
r#"
- fn test() {
- let a = 1isize;
- let b: usize = 1;
- let c = b;
- let d: u32;
- let e;
- let f: i32 = e;
- }
- "#,
+fn test() {
+ let a = 1isize;
+ let b: usize = 1;
+ let c = b;
+ let d: u32;
+ let e;
+ let f: i32 = e;
+}
+"#,
expect![[r#"
10..117 '{ ...= e; }': ()
20..21 'a': isize
fn infer_paths() {
check_infer(
r#"
- fn a() -> u32 { 1 }
+fn a() -> u32 { 1 }
- mod b {
- fn c() -> u32 { 1 }
- }
+mod b {
+ fn c() -> u32 { 1 }
+}
- fn test() {
- a();
- b::c();
- }
- "#,
+fn test() {
+ a();
+ b::c();
+}
+"#,
expect![[r#"
14..19 '{ 1 }': u32
16..17 '1': u32
fn infer_path_type() {
check_infer(
r#"
- struct S;
+struct S;
- impl S {
- fn foo() -> i32 { 1 }
- }
+impl S {
+ fn foo() -> i32 { 1 }
+}
- fn test() {
- S::foo();
- <S>::foo();
- }
- "#,
+fn test() {
+ S::foo();
+ <S>::foo();
+}
+"#,
expect![[r#"
40..45 '{ 1 }': i32
42..43 '1': i32
fn infer_struct() {
check_infer(
r#"
- struct A {
- b: B,
- c: C,
- }
- struct B;
- struct C(usize);
+struct A {
+ b: B,
+ c: C,
+}
+struct B;
+struct C(usize);
- fn test() {
- let c = C(1);
- B;
- let a: A = A { b: B, c: C(1) };
- a.b;
- a.c;
- }
- "#,
+fn test() {
+ let c = C(1);
+ B;
+ let a: A = A { b: B, c: C(1) };
+ a.b;
+ a.c;
+}
+"#,
expect![[r#"
71..153 '{ ...a.c; }': ()
81..82 'c': C
fn infer_enum() {
check_infer(
r#"
- enum E {
- V1 { field: u32 },
- V2
- }
- fn test() {
- E::V1 { field: 1 };
- E::V2;
- }"#,
+enum E {
+ V1 { field: u32 },
+ V2
+}
+fn test() {
+ E::V1 { field: 1 };
+ E::V2;
+}
+"#,
expect![[r#"
51..89 '{ ...:V2; }': ()
57..75 'E::V1 ...d: 1 }': E
fn infer_union() {
check_infer(
r#"
- union MyUnion {
- foo: u32,
- bar: f32,
- }
+union MyUnion {
+ foo: u32,
+ bar: f32,
+}
- fn test() {
- let u = MyUnion { foo: 0 };
- unsafe { baz(u); }
- let u = MyUnion { bar: 0.0 };
- unsafe { baz(u); }
- }
+fn test() {
+ let u = MyUnion { foo: 0 };
+ unsafe { baz(u); }
+ let u = MyUnion { bar: 0.0 };
+ unsafe { baz(u); }
+}
- unsafe fn baz(u: MyUnion) {
- let inner = u.foo;
- let inner = u.bar;
- }
- "#,
+unsafe fn baz(u: MyUnion) {
+ let inner = u.foo;
+ let inner = u.bar;
+}
+"#,
expect![[r#"
57..172 '{ ...); } }': ()
67..68 'u': MyUnion
71..89 'MyUnio...o: 0 }': MyUnion
86..87 '0': u32
95..113 'unsafe...(u); }': ()
- 102..113 '{ baz(u); }': ()
+ 95..113 'unsafe...(u); }': ()
104..107 'baz': fn baz(MyUnion)
104..110 'baz(u)': ()
108..109 'u': MyUnion
126..146 'MyUnio... 0.0 }': MyUnion
141..144 '0.0': f32
152..170 'unsafe...(u); }': ()
- 159..170 '{ baz(u); }': ()
+ 152..170 'unsafe...(u); }': ()
161..164 'baz': fn baz(MyUnion)
161..167 'baz(u)': ()
165..166 'u': MyUnion
fn infer_refs() {
check_infer(
r#"
- fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
- a;
- *a;
- &a;
- &mut a;
- b;
- *b;
- &b;
- c;
- *c;
- d;
- *d;
- }
+fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
+ a;
+ *a;
+ &a;
+ &mut a;
+ b;
+ *b;
+ &b;
+ c;
+ *c;
+ d;
+ *d;
+}
"#,
expect![[r#"
8..9 'a': &u32
fn infer_raw_ref() {
check_infer(
r#"
- fn test(a: i32) {
- &raw mut a;
- &raw const a;
- }
- "#,
+fn test(a: i32) {
+ &raw mut a;
+ &raw const a;
+}
+"#,
expect![[r#"
8..9 'a': i32
16..53 '{ ...t a; }': ()
fn infer_unary_op() {
check_infer(
r#"
- enum SomeType {}
-
- fn test(x: SomeType) {
- let b = false;
- let c = !b;
- let a = 100;
- let d: i128 = -a;
- let e = -100;
- let f = !!!true;
- let g = !42;
- let h = !10u32;
- let j = !a;
- -3.14;
- !3;
- -x;
- !x;
- -"hello";
- !"hello";
- }
- "#,
+enum SomeType {}
+
+fn test(x: SomeType) {
+ let b = false;
+ let c = !b;
+ let a = 100;
+ let d: i128 = -a;
+ let e = -100;
+ let f = !!!true;
+ let g = !42;
+ let h = !10u32;
+ let j = !a;
+ -3.14;
+ !3;
+ -x;
+ !x;
+ -"hello";
+ !"hello";
+}
+"#,
expect![[r#"
26..27 'x': SomeType
39..271 '{ ...lo"; }': ()
fn infer_backwards() {
check_infer(
r#"
- fn takes_u32(x: u32) {}
+fn takes_u32(x: u32) {}
- struct S { i32_field: i32 }
+struct S { i32_field: i32 }
- fn test() -> &mut &f64 {
- let a = unknown_function();
- takes_u32(a);
- let b = unknown_function();
- S { i32_field: b };
- let c = unknown_function();
- &mut &c
- }
- "#,
+fn test() -> &mut &f64 {
+ let a = unknown_function();
+ takes_u32(a);
+ let b = unknown_function();
+ S { i32_field: b };
+ let c = unknown_function();
+ &mut &c
+}
+"#,
expect![[r#"
13..14 'x': u32
21..23 '{}': ()
fn infer_self() {
check_infer(
r#"
- struct S;
+struct S;
- impl S {
- fn test(&self) {
- self;
- }
- fn test2(self: &Self) {
- self;
- }
- fn test3() -> Self {
- S {}
- }
- fn test4() -> Self {
- Self {}
- }
- }
- "#,
+impl S {
+ fn test(&self) {
+ self;
+ }
+ fn test2(self: &Self) {
+ self;
+ }
+ fn test3() -> Self {
+ S {}
+ }
+ fn test4() -> Self {
+ Self {}
+ }
+}
+"#,
expect![[r#"
33..37 'self': &S
39..60 '{ ... }': ()
fn infer_self_as_path() {
check_infer(
r#"
- struct S1;
- struct S2(isize);
- enum E {
- V1,
- V2(u32),
- }
+struct S1;
+struct S2(isize);
+enum E {
+ V1,
+ V2(u32),
+}
- impl S1 {
- fn test() {
- Self;
- }
- }
- impl S2 {
- fn test() {
- Self(1);
- }
- }
- impl E {
- fn test() {
- Self::V1;
- Self::V2(1);
- }
- }
- "#,
+impl S1 {
+ fn test() {
+ Self;
+ }
+}
+impl S2 {
+ fn test() {
+ Self(1);
+ }
+}
+impl E {
+ fn test() {
+ Self::V1;
+ Self::V2(1);
+ }
+}
+"#,
expect![[r#"
86..107 '{ ... }': ()
96..100 'Self': S1
fn infer_binary_op() {
check_infer(
r#"
- fn f(x: bool) -> i32 {
- 0i32
- }
+fn f(x: bool) -> i32 {
+ 0i32
+}
- fn test() -> bool {
- let x = a && b;
- let y = true || false;
- let z = x == y;
- let t = x != y;
- let minus_forty: isize = -40isize;
- let h = minus_forty <= CONST_2;
- let c = f(z || y) + 5;
- let d = b;
- let g = minus_forty ^= i;
- let ten: usize = 10;
- let ten_is_eleven = ten == some_num;
-
- ten < 3
- }
- "#,
+fn test() -> bool {
+ let x = a && b;
+ let y = true || false;
+ let z = x == y;
+ let t = x != y;
+ let minus_forty: isize = -40isize;
+ let h = minus_forty <= CONST_2;
+ let c = f(z || y) + 5;
+ let d = b;
+ let g = minus_forty ^= i;
+ let ten: usize = 10;
+ let ten_is_eleven = ten == some_num;
+
+ ten < 3
+}
+"#,
expect![[r#"
5..6 'x': bool
21..33 '{ 0i32 }': i32
fn infer_shift_op() {
check_infer(
r#"
- fn test() {
- 1u32 << 5u8;
- 1u32 >> 5u8;
- }
- "#,
+fn test() {
+ 1u32 << 5u8;
+ 1u32 >> 5u8;
+}
+"#,
expect![[r#"
10..47 '{ ...5u8; }': ()
16..20 '1u32': u32
fn infer_field_autoderef() {
check_infer(
r#"
- struct A {
- b: B,
- }
- struct B;
-
- fn test1(a: A) {
- let a1 = a;
- a1.b;
- let a2 = &a;
- a2.b;
- let a3 = &mut a;
- a3.b;
- let a4 = &&&&&&&a;
- a4.b;
- let a5 = &mut &&mut &&mut a;
- a5.b;
- }
+struct A {
+ b: B,
+}
+struct B;
- fn test2(a1: *const A, a2: *mut A) {
- a1.b;
- a2.b;
- }
- "#,
+fn test1(a: A) {
+ let a1 = a;
+ a1.b;
+ let a2 = &a;
+ a2.b;
+ let a3 = &mut a;
+ a3.b;
+ let a4 = &&&&&&&a;
+ a4.b;
+ let a5 = &mut &&mut &&mut a;
+ a5.b;
+}
+
+fn test2(a1: *const A, a2: *mut A) {
+ a1.b;
+ a2.b;
+}
+"#,
expect![[r#"
43..44 'a': A
49..212 '{ ...5.b; }': ()
fn infer_argument_autoderef() {
check_infer(
r#"
- #[lang = "deref"]
- pub trait Deref {
- type Target;
- fn deref(&self) -> &Self::Target;
- }
-
- struct A<T>(T);
+//- minicore: deref
+use core::ops::Deref;
+struct A<T>(T);
- impl<T> A<T> {
- fn foo(&self) -> &T {
- &self.0
- }
- }
+impl<T> A<T> {
+ fn foo(&self) -> &T {
+ &self.0
+ }
+}
- struct B<T>(T);
+struct B<T>(T);
- impl<T> Deref for B<T> {
- type Target = T;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
- }
+impl<T> Deref for B<T> {
+ type Target = T;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
- fn test() {
- let t = A::foo(&&B(B(A(42))));
- }
- "#,
+fn test() {
+ let t = A::foo(&&B(B(A(42))));
+}
+"#,
expect![[r#"
- 67..71 'self': &Self
- 138..142 'self': &A<T>
- 150..173 '{ ... }': &T
- 160..167 '&self.0': &T
- 161..165 'self': &A<T>
- 161..167 'self.0': T
- 254..258 'self': &B<T>
- 277..300 '{ ... }': &T
- 287..294 '&self.0': &T
- 288..292 'self': &B<T>
- 288..294 'self.0': T
- 314..352 '{ ...))); }': ()
- 324..325 't': &i32
- 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32
- 328..349 'A::foo...42))))': &i32
- 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>>
- 336..348 '&B(B(A(42)))': &B<B<A<i32>>>
- 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
- 337..348 'B(B(A(42)))': B<B<A<i32>>>
- 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
- 339..347 'B(A(42))': B<A<i32>>
- 341..342 'A': A<i32>(i32) -> A<i32>
- 341..346 'A(42)': A<i32>
- 343..345 '42': i32
+ 66..70 'self': &A<T>
+ 78..101 '{ ... }': &T
+ 88..95 '&self.0': &T
+ 89..93 'self': &A<T>
+ 89..95 'self.0': T
+ 182..186 'self': &B<T>
+ 205..228 '{ ... }': &T
+ 215..222 '&self.0': &T
+ 216..220 'self': &B<T>
+ 216..222 'self.0': T
+ 242..280 '{ ...))); }': ()
+ 252..253 't': &i32
+ 256..262 'A::foo': fn foo<i32>(&A<i32>) -> &i32
+ 256..277 'A::foo...42))))': &i32
+ 263..276 '&&B(B(A(42)))': &&B<B<A<i32>>>
+ 264..276 '&B(B(A(42)))': &B<B<A<i32>>>
+ 265..266 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
+ 265..276 'B(B(A(42)))': B<B<A<i32>>>
+ 267..268 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
+ 267..275 'B(A(42))': B<A<i32>>
+ 269..270 'A': A<i32>(i32) -> A<i32>
+ 269..274 'A(42)': A<i32>
+ 271..273 '42': i32
"#]],
);
}
fn infer_method_argument_autoderef() {
check_infer(
r#"
- #[lang = "deref"]
- pub trait Deref {
- type Target;
- fn deref(&self) -> &Self::Target;
- }
-
- struct A<T>(*mut T);
+//- minicore: deref
+use core::ops::Deref;
+struct A<T>(*mut T);
- impl<T> A<T> {
- fn foo(&self, x: &A<T>) -> &T {
- &*x.0
- }
- }
+impl<T> A<T> {
+ fn foo(&self, x: &A<T>) -> &T {
+ &*x.0
+ }
+}
- struct B<T>(T);
+struct B<T>(T);
- impl<T> Deref for B<T> {
- type Target = T;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
- }
+impl<T> Deref for B<T> {
+ type Target = T;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
- fn test(a: A<i32>) {
- let t = A(0 as *mut _).foo(&&B(B(a)));
- }
- "#,
+fn test(a: A<i32>) {
+ let t = A(0 as *mut _).foo(&&B(B(a)));
+}
+"#,
expect![[r#"
- 67..71 'self': &Self
- 143..147 'self': &A<T>
- 149..150 'x': &A<T>
- 165..186 '{ ... }': &T
- 175..180 '&*x.0': &T
- 176..180 '*x.0': T
- 177..178 'x': &A<T>
- 177..180 'x.0': *mut T
- 267..271 'self': &B<T>
- 290..313 '{ ... }': &T
- 300..307 '&self.0': &T
- 301..305 'self': &B<T>
- 301..307 'self.0': T
- 325..326 'a': A<i32>
- 336..382 '{ ...))); }': ()
- 346..347 't': &i32
- 350..351 'A': A<i32>(*mut i32) -> A<i32>
- 350..364 'A(0 as *mut _)': A<i32>
- 350..379 'A(0 as...B(a)))': &i32
- 352..353 '0': i32
- 352..363 '0 as *mut _': *mut i32
- 369..378 '&&B(B(a))': &&B<B<A<i32>>>
- 370..378 '&B(B(a))': &B<B<A<i32>>>
- 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
- 371..378 'B(B(a))': B<B<A<i32>>>
- 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
- 373..377 'B(a)': B<A<i32>>
- 375..376 'a': A<i32>
+ 71..75 'self': &A<T>
+ 77..78 'x': &A<T>
+ 93..114 '{ ... }': &T
+ 103..108 '&*x.0': &T
+ 104..108 '*x.0': T
+ 105..106 'x': &A<T>
+ 105..108 'x.0': *mut T
+ 195..199 'self': &B<T>
+ 218..241 '{ ... }': &T
+ 228..235 '&self.0': &T
+ 229..233 'self': &B<T>
+ 229..235 'self.0': T
+ 253..254 'a': A<i32>
+ 264..310 '{ ...))); }': ()
+ 274..275 't': &i32
+ 278..279 'A': A<i32>(*mut i32) -> A<i32>
+ 278..292 'A(0 as *mut _)': A<i32>
+ 278..307 'A(0 as...B(a)))': &i32
+ 280..281 '0': i32
+ 280..291 '0 as *mut _': *mut i32
+ 297..306 '&&B(B(a))': &&B<B<A<i32>>>
+ 298..306 '&B(B(a))': &B<B<A<i32>>>
+ 299..300 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
+ 299..306 'B(B(a))': B<B<A<i32>>>
+ 301..302 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
+ 301..305 'B(a)': B<A<i32>>
+ 303..304 'a': A<i32>
"#]],
);
}
fn infer_in_elseif() {
check_infer(
r#"
- struct Foo { field: i32 }
- fn main(foo: Foo) {
- if true {
+struct Foo { field: i32 }
+fn main(foo: Foo) {
+ if true {
- } else if false {
- foo.field
- }
- }
- "#,
+ } else if false {
+ foo.field
+ }
+}
+"#,
expect![[r#"
34..37 'foo': Foo
44..108 '{ ... } }': ()
fn infer_if_match_with_return() {
check_infer(
r#"
- fn foo() {
- let _x1 = if true {
- 1
- } else {
- return;
- };
- let _x2 = if true {
- 2
- } else {
- return
- };
- let _x3 = match true {
- true => 3,
- _ => {
- return;
- }
- };
- let _x4 = match true {
- true => 4,
- _ => return
- };
- }"#,
+fn foo() {
+ let _x1 = if true {
+ 1
+ } else {
+ return;
+ };
+ let _x2 = if true {
+ 2
+ } else {
+ return
+ };
+ let _x3 = match true {
+ true => 3,
+ _ => {
+ return;
+ }
+ };
+ let _x4 = match true {
+ true => 4,
+ _ => return
+ };
+}
+"#,
expect![[r#"
9..322 '{ ... }; }': ()
19..22 '_x1': i32
fn main() {
let x: i32 = i32;
x.foo();
- //^ Foo
+ //^^^^^^^ Foo
}"#,
);
}
fn inner() {}
let x: i32 = i32;
x.foo();
- //^ Foo
+ //^^^^^^^ Foo
}"#,
);
}
fn main() {
foo();
- //^ &str
+ //^^^^^ &str
}"#,
);
}
fn main() {
str::foo();
- //^ u32
+ //^^^^^^^^^^ u32
}"#,
);
}
fn main() {
d::foo();
- //^ u8
+ //^^^^^^^^ u8
d::foo{a:0};
- //^ u8
+ //^^^^^^^^^^^ foo
}"#,
);
}
}
#[test]
-fn effects_smoke_test() {
+fn block_modifiers_smoke_test() {
check_infer(
r#"
- async fn main() {
- let x = unsafe { 92 };
- let y = async { async { () }.await };
- let z = try { () };
- let w = const { 92 };
- let t = 'a: { 92 };
- }
-
- #[prelude_import] use future::*;
-
- mod future {
- #[lang = "future_trait"]
- pub trait Future { type Output; }
- }
+//- minicore: future
+async fn main() {
+ let x = unsafe { 92 };
+ let y = async { async { () }.await };
+ let z = try { () };
+ let w = const { 92 };
+ let t = 'a: { 92 };
+}
"#,
expect![[r#"
16..162 '{ ...2 }; }': ()
26..27 'x': i32
30..43 'unsafe { 92 }': i32
- 37..43 '{ 92 }': i32
+ 30..43 'unsafe { 92 }': i32
39..41 '92': i32
53..54 'y': impl Future<Output = ()>
+ 57..85 'async ...wait }': ()
57..85 'async ...wait }': impl Future<Output = ()>
- 63..85 '{ asyn...wait }': ()
+ 65..77 'async { () }': ()
65..77 'async { () }': impl Future<Output = ()>
65..83 'async ....await': ()
- 71..77 '{ () }': ()
73..75 '()': ()
95..96 'z': {unknown}
+ 99..109 'try { () }': ()
99..109 'try { () }': {unknown}
- 103..109 '{ () }': ()
105..107 '()': ()
119..120 'w': i32
123..135 'const { 92 }': i32
- 129..135 '{ 92 }': i32
+ 123..135 'const { 92 }': i32
131..133 '92': i32
145..146 't': i32
- 153..159 '{ 92 }': i32
+ 149..159 ''a: { 92 }': i32
155..157 '92': i32
"#]],
)
fn infer_labelled_block_break_with_val() {
check_infer(
r#"
- fn default<T>() -> T { loop {} }
- fn foo() {
- let _x = 'outer: {
- let inner = 'inner: {
- let i = default();
- if (break 'outer i) {
- break 'inner 5i8;
- } else if true {
- break 'inner 6;
- }
- break 'inner 'innermost: { 0 };
- 42
- };
- break 'outer inner < 8;
- };
- }
- "#,
+fn default<T>() -> T { loop {} }
+fn foo() {
+ let _x = 'outer: {
+ let inner = 'inner: {
+ let i = default();
+ if (break 'outer i) {
+ break 'inner 5i8;
+ } else if true {
+ break 'inner 6;
+ }
+ break 'inner 'innermost: { 0 };
+ 42
+ };
+ break 'outer inner < 8;
+ };
+}
+"#,
expect![[r#"
21..32 '{ loop {} }': T
23..30 'loop {}': !
28..30 '{}': ()
42..381 '{ ... }; }': ()
52..54 '_x': bool
- 65..378 '{ ... }': bool
+ 57..378 ''outer... }': bool
79..84 'inner': i8
- 95..339 '{ ... }': i8
+ 87..339 ''inner... }': i8
113..114 'i': bool
117..124 'default': fn default<bool>() -> bool
117..126 'default()': bool
241..255 'break 'inner 6': !
254..255 '6': i8
283..313 'break ... { 0 }': !
- 308..313 '{ 0 }': i8
+ 296..313 ''inner... { 0 }': i8
310..311 '0': i8
327..329 '42': i8
349..371 'break ...er < 8': !
176..193 'Thing ...1i32 }': Thing<i32>
187..191 '1i32': i32
199..240 'if let... }': ()
+ 202..221 'let Th... } = z': bool
206..217 'Thing { t }': Thing<i32>
214..215 't': i32
220..221 'z': Thing<i32>
#[test]
fn infer_operator_overload() {
- cov_mark::check!(infer_expr_inner_binary_operator_overload);
-
- check_infer(
+ check_types(
r#"
- struct V2([f32; 2]);
+//- minicore: add
+struct V2([f32; 2]);
- #[lang = "add"]
- pub trait Add<Rhs = Self> {
- /// The resulting type after applying the `+` operator.
- type Output;
-
- /// Performs the `+` operation.
- #[must_use]
- fn add(self, rhs: Rhs) -> Self::Output;
- }
-
- impl Add<V2> for V2 {
- type Output = V2;
-
- fn add(self, rhs: V2) -> V2 {
- let x = self.0[0] + rhs.0[0];
- let y = self.0[1] + rhs.0[1];
- V2([x, y])
- }
- }
+impl core::ops::Add<V2> for V2 {
+ type Output = V2;
+}
- fn test() {
- let va = V2([0.0, 1.0]);
- let vb = V2([0.0, 1.0]);
+fn test() {
+ let va = V2([0.0, 1.0]);
+ let vb = V2([0.0, 1.0]);
- let r = va + vb;
- }
+ let r = va + vb;
+ // ^^^^^^^ V2
+}
"#,
- expect![[r#"
- 207..211 'self': Self
- 213..216 'rhs': Rhs
- 299..303 'self': V2
- 305..308 'rhs': V2
- 320..422 '{ ... }': V2
- 334..335 'x': f32
- 338..342 'self': V2
- 338..344 'self.0': [f32; 2]
- 338..347 'self.0[0]': {unknown}
- 338..358 'self.0...s.0[0]': f32
- 345..346 '0': i32
- 350..353 'rhs': V2
- 350..355 'rhs.0': [f32; 2]
- 350..358 'rhs.0[0]': {unknown}
- 356..357 '0': i32
- 372..373 'y': f32
- 376..380 'self': V2
- 376..382 'self.0': [f32; 2]
- 376..385 'self.0[1]': {unknown}
- 376..396 'self.0...s.0[1]': f32
- 383..384 '1': i32
- 388..391 'rhs': V2
- 388..393 'rhs.0': [f32; 2]
- 388..396 'rhs.0[1]': {unknown}
- 394..395 '1': i32
- 406..408 'V2': V2([f32; 2]) -> V2
- 406..416 'V2([x, y])': V2
- 409..415 '[x, y]': [f32; 2]
- 410..411 'x': f32
- 413..414 'y': f32
- 436..519 '{ ... vb; }': ()
- 446..448 'va': V2
- 451..453 'V2': V2([f32; 2]) -> V2
- 451..465 'V2([0.0, 1.0])': V2
- 454..464 '[0.0, 1.0]': [f32; 2]
- 455..458 '0.0': f32
- 460..463 '1.0': f32
- 475..477 'vb': V2
- 480..482 'V2': V2([f32; 2]) -> V2
- 480..494 'V2([0.0, 1.0])': V2
- 483..493 '[0.0, 1.0]': [f32; 2]
- 484..487 '0.0': f32
- 489..492 '1.0': f32
- 505..506 'r': V2
- 509..511 'va': V2
- 509..516 'va + vb': V2
- 514..516 'vb': V2
- "#]],
);
}
fn infer_boxed_self_receiver() {
check_infer(
r#"
-#[lang = "deref"]
-pub trait Deref {
- type Target;
- fn deref(&self) -> &Self::Target;
-}
+//- minicore: deref
+use core::ops::Deref;
struct Box<T>(T);
}
"#,
expect![[r#"
- 67..71 'self': &Self
- 175..179 'self': &Box<T>
- 259..263 'self': &Box<Foo<T>>
- 289..291 '{}': ()
- 313..317 'self': &Box<Foo<T>>
- 346..348 '{}': ()
- 368..372 'self': Box<Foo<T>>
- 393..395 '{}': ()
- 409..630 '{ ...r(); }': ()
- 419..424 'boxed': Box<Foo<i32>>
- 427..430 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
- 427..442 'Box(Foo(0_i32))': Box<Foo<i32>>
- 431..434 'Foo': Foo<i32>(i32) -> Foo<i32>
- 431..441 'Foo(0_i32)': Foo<i32>
- 435..440 '0_i32': i32
- 453..457 'bad1': &i32
- 460..465 'boxed': Box<Foo<i32>>
- 460..477 'boxed....nner()': &i32
- 487..492 'good1': &i32
- 495..509 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
- 495..517 'Foo::g...boxed)': &i32
- 510..516 '&boxed': &Box<Foo<i32>>
- 511..516 'boxed': Box<Foo<i32>>
- 528..532 'bad2': &Foo<i32>
- 535..540 'boxed': Box<Foo<i32>>
- 535..551 'boxed....self()': &Foo<i32>
- 561..566 'good2': &Foo<i32>
- 569..582 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
- 569..590 'Foo::g...boxed)': &Foo<i32>
- 583..589 '&boxed': &Box<Foo<i32>>
- 584..589 'boxed': Box<Foo<i32>>
- 601..606 'inner': Foo<i32>
- 609..614 'boxed': Box<Foo<i32>>
- 609..627 'boxed....nner()': Foo<i32>
+ 104..108 'self': &Box<T>
+ 188..192 'self': &Box<Foo<T>>
+ 218..220 '{}': ()
+ 242..246 'self': &Box<Foo<T>>
+ 275..277 '{}': ()
+ 297..301 'self': Box<Foo<T>>
+ 322..324 '{}': ()
+ 338..559 '{ ...r(); }': ()
+ 348..353 'boxed': Box<Foo<i32>>
+ 356..359 'Box': Box<Foo<i32>>(Foo<i32>) -> Box<Foo<i32>>
+ 356..371 'Box(Foo(0_i32))': Box<Foo<i32>>
+ 360..363 'Foo': Foo<i32>(i32) -> Foo<i32>
+ 360..370 'Foo(0_i32)': Foo<i32>
+ 364..369 '0_i32': i32
+ 382..386 'bad1': &i32
+ 389..394 'boxed': Box<Foo<i32>>
+ 389..406 'boxed....nner()': &i32
+ 416..421 'good1': &i32
+ 424..438 'Foo::get_inner': fn get_inner<i32>(&Box<Foo<i32>>) -> &i32
+ 424..446 'Foo::g...boxed)': &i32
+ 439..445 '&boxed': &Box<Foo<i32>>
+ 440..445 'boxed': Box<Foo<i32>>
+ 457..461 'bad2': &Foo<i32>
+ 464..469 'boxed': Box<Foo<i32>>
+ 464..480 'boxed....self()': &Foo<i32>
+ 490..495 'good2': &Foo<i32>
+ 498..511 'Foo::get_self': fn get_self<i32>(&Box<Foo<i32>>) -> &Foo<i32>
+ 498..519 'Foo::g...boxed)': &Foo<i32>
+ 512..518 '&boxed': &Box<Foo<i32>>
+ 513..518 'boxed': Box<Foo<i32>>
+ 530..535 'inner': Foo<i32>
+ 538..543 'boxed': Box<Foo<i32>>
+ 538..556 'boxed....nner()': Foo<i32>
"#]],
);
}
+
+#[test]
+fn prelude_2015() {
+ check_types(
+ r#"
+//- /main.rs edition:2015 crate:main deps:core
+fn f() {
+ Rust;
+ //^^^^ Rust
+}
+
+//- /core.rs crate:core
+pub mod prelude {
+ pub mod rust_2015 {
+ pub struct Rust;
+ }
+}
+ "#,
+ );
+}