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
}
"#,
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 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]);
-
- #[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;
+//- minicore: add
+struct V2([f32; 2]);
- 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>
"#]],
);
}
//- /main.rs edition:2015 crate:main deps:core
fn f() {
Rust;
- //^ Rust
+ //^^^^ Rust
}
//- /core.rs crate:core