From f7e4b99d154fa85e4f37aa9e53d4ffb8f4a0073e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Tue, 21 Jul 2020 13:08:55 +0300 Subject: Replace remaining insta uses --- crates/ra_hir_ty/src/tests/macros.rs | 620 ++-- crates/ra_hir_ty/src/tests/method_resolution.rs | 1150 ++++---- crates/ra_hir_ty/src/tests/patterns.rs | 1102 ++++---- crates/ra_hir_ty/src/tests/regression.rs | 1172 ++++---- crates/ra_hir_ty/src/tests/simple.rs | 3413 ++++++++++++----------- crates/ra_hir_ty/src/tests/traits.rs | 3274 +++++++++++----------- 6 files changed, 5366 insertions(+), 5365 deletions(-) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 45c4e309e..24c53eb02 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs @@ -1,9 +1,9 @@ use std::fs; -use insta::assert_snapshot; +use expect::expect; use test_utils::project_dir; -use super::{check_types, infer}; +use super::{check_infer, check_types}; #[test] fn cfg_impl_def() { @@ -46,204 +46,204 @@ impl S { #[test] fn infer_macros_expanded() { - assert_snapshot!( - infer(r#" -struct Foo(Vec); - -macro_rules! foo { - ($($item:expr),*) => { - { - Foo(vec![$($item,)*]) - } - }; -} + check_infer( + r#" + struct Foo(Vec); + + macro_rules! foo { + ($($item:expr),*) => { + { + Foo(vec![$($item,)*]) + } + }; + } -fn main() { - let x = foo!(1,2); -} -"#), - @r###" - !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': Foo({unknown}) -> Foo - !1..16 'Foo(vec![1,2,])': Foo - !5..15 'vec![1,2,]': {unknown} - 155..181 '{ ...,2); }': () - 165..166 'x': Foo - "### + fn main() { + let x = foo!(1,2); + } + "#, + expect![[r#" + !0..17 '{Foo(v...,2,])}': Foo + !1..4 'Foo': Foo({unknown}) -> Foo + !1..16 'Foo(vec![1,2,])': Foo + !5..15 'vec![1,2,]': {unknown} + 155..181 '{ ...,2); }': () + 165..166 'x': Foo + "#]], ); } #[test] fn infer_legacy_textual_scoped_macros_expanded() { - assert_snapshot!( - infer(r#" -struct Foo(Vec); - -#[macro_use] -mod m { - macro_rules! foo { - ($($item:expr),*) => { - { - Foo(vec![$($item,)*]) + check_infer( + r#" + struct Foo(Vec); + + #[macro_use] + mod m { + macro_rules! foo { + ($($item:expr),*) => { + { + Foo(vec![$($item,)*]) + } + }; } - }; - } -} + } -fn main() { - let x = foo!(1,2); - let y = crate::foo!(1,2); -} -"#), - @r###" - !0..17 '{Foo(v...,2,])}': Foo - !1..4 'Foo': Foo({unknown}) -> Foo - !1..16 'Foo(vec![1,2,])': Foo - !5..15 'vec![1,2,]': {unknown} - 194..250 '{ ...,2); }': () - 204..205 'x': Foo - 227..228 'y': {unknown} - 231..247 'crate:...!(1,2)': {unknown} - "### + fn main() { + let x = foo!(1,2); + let y = crate::foo!(1,2); + } + "#, + expect![[r#" + !0..17 '{Foo(v...,2,])}': Foo + !1..4 'Foo': Foo({unknown}) -> Foo + !1..16 'Foo(vec![1,2,])': Foo + !5..15 'vec![1,2,]': {unknown} + 194..250 '{ ...,2); }': () + 204..205 'x': Foo + 227..228 'y': {unknown} + 231..247 'crate:...!(1,2)': {unknown} + "#]], ); } #[test] fn infer_path_qualified_macros_expanded() { - assert_snapshot!( - infer(r#" -#[macro_export] -macro_rules! foo { - () => { 42i32 } -} + check_infer( + r#" + #[macro_export] + macro_rules! foo { + () => { 42i32 } + } -mod m { - pub use super::foo as bar; -} + mod m { + pub use super::foo as bar; + } -fn main() { - let x = crate::foo!(); - let y = m::bar!(); -} -"#), - @r###" - !0..5 '42i32': i32 - !0..5 '42i32': i32 - 110..163 '{ ...!(); }': () - 120..121 'x': i32 - 147..148 'y': i32 - "### + fn main() { + let x = crate::foo!(); + let y = m::bar!(); + } + "#, + expect![[r#" + !0..5 '42i32': i32 + !0..5 '42i32': i32 + 110..163 '{ ...!(); }': () + 120..121 'x': i32 + 147..148 'y': i32 + "#]], ); } #[test] fn expr_macro_expanded_in_various_places() { - assert_snapshot!( - infer(r#" -macro_rules! spam { - () => (1isize); -} - -fn spam() { - spam!(); - (spam!()); - spam!().spam(spam!()); - for _ in spam!() {} - || spam!(); - while spam!() {} - break spam!(); - return spam!(); - match spam!() { - _ if spam!() => spam!(), - } - spam!()(spam!()); - Spam { spam: spam!() }; - spam!()[spam!()]; - await spam!(); - spam!() as usize; - &spam!(); - -spam!(); - spam!()..spam!(); - spam!() + spam!(); -} -"#), - @r###" - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - !0..6 '1isize': isize - 53..456 '{ ...!(); }': () - 87..108 'spam!(...am!())': {unknown} - 114..133 'for _ ...!() {}': () - 118..119 '_': {unknown} - 131..133 '{}': () - 138..148 '|| spam!()': || -> isize - 154..170 'while ...!() {}': () - 168..170 '{}': () - 175..188 'break spam!()': ! - 194..208 'return spam!()': ! - 214..268 'match ... }': isize - 238..239 '_': isize - 273..289 'spam!(...am!())': {unknown} - 295..317 'Spam {...m!() }': {unknown} - 323..339 'spam!(...am!()]': {unknown} - 364..380 'spam!(... usize': usize - 386..394 '&spam!()': &isize - 400..408 '-spam!()': isize - 414..430 'spam!(...pam!()': {unknown} - 436..453 'spam!(...pam!()': isize - "### + check_infer( + r#" + macro_rules! spam { + () => (1isize); + } + + fn spam() { + spam!(); + (spam!()); + spam!().spam(spam!()); + for _ in spam!() {} + || spam!(); + while spam!() {} + break spam!(); + return spam!(); + match spam!() { + _ if spam!() => spam!(), + } + spam!()(spam!()); + Spam { spam: spam!() }; + spam!()[spam!()]; + await spam!(); + spam!() as usize; + &spam!(); + -spam!(); + spam!()..spam!(); + spam!() + spam!(); + } + "#, + expect![[r#" + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + !0..6 '1isize': isize + 53..456 '{ ...!(); }': () + 87..108 'spam!(...am!())': {unknown} + 114..133 'for _ ...!() {}': () + 118..119 '_': {unknown} + 131..133 '{}': () + 138..148 '|| spam!()': || -> isize + 154..170 'while ...!() {}': () + 168..170 '{}': () + 175..188 'break spam!()': ! + 194..208 'return spam!()': ! + 214..268 'match ... }': isize + 238..239 '_': isize + 273..289 'spam!(...am!())': {unknown} + 295..317 'Spam {...m!() }': {unknown} + 323..339 'spam!(...am!()]': {unknown} + 364..380 'spam!(... usize': usize + 386..394 '&spam!()': &isize + 400..408 '-spam!()': isize + 414..430 'spam!(...pam!()': {unknown} + 436..453 'spam!(...pam!()': isize + "#]], ); } #[test] fn infer_type_value_macro_having_same_name() { - assert_snapshot!( - infer(r#" -#[macro_export] -macro_rules! foo { - () => { - mod foo { - pub use super::foo; + check_infer( + r#" + #[macro_export] + macro_rules! foo { + () => { + mod foo { + pub use super::foo; + } + }; + ($x:tt) => { + $x + }; } - }; - ($x:tt) => { - $x - }; -} -foo!(); + foo!(); -fn foo() { - let foo = foo::foo!(42i32); -} -"#), - @r###" - !0..5 '42i32': i32 - 170..205 '{ ...32); }': () - 180..183 'foo': i32 - "### + fn foo() { + let foo = foo::foo!(42i32); + } + "#, + expect![[r#" + !0..5 '42i32': i32 + 170..205 '{ ...32); }': () + 180..183 'foo': i32 + "#]], ); } @@ -372,50 +372,50 @@ expand!(); #[test] fn infer_type_value_non_legacy_macro_use_as() { - assert_snapshot!( - infer(r#" -mod m { - macro_rules! _foo { - ($x:ident) => { type $x = u64; } - } - pub(crate) use _foo as foo; -} + check_infer( + r#" + mod m { + macro_rules! _foo { + ($x:ident) => { type $x = u64; } + } + pub(crate) use _foo as foo; + } -m::foo!(foo); -use foo as bar; -fn f() -> bar { 0 } -fn main() { - let _a = f(); -} -"#), - @r###" - 158..163 '{ 0 }': u64 - 160..161 '0': u64 - 174..196 '{ ...f(); }': () - 184..186 '_a': u64 - 190..191 'f': fn f() -> u64 - 190..193 'f()': u64 - "### + m::foo!(foo); + use foo as bar; + fn f() -> bar { 0 } + fn main() { + let _a = f(); + } + "#, + expect![[r#" + 158..163 '{ 0 }': u64 + 160..161 '0': u64 + 174..196 '{ ...f(); }': () + 184..186 '_a': u64 + 190..191 'f': fn f() -> u64 + 190..193 'f()': u64 + "#]], ); } #[test] fn infer_local_macro() { - assert_snapshot!( - infer(r#" -fn main() { - macro_rules! foo { - () => { 1usize } - } - let _a = foo!(); -} -"#), - @r###" - !0..6 '1usize': usize - 10..89 '{ ...!(); }': () - 16..65 'macro_... }': {unknown} - 74..76 '_a': usize - "### + check_infer( + r#" + fn main() { + macro_rules! foo { + () => { 1usize } + } + let _a = foo!(); + } + "#, + expect![[r#" + !0..6 '1usize': usize + 10..89 '{ ...!(); }': () + 16..65 'macro_... }': {unknown} + 74..76 '_a': usize + "#]], ); } @@ -446,77 +446,77 @@ macro_rules! bar { #[test] fn infer_builtin_macros_line() { - assert_snapshot!( - infer(r#" -#[rustc_builtin_macro] -macro_rules! line {() => {}} + check_infer( + r#" + #[rustc_builtin_macro] + macro_rules! line {() => {}} -fn main() { - let x = line!(); -} -"#), - @r###" - !0..1 '0': i32 - 63..87 '{ ...!(); }': () - 73..74 'x': i32 - "### + fn main() { + let x = line!(); + } + "#, + expect![[r#" + !0..1 '0': i32 + 63..87 '{ ...!(); }': () + 73..74 'x': i32 + "#]], ); } #[test] fn infer_builtin_macros_file() { - assert_snapshot!( - infer(r#" -#[rustc_builtin_macro] -macro_rules! file {() => {}} + check_infer( + r#" + #[rustc_builtin_macro] + macro_rules! file {() => {}} -fn main() { - let x = file!(); -} -"#), - @r###" - !0..2 '""': &str - 63..87 '{ ...!(); }': () - 73..74 'x': &str - "### + fn main() { + let x = file!(); + } + "#, + expect![[r#" + !0..2 '""': &str + 63..87 '{ ...!(); }': () + 73..74 'x': &str + "#]], ); } #[test] fn infer_builtin_macros_column() { - assert_snapshot!( - infer(r#" -#[rustc_builtin_macro] -macro_rules! column {() => {}} + check_infer( + r#" + #[rustc_builtin_macro] + macro_rules! column {() => {}} -fn main() { - let x = column!(); -} -"#), - @r###" - !0..1 '0': i32 - 65..91 '{ ...!(); }': () - 75..76 'x': i32 - "### + fn main() { + let x = column!(); + } + "#, + expect![[r#" + !0..1 '0': i32 + 65..91 '{ ...!(); }': () + 75..76 'x': i32 + "#]], ); } #[test] fn infer_builtin_macros_concat() { - assert_snapshot!( - infer(r#" -#[rustc_builtin_macro] -macro_rules! concat {() => {}} + check_infer( + r#" + #[rustc_builtin_macro] + macro_rules! concat {() => {}} -fn main() { - let x = concat!("hello", concat!("world", "!")); -} -"#), - @r###" - !0..13 '"helloworld!"': &str - 65..121 '{ ...")); }': () - 75..76 'x': &str - "### + fn main() { + let x = concat!("hello", concat!("world", "!")); + } + "#, + expect![[r#" + !0..13 '"helloworld!"': &str + 65..121 '{ ...")); }': () + 75..76 'x': &str + "#]], ); } @@ -622,7 +622,7 @@ macro_rules! include {() => {}} include!("main.rs"); fn main() { - 0 + 0 } //^ i32 "#, ); @@ -630,42 +630,42 @@ fn main() { #[test] fn infer_builtin_macros_concat_with_lazy() { - assert_snapshot!( - infer(r#" -macro_rules! hello {() => {"hello"}} + check_infer( + r#" + macro_rules! hello {() => {"hello"}} -#[rustc_builtin_macro] -macro_rules! concat {() => {}} + #[rustc_builtin_macro] + macro_rules! concat {() => {}} -fn main() { - let x = concat!(hello!(), concat!("world", "!")); -} -"#), - @r###" - !0..13 '"helloworld!"': &str - 103..160 '{ ...")); }': () - 113..114 'x': &str - "### + fn main() { + let x = concat!(hello!(), concat!("world", "!")); + } + "#, + expect![[r#" + !0..13 '"helloworld!"': &str + 103..160 '{ ...")); }': () + 113..114 'x': &str + "#]], ); } #[test] fn infer_builtin_macros_env() { - assert_snapshot!( - infer(r#" -//- /main.rs env:foo=bar -#[rustc_builtin_macro] -macro_rules! env {() => {}} + check_infer( + r#" + //- /main.rs env:foo=bar + #[rustc_builtin_macro] + macro_rules! env {() => {}} -fn main() { - let x = env!("foo"); -} -"#), - @r###" - !0..22 '"__RA_...TED__"': &str - 62..90 '{ ...o"); }': () - 72..73 'x': &str - "### + fn main() { + let x = env!("foo"); + } + "#, + expect![[r#" + !0..22 '"__RA_...TED__"': &str + 62..90 '{ ...o"); }': () + 72..73 'x': &str + "#]], ); } @@ -763,25 +763,25 @@ fn test() { #[test] fn macro_in_arm() { - assert_snapshot!( - infer(r#" -macro_rules! unit { - () => { () }; -} + check_infer( + r#" + macro_rules! unit { + () => { () }; + } -fn main() { - let x = match () { - unit!() => 92u32, - }; -} -"#), - @r###" - 51..110 '{ ... }; }': () - 61..62 'x': u32 - 65..107 'match ... }': u32 - 71..73 '()': () - 84..91 'unit!()': () - 95..100 '92u32': u32 - "### + fn main() { + let x = match () { + unit!() => 92u32, + }; + } + "#, + expect![[r#" + 51..110 '{ ... }; }': () + 61..62 'x': u32 + 65..107 'match ... }': u32 + 71..73 '()': () + 84..91 'unit!()': () + 95..100 '92u32': u32 + "#]], ); } diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 9c8f22314..fa68355aa 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -1,245 +1,245 @@ -use insta::assert_snapshot; +use expect::expect; -use super::{check_types, infer}; +use super::{check_infer, check_types}; #[test] fn infer_slice_method() { - assert_snapshot!( - infer(r#" -#[lang = "slice"] -impl [T] { - fn foo(&self) -> T { - loop {} - } -} - -#[lang = "slice_alloc"] -impl [T] {} - -fn test(x: &[u8]) { - <[_]>::foo(x); -} -"#), - @r###" - 44..48 'self': &[T] - 55..78 '{ ... }': T - 65..72 'loop {}': ! - 70..72 '{}': () - 130..131 'x': &[u8] - 140..162 '{ ...(x); }': () - 146..156 '<[_]>::foo': fn foo(&[u8]) -> u8 - 146..159 '<[_]>::foo(x)': u8 - 157..158 'x': &[u8] - "### + check_infer( + r#" + #[lang = "slice"] + impl [T] { + fn foo(&self) -> T { + loop {} + } + } + + #[lang = "slice_alloc"] + impl [T] {} + + fn test(x: &[u8]) { + <[_]>::foo(x); + } + "#, + expect![[r#" + 44..48 'self': &[T] + 55..78 '{ ... }': T + 65..72 'loop {}': ! + 70..72 '{}': () + 130..131 'x': &[u8] + 140..162 '{ ...(x); }': () + 146..156 '<[_]>::foo': fn foo(&[u8]) -> u8 + 146..159 '<[_]>::foo(x)': u8 + 157..158 'x': &[u8] + "#]], ); } #[test] fn infer_associated_method_struct() { - assert_snapshot!( - infer(r#" -struct A { x: u32 } - -impl A { - fn new() -> A { - A { x: 0 } - } -} -fn test() { - let a = A::new(); - a.x; -} -"#), - @r###" - 48..74 '{ ... }': A - 58..68 'A { x: 0 }': A - 65..66 '0': u32 - 87..121 '{ ...a.x; }': () - 97..98 'a': A - 101..107 'A::new': fn new() -> A - 101..109 'A::new()': A - 115..116 'a': A - 115..118 'a.x': u32 - "### + check_infer( + r#" + struct A { x: u32 } + + impl A { + fn new() -> A { + A { x: 0 } + } + } + fn test() { + let a = A::new(); + a.x; + } + "#, + expect![[r#" + 48..74 '{ ... }': A + 58..68 'A { x: 0 }': A + 65..66 '0': u32 + 87..121 '{ ...a.x; }': () + 97..98 'a': A + 101..107 'A::new': fn new() -> A + 101..109 'A::new()': A + 115..116 'a': A + 115..118 'a.x': u32 + "#]], ); } #[test] fn infer_associated_method_enum() { - assert_snapshot!( - infer(r#" -enum A { B, C } - -impl A { - pub fn b() -> A { - A::B - } - pub fn c() -> A { - A::C - } -} -fn test() { - let a = A::b(); - a; - let c = A::c(); - c; -} -"#), - @r###" - 46..66 '{ ... }': A - 56..60 'A::B': A - 87..107 '{ ... }': A - 97..101 'A::C': A - 120..177 '{ ... c; }': () - 130..131 'a': A - 134..138 'A::b': fn b() -> A - 134..140 'A::b()': A - 146..147 'a': A - 157..158 'c': A - 161..165 'A::c': fn c() -> A - 161..167 'A::c()': A - 173..174 'c': A - "### + check_infer( + r#" + enum A { B, C } + + impl A { + pub fn b() -> A { + A::B + } + pub fn c() -> A { + A::C + } + } + fn test() { + let a = A::b(); + a; + let c = A::c(); + c; + } + "#, + expect![[r#" + 46..66 '{ ... }': A + 56..60 'A::B': A + 87..107 '{ ... }': A + 97..101 'A::C': A + 120..177 '{ ... c; }': () + 130..131 'a': A + 134..138 'A::b': fn b() -> A + 134..140 'A::b()': A + 146..147 'a': A + 157..158 'c': A + 161..165 'A::c': fn c() -> A + 161..167 'A::c()': A + 173..174 'c': A + "#]], ); } #[test] fn infer_associated_method_with_modules() { - assert_snapshot!( - infer(r#" -mod a { - struct A; - impl A { pub fn thing() -> A { A {} }} -} - -mod b { - struct B; - impl B { pub fn thing() -> u32 { 99 }} - - mod c { - struct C; - impl C { pub fn thing() -> C { C {} }} - } -} -use b::c; - -fn test() { - let x = a::A::thing(); - let y = b::B::thing(); - let z = c::C::thing(); -} -"#), - @r###" - 55..63 '{ A {} }': A - 57..61 'A {}': A - 125..131 '{ 99 }': u32 - 127..129 '99': u32 - 201..209 '{ C {} }': C - 203..207 'C {}': C - 240..324 '{ ...g(); }': () - 250..251 'x': A - 254..265 'a::A::thing': fn thing() -> A - 254..267 'a::A::thing()': A - 277..278 'y': u32 - 281..292 'b::B::thing': fn thing() -> u32 - 281..294 'b::B::thing()': u32 - 304..305 'z': C - 308..319 'c::C::thing': fn thing() -> C - 308..321 'c::C::thing()': C - "### + check_infer( + r#" + mod a { + struct A; + impl A { pub fn thing() -> A { A {} }} + } + + mod b { + struct B; + impl B { pub fn thing() -> u32 { 99 }} + + mod c { + struct C; + impl C { pub fn thing() -> C { C {} }} + } + } + use b::c; + + fn test() { + let x = a::A::thing(); + let y = b::B::thing(); + let z = c::C::thing(); + } + "#, + expect![[r#" + 55..63 '{ A {} }': A + 57..61 'A {}': A + 125..131 '{ 99 }': u32 + 127..129 '99': u32 + 201..209 '{ C {} }': C + 203..207 'C {}': C + 240..324 '{ ...g(); }': () + 250..251 'x': A + 254..265 'a::A::thing': fn thing() -> A + 254..267 'a::A::thing()': A + 277..278 'y': u32 + 281..292 'b::B::thing': fn thing() -> u32 + 281..294 'b::B::thing()': u32 + 304..305 'z': C + 308..319 'c::C::thing': fn thing() -> C + 308..321 'c::C::thing()': C + "#]], ); } #[test] fn infer_associated_method_generics() { - assert_snapshot!( - infer(r#" -struct Gen { - val: T -} - -impl Gen { - pub fn make(val: T) -> Gen { - Gen { val } - } -} - -fn test() { - let a = Gen::make(0u32); -} -"#), - @r###" - 63..66 'val': T - 81..108 '{ ... }': Gen - 91..102 'Gen { val }': Gen - 97..100 'val': T - 122..154 '{ ...32); }': () - 132..133 'a': Gen - 136..145 'Gen::make': fn make(u32) -> Gen - 136..151 'Gen::make(0u32)': Gen - 146..150 '0u32': u32 - "### + check_infer( + r#" + struct Gen { + val: T + } + + impl Gen { + pub fn make(val: T) -> Gen { + Gen { val } + } + } + + fn test() { + let a = Gen::make(0u32); + } + "#, + expect![[r#" + 63..66 'val': T + 81..108 '{ ... }': Gen + 91..102 'Gen { val }': Gen + 97..100 'val': T + 122..154 '{ ...32); }': () + 132..133 'a': Gen + 136..145 'Gen::make': fn make(u32) -> Gen + 136..151 'Gen::make(0u32)': Gen + 146..150 '0u32': u32 + "#]], ); } #[test] fn infer_associated_method_generics_without_args() { - assert_snapshot!( - infer(r#" -struct Gen { - val: T -} - -impl Gen { - pub fn make() -> Gen { - loop { } - } -} - -fn test() { - let a = Gen::::make(); -} -"#), - @r###" - 75..99 '{ ... }': Gen - 85..93 'loop { }': ! - 90..93 '{ }': () - 113..148 '{ ...e(); }': () - 123..124 'a': Gen - 127..143 'Gen::<...::make': fn make() -> Gen - 127..145 'Gen::<...make()': Gen - "### + check_infer( + r#" + struct Gen { + val: T + } + + impl Gen { + pub fn make() -> Gen { + loop { } + } + } + + fn test() { + let a = Gen::::make(); + } + "#, + expect![[r#" + 75..99 '{ ... }': Gen + 85..93 'loop { }': ! + 90..93 '{ }': () + 113..148 '{ ...e(); }': () + 123..124 'a': Gen + 127..143 'Gen::<...::make': fn make() -> Gen + 127..145 'Gen::<...make()': Gen + "#]], ); } #[test] fn infer_associated_method_generics_2_type_params_without_args() { - assert_snapshot!( - infer(r#" -struct Gen { - val: T, - val2: U, -} - -impl Gen { - pub fn make() -> Gen { - loop { } - } -} - -fn test() { - let a = Gen::::make(); -} -"#), - @r###" - 101..125 '{ ... }': Gen - 111..119 'loop { }': ! - 116..119 '{ }': () - 139..179 '{ ...e(); }': () - 149..150 'a': Gen - 153..174 'Gen::<...::make': fn make() -> Gen - 153..176 'Gen::<...make()': Gen - "### + check_infer( + r#" + struct Gen { + val: T, + val2: U, + } + + impl Gen { + pub fn make() -> Gen { + loop { } + } + } + + fn test() { + let a = Gen::::make(); + } + "#, + expect![[r#" + 101..125 '{ ... }': Gen + 111..119 'loop { }': ! + 116..119 '{ }': () + 139..179 '{ ...e(); }': () + 149..150 'a': Gen + 153..174 'Gen::<...::make': fn make() -> Gen + 153..176 'Gen::<...make()': Gen + "#]], ); } @@ -267,416 +267,416 @@ mod foo { #[test] fn infer_trait_method_simple() { // the trait implementation is intentionally incomplete -- it shouldn't matter - assert_snapshot!( - infer(r#" -trait Trait1 { - fn method(&self) -> u32; -} -struct S1; -impl Trait1 for S1 {} -trait Trait2 { - fn method(&self) -> i128; -} -struct S2; -impl Trait2 for S2 {} -fn test() { - S1.method(); // -> u32 - S2.method(); // -> i128 -} -"#), - @r###" - 30..34 'self': &Self - 109..113 'self': &Self - 169..227 '{ ...i128 }': () - 175..177 'S1': S1 - 175..186 'S1.method()': u32 - 202..204 'S2': S2 - 202..213 'S2.method()': i128 - "### + check_infer( + r#" + trait Trait1 { + fn method(&self) -> u32; + } + struct S1; + impl Trait1 for S1 {} + trait Trait2 { + fn method(&self) -> i128; + } + struct S2; + impl Trait2 for S2 {} + fn test() { + S1.method(); // -> u32 + S2.method(); // -> i128 + } + "#, + expect![[r#" + 30..34 'self': &Self + 109..113 'self': &Self + 169..227 '{ ...i128 }': () + 175..177 'S1': S1 + 175..186 'S1.method()': u32 + 202..204 'S2': S2 + 202..213 'S2.method()': i128 + "#]], ); } #[test] fn infer_trait_method_scoped() { // the trait implementation is intentionally incomplete -- it shouldn't matter - assert_snapshot!( - infer(r#" -struct S; -mod foo { - pub trait Trait1 { - fn method(&self) -> u32; - } - impl Trait1 for super::S {} -} -mod bar { - pub trait Trait2 { - fn method(&self) -> i128; - } - impl Trait2 for super::S {} -} - -mod foo_test { - use super::S; - use super::foo::Trait1; - fn test() { - S.method(); // -> u32 - } -} - -mod bar_test { - use super::S; - use super::bar::Trait2; - fn test() { - S.method(); // -> i128 - } -} -"#), - @r###" - 62..66 'self': &Self - 168..172 'self': &Self - 299..336 '{ ... }': () - 309..310 'S': S - 309..319 'S.method()': u32 - 415..453 '{ ... }': () - 425..426 'S': S - 425..435 'S.method()': i128 - "### + check_infer( + r#" + struct S; + mod foo { + pub trait Trait1 { + fn method(&self) -> u32; + } + impl Trait1 for super::S {} + } + mod bar { + pub trait Trait2 { + fn method(&self) -> i128; + } + impl Trait2 for super::S {} + } + + mod foo_test { + use super::S; + use super::foo::Trait1; + fn test() { + S.method(); // -> u32 + } + } + + mod bar_test { + use super::S; + use super::bar::Trait2; + fn test() { + S.method(); // -> i128 + } + } + "#, + expect![[r#" + 62..66 'self': &Self + 168..172 'self': &Self + 299..336 '{ ... }': () + 309..310 'S': S + 309..319 'S.method()': u32 + 415..453 '{ ... }': () + 425..426 'S': S + 425..435 'S.method()': i128 + "#]], ); } #[test] fn infer_trait_method_generic_1() { // the trait implementation is intentionally incomplete -- it shouldn't matter - assert_snapshot!( - infer(r#" -trait Trait { - fn method(&self) -> T; -} -struct S; -impl Trait for S {} -fn test() { - S.method(); -} -"#), - @r###" - 32..36 'self': &Self - 91..110 '{ ...d(); }': () - 97..98 'S': S - 97..107 'S.method()': u32 - "### + check_infer( + r#" + trait Trait { + fn method(&self) -> T; + } + struct S; + impl Trait for S {} + fn test() { + S.method(); + } + "#, + expect![[r#" + 32..36 'self': &Self + 91..110 '{ ...d(); }': () + 97..98 'S': S + 97..107 'S.method()': u32 + "#]], ); } #[test] fn infer_trait_method_generic_more_params() { // the trait implementation is intentionally incomplete -- it shouldn't matter - assert_snapshot!( - infer(r#" -trait Trait { - fn method1(&self) -> (T1, T2, T3); - fn method2(&self) -> (T3, T2, T1); -} -struct S1; -impl Trait for S1 {} -struct S2; -impl Trait for S2 {} -fn test() { - S1.method1(); // u8, u16, u32 - S1.method2(); // u32, u16, u8 - S2.method1(); // i8, i16, {unknown} - S2.method2(); // {unknown}, i16, i8 -} -"#), - @r###" - 42..46 'self': &Self - 81..85 'self': &Self - 209..360 '{ ..., i8 }': () - 215..217 'S1': S1 - 215..227 'S1.method1()': (u8, u16, u32) - 249..251 'S1': S1 - 249..261 'S1.method2()': (u32, u16, u8) - 283..285 'S2': S2 - 283..295 'S2.method1()': (i8, i16, {unknown}) - 323..325 'S2': S2 - 323..335 'S2.method2()': ({unknown}, i16, i8) - "### + check_infer( + r#" + trait Trait { + fn method1(&self) -> (T1, T2, T3); + fn method2(&self) -> (T3, T2, T1); + } + struct S1; + impl Trait for S1 {} + struct S2; + impl Trait for S2 {} + fn test() { + S1.method1(); // u8, u16, u32 + S1.method2(); // u32, u16, u8 + S2.method1(); // i8, i16, {unknown} + S2.method2(); // {unknown}, i16, i8 + } + "#, + expect![[r#" + 42..46 'self': &Self + 81..85 'self': &Self + 209..360 '{ ..., i8 }': () + 215..217 'S1': S1 + 215..227 'S1.method1()': (u8, u16, u32) + 249..251 'S1': S1 + 249..261 'S1.method2()': (u32, u16, u8) + 283..285 'S2': S2 + 283..295 'S2.method1()': (i8, i16, {unknown}) + 323..325 'S2': S2 + 323..335 'S2.method2()': ({unknown}, i16, i8) + "#]], ); } #[test] fn infer_trait_method_generic_2() { // the trait implementation is intentionally incomplete -- it shouldn't matter - assert_snapshot!( - infer(r#" -trait Trait { - fn method(&self) -> T; -} -struct S(T); -impl Trait for S {} -fn test() { - S(1u32).method(); -} -"#), - @r###" - 32..36 'self': &Self - 101..126 '{ ...d(); }': () - 107..108 'S': S(u32) -> S - 107..114 'S(1u32)': S - 107..123 'S(1u32...thod()': u32 - 109..113 '1u32': u32 - "### + check_infer( + r#" + trait Trait { + fn method(&self) -> T; + } + struct S(T); + impl Trait for S {} + fn test() { + S(1u32).method(); + } + "#, + expect![[r#" + 32..36 'self': &Self + 101..126 '{ ...d(); }': () + 107..108 'S': S(u32) -> S + 107..114 'S(1u32)': S + 107..123 'S(1u32...thod()': u32 + 109..113 '1u32': u32 + "#]], ); } #[test] fn infer_trait_assoc_method() { - assert_snapshot!( - infer(r#" -trait Default { - fn default() -> Self; -} -struct S; -impl Default for S {} -fn test() { - let s1: S = Default::default(); - let s2 = S::default(); - let s3 = ::default(); -} -"#), - @r###" - 86..192 '{ ...t(); }': () - 96..98 's1': S - 104..120 'Defaul...efault': fn default() -> S - 104..122 'Defaul...ault()': S - 132..134 's2': S - 137..147 'S::default': fn default() -> S - 137..149 'S::default()': S - 159..161 's3': S - 164..187 '() -> S - 164..189 ' Self; + } + struct S; + impl Default for S {} + fn test() { + let s1: S = Default::default(); + let s2 = S::default(); + let s3 = ::default(); + } + "#, + expect![[r#" + 86..192 '{ ...t(); }': () + 96..98 's1': S + 104..120 'Defaul...efault': fn default() -> S + 104..122 'Defaul...ault()': S + 132..134 's2': S + 137..147 'S::default': fn default() -> S + 137..149 'S::default()': S + 159..161 's3': S + 164..187 '() -> S + 164..189 ' { - fn make() -> T; -} -struct S; -impl Trait for S {} -struct G; -impl Trait for G {} -fn test() { - let a = S::make(); - let b = G::::make(); - let c: f64 = G::make(); -} -"#), - @r###" - 126..210 '{ ...e(); }': () - 136..137 'a': u32 - 140..147 'S::make': fn make() -> u32 - 140..149 'S::make()': u32 - 159..160 'b': u64 - 163..177 'G::::make': fn make, u64>() -> u64 - 163..179 'G::, f64>() -> f64 - 198..207 'G::make()': f64 - "### + check_infer( + r#" + trait Trait { + fn make() -> T; + } + struct S; + impl Trait for S {} + struct G; + impl Trait for G {} + fn test() { + let a = S::make(); + let b = G::::make(); + let c: f64 = G::make(); + } + "#, + expect![[r#" + 126..210 '{ ...e(); }': () + 136..137 'a': u32 + 140..147 'S::make': fn make() -> u32 + 140..149 'S::make()': u32 + 159..160 'b': u64 + 163..177 'G::::make': fn make, u64>() -> u64 + 163..179 'G::, f64>() -> f64 + 198..207 'G::make()': f64 + "#]], ); } #[test] fn infer_trait_assoc_method_generics_2() { - assert_snapshot!( - infer(r#" -trait Trait { - fn make() -> (T, U); -} -struct S; -impl Trait for S {} -struct G; -impl Trait for G {} -fn test() { - let a = S::make::(); - let b: (_, i64) = S::make(); - let c = G::::make::(); - let d: (u32, _) = G::make::(); - let e: (u32, i64) = G::make(); -} -"#), - @r###" - 134..312 '{ ...e(); }': () - 144..145 'a': (u32, i64) - 148..162 'S::make::': fn make() -> (u32, i64) - 148..164 'S::mak...i64>()': (u32, i64) - 174..175 'b': (u32, i64) - 188..195 'S::make': fn make() -> (u32, i64) - 188..197 'S::make()': (u32, i64) - 207..208 'c': (u32, i64) - 211..232 'G::': fn make, u32, i64>() -> (u32, i64) - 211..234 'G::()': (u32, i64) - 244..245 'd': (u32, i64) - 258..272 'G::make::': fn make, u32, i64>() -> (u32, i64) - 258..274 'G::mak...i64>()': (u32, i64) - 284..285 'e': (u32, i64) - 300..307 'G::make': fn make, u32, i64>() -> (u32, i64) - 300..309 'G::make()': (u32, i64) - "### + check_infer( + r#" + trait Trait { + fn make() -> (T, U); + } + struct S; + impl Trait for S {} + struct G; + impl Trait for G {} + fn test() { + let a = S::make::(); + let b: (_, i64) = S::make(); + let c = G::::make::(); + let d: (u32, _) = G::make::(); + let e: (u32, i64) = G::make(); + } + "#, + expect![[r#" + 134..312 '{ ...e(); }': () + 144..145 'a': (u32, i64) + 148..162 'S::make::': fn make() -> (u32, i64) + 148..164 'S::mak...i64>()': (u32, i64) + 174..175 'b': (u32, i64) + 188..195 'S::make': fn make() -> (u32, i64) + 188..197 'S::make()': (u32, i64) + 207..208 'c': (u32, i64) + 211..232 'G::': fn make, u32, i64>() -> (u32, i64) + 211..234 'G::()': (u32, i64) + 244..245 'd': (u32, i64) + 258..272 'G::make::': fn make, u32, i64>() -> (u32, i64) + 258..274 'G::mak...i64>()': (u32, i64) + 284..285 'e': (u32, i64) + 300..307 'G::make': fn make, u32, i64>() -> (u32, i64) + 300..309 'G::make()': (u32, i64) + "#]], ); } #[test] fn infer_trait_assoc_method_generics_3() { - assert_snapshot!( - infer(r#" -trait Trait { - fn make() -> (Self, T); -} -struct S; -impl Trait for S {} -fn test() { - let a = S::make(); -} -"#), - @r###" - 100..126 '{ ...e(); }': () - 110..111 'a': (S, i64) - 114..121 'S::make': fn make, i64>() -> (S, i64) - 114..123 'S::make()': (S, i64) - "### + check_infer( + r#" + trait Trait { + fn make() -> (Self, T); + } + struct S; + impl Trait for S {} + fn test() { + let a = S::make(); + } + "#, + expect![[r#" + 100..126 '{ ...e(); }': () + 110..111 'a': (S, i64) + 114..121 'S::make': fn make, i64>() -> (S, i64) + 114..123 'S::make()': (S, i64) + "#]], ); } #[test] fn infer_trait_assoc_method_generics_4() { - assert_snapshot!( - infer(r#" -trait Trait { - fn make() -> (Self, T); -} -struct S; -impl Trait for S {} -impl Trait for S {} -fn test() { - let a: (S, _) = S::make(); - let b: (_, i32) = S::make(); -} -"#), - @r###" - 130..202 '{ ...e(); }': () - 140..141 'a': (S, i64) - 157..164 'S::make': fn make, i64>() -> (S, i64) - 157..166 'S::make()': (S, i64) - 176..177 'b': (S, i32) - 190..197 'S::make': fn make, i32>() -> (S, i32) - 190..199 'S::make()': (S, i32) - "### + check_infer( + r#" + trait Trait { + fn make() -> (Self, T); + } + struct S; + impl Trait for S {} + impl Trait for S {} + fn test() { + let a: (S, _) = S::make(); + let b: (_, i32) = S::make(); + } + "#, + expect![[r#" + 130..202 '{ ...e(); }': () + 140..141 'a': (S, i64) + 157..164 'S::make': fn make, i64>() -> (S, i64) + 157..166 'S::make()': (S, i64) + 176..177 'b': (S, i32) + 190..197 'S::make': fn make, i32>() -> (S, i32) + 190..199 'S::make()': (S, i32) + "#]], ); } #[test] fn infer_trait_assoc_method_generics_5() { - assert_snapshot!( - infer(r#" -trait Trait { - fn make() -> (Self, T, U); -} -struct S; -impl Trait for S {} -fn test() { - let a = >::make::(); - let b: (S, _, _) = Trait::::make::(); -} -"#), - @r###" - 106..210 '{ ...>(); }': () - 116..117 'a': (S, i64, u8) - 120..149 '': fn make, i64, u8>() -> (S, i64, u8) - 120..151 '()': (S, i64, u8) - 161..162 'b': (S, i64, u8) - 181..205 'Trait:...::': fn make, i64, u8>() -> (S, i64, u8) - 181..207 'Trait:...()': (S, i64, u8) - "### + check_infer( + r#" + trait Trait { + fn make() -> (Self, T, U); + } + struct S; + impl Trait for S {} + fn test() { + let a = >::make::(); + let b: (S, _, _) = Trait::::make::(); + } + "#, + expect![[r#" + 106..210 '{ ...>(); }': () + 116..117 'a': (S, i64, u8) + 120..149 '': fn make, i64, u8>() -> (S, i64, u8) + 120..151 '()': (S, i64, u8) + 161..162 'b': (S, i64, u8) + 181..205 'Trait:...::': fn make, i64, u8>() -> (S, i64, u8) + 181..207 'Trait:...()': (S, i64, u8) + "#]], ); } #[test] fn infer_call_trait_method_on_generic_param_1() { - assert_snapshot!( - infer(r#" -trait Trait { - fn method(&self) -> u32; -} -fn test(t: T) { - t.method(); -} -"#), - @r###" - 29..33 'self': &Self - 63..64 't': T - 69..88 '{ ...d(); }': () - 75..76 't': T - 75..85 't.method()': u32 - "### + check_infer( + r#" + trait Trait { + fn method(&self) -> u32; + } + fn test(t: T) { + t.method(); + } + "#, + expect![[r#" + 29..33 'self': &Self + 63..64 't': T + 69..88 '{ ...d(); }': () + 75..76 't': T + 75..85 't.method()': u32 + "#]], ); } #[test] fn infer_call_trait_method_on_generic_param_2() { - assert_snapshot!( - infer(r#" -trait Trait { - fn method(&self) -> T; -} -fn test>(t: T) { - t.method(); -} -"#), - @r###" - 32..36 'self': &Self - 70..71 't': T - 76..95 '{ ...d(); }': () - 82..83 't': T - 82..92 't.method()': U - "### + check_infer( + r#" + trait Trait { + fn method(&self) -> T; + } + fn test>(t: T) { + t.method(); + } + "#, + expect![[r#" + 32..36 'self': &Self + 70..71 't': T + 76..95 '{ ...d(); }': () + 82..83 't': T + 82..92 't.method()': U + "#]], ); } #[test] fn infer_with_multiple_trait_impls() { - assert_snapshot!( - infer(r#" -trait Into { - fn into(self) -> T; -} -struct S; -impl Into for S {} -impl Into for S {} -fn test() { - let x: u32 = S.into(); - let y: u64 = S.into(); - let z = Into::::into(S); -} -"#), - @r###" - 28..32 'self': Self - 110..201 '{ ...(S); }': () - 120..121 'x': u32 - 129..130 'S': S - 129..137 'S.into()': u32 - 147..148 'y': u64 - 156..157 'S': S - 156..164 'S.into()': u64 - 174..175 'z': u64 - 178..195 'Into::...::into': fn into(S) -> u64 - 178..198 'Into::...nto(S)': u64 - 196..197 'S': S - "### + check_infer( + r#" + trait Into { + fn into(self) -> T; + } + struct S; + impl Into for S {} + impl Into for S {} + fn test() { + let x: u32 = S.into(); + let y: u64 = S.into(); + let z = Into::::into(S); + } + "#, + expect![[r#" + 28..32 'self': Self + 110..201 '{ ...(S); }': () + 120..121 'x': u32 + 129..130 'S': S + 129..137 'S.into()': u32 + 147..148 'y': u64 + 156..157 'S': S + 156..164 'S.into()': u64 + 174..175 'z': u64 + 178..195 'Into::...::into': fn into(S) -> u64 + 178..198 'Into::...nto(S)': u64 + 196..197 'S': S + "#]], ); } @@ -1023,31 +1023,31 @@ fn test() { (S {}).method(); } #[test] fn dyn_trait_super_trait_not_in_scope() { - assert_snapshot!( - infer(r#" -mod m { - pub trait SuperTrait { - fn foo(&self) -> u32 { 0 } - } -} -trait Trait: m::SuperTrait {} - -struct S; -impl m::SuperTrait for S {} -impl Trait for S {} - -fn test(d: &dyn Trait) { - d.foo(); -} -"#), - @r###" - 51..55 'self': &Self - 64..69 '{ 0 }': u32 - 66..67 '0': u32 - 176..177 'd': &dyn Trait - 191..207 '{ ...o(); }': () - 197..198 'd': &dyn Trait - 197..204 'd.foo()': u32 - "### + check_infer( + r#" + mod m { + pub trait SuperTrait { + fn foo(&self) -> u32 { 0 } + } + } + trait Trait: m::SuperTrait {} + + struct S; + impl m::SuperTrait for S {} + impl Trait for S {} + + fn test(d: &dyn Trait) { + d.foo(); + } + "#, + expect![[r#" + 51..55 'self': &Self + 64..69 '{ 0 }': u32 + 66..67 '0': u32 + 176..177 'd': &dyn Trait + 191..207 '{ ...o(); }': () + 197..198 'd': &dyn Trait + 197..204 'd.foo()': u32 + "#]], ); } diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index f937426bd..39fabf7eb 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs @@ -1,561 +1,561 @@ -use insta::assert_snapshot; +use expect::expect; use test_utils::mark; -use super::{infer, infer_with_mismatches}; +use super::{check_infer, check_infer_with_mismatches}; #[test] fn infer_pattern() { - assert_snapshot!( - infer(r#" -fn test(x: &i32) { - let y = x; - let &z = x; - let a = z; - let (c, d) = (1, "hello"); - - for (e, f) in some_iter { - let g = e; - } - - if let [val] = opt { - let h = val; - } - - let lambda = |a: u64, b, c: i32| { a + b; c }; - - let ref ref_to_x = x; - let mut mut_x = x; - let ref mut mut_ref_to_x = x; - let k = mut_ref_to_x; -} -"#), - @r###" - 8..9 'x': &i32 - 17..368 '{ ...o_x; }': () - 27..28 'y': &i32 - 31..32 'x': &i32 - 42..44 '&z': &i32 - 43..44 'z': i32 - 47..48 'x': &i32 - 58..59 'a': i32 - 62..63 'z': i32 - 73..79 '(c, d)': (i32, &str) - 74..75 'c': i32 - 77..78 'd': &str - 82..94 '(1, "hello")': (i32, &str) - 83..84 '1': i32 - 86..93 '"hello"': &str - 101..151 'for (e... }': () - 105..111 '(e, f)': ({unknown}, {unknown}) - 106..107 'e': {unknown} - 109..110 'f': {unknown} - 115..124 'some_iter': {unknown} - 125..151 '{ ... }': () - 139..140 'g': {unknown} - 143..144 'e': {unknown} - 157..204 'if let... }': () - 164..169 '[val]': [{unknown}] - 165..168 'val': {unknown} - 172..175 'opt': [{unknown}] - 176..204 '{ ... }': () - 190..191 'h': {unknown} - 194..197 'val': {unknown} - 214..220 'lambda': |u64, u64, i32| -> i32 - 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 - 224..225 'a': u64 - 232..233 'b': u64 - 235..236 'c': i32 - 243..255 '{ a + b; c }': i32 - 245..246 'a': u64 - 245..250 'a + b': u64 - 249..250 'b': u64 - 252..253 'c': i32 - 266..278 'ref ref_to_x': &&i32 - 281..282 'x': &i32 - 292..301 'mut mut_x': &i32 - 304..305 'x': &i32 - 315..335 'ref mu...f_to_x': &mut &i32 - 338..339 'x': &i32 - 349..350 'k': &mut &i32 - 353..365 'mut_ref_to_x': &mut &i32 - "### + check_infer( + r#" + fn test(x: &i32) { + let y = x; + let &z = x; + let a = z; + let (c, d) = (1, "hello"); + + for (e, f) in some_iter { + let g = e; + } + + if let [val] = opt { + let h = val; + } + + let lambda = |a: u64, b, c: i32| { a + b; c }; + + let ref ref_to_x = x; + let mut mut_x = x; + let ref mut mut_ref_to_x = x; + let k = mut_ref_to_x; + } + "#, + expect![[r#" + 8..9 'x': &i32 + 17..368 '{ ...o_x; }': () + 27..28 'y': &i32 + 31..32 'x': &i32 + 42..44 '&z': &i32 + 43..44 'z': i32 + 47..48 'x': &i32 + 58..59 'a': i32 + 62..63 'z': i32 + 73..79 '(c, d)': (i32, &str) + 74..75 'c': i32 + 77..78 'd': &str + 82..94 '(1, "hello")': (i32, &str) + 83..84 '1': i32 + 86..93 '"hello"': &str + 101..151 'for (e... }': () + 105..111 '(e, f)': ({unknown}, {unknown}) + 106..107 'e': {unknown} + 109..110 'f': {unknown} + 115..124 'some_iter': {unknown} + 125..151 '{ ... }': () + 139..140 'g': {unknown} + 143..144 'e': {unknown} + 157..204 'if let... }': () + 164..169 '[val]': [{unknown}] + 165..168 'val': {unknown} + 172..175 'opt': [{unknown}] + 176..204 '{ ... }': () + 190..191 'h': {unknown} + 194..197 'val': {unknown} + 214..220 'lambda': |u64, u64, i32| -> i32 + 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 + 224..225 'a': u64 + 232..233 'b': u64 + 235..236 'c': i32 + 243..255 '{ a + b; c }': i32 + 245..246 'a': u64 + 245..250 'a + b': u64 + 249..250 'b': u64 + 252..253 'c': i32 + 266..278 'ref ref_to_x': &&i32 + 281..282 'x': &i32 + 292..301 'mut mut_x': &i32 + 304..305 'x': &i32 + 315..335 'ref mu...f_to_x': &mut &i32 + 338..339 'x': &i32 + 349..350 'k': &mut &i32 + 353..365 'mut_ref_to_x': &mut &i32 + "#]], ); } #[test] fn infer_literal_pattern() { - assert_snapshot!( - infer_with_mismatches(r#" -fn any() -> T { loop {} } -fn test(x: &i32) { - if let "foo" = any() {} - if let 1 = any() {} - if let 1u32 = any() {} - if let 1f32 = any() {} - if let 1.0 = any() {} - if let true = any() {} -} -"#, true), - @r###" - 17..28 '{ loop {} }': T - 19..26 'loop {}': ! - 24..26 '{}': () - 37..38 'x': &i32 - 46..208 '{ ...) {} }': () - 52..75 'if let...y() {}': () - 59..64 '"foo"': &str - 59..64 '"foo"': &str - 67..70 'any': fn any<&str>() -> &str - 67..72 'any()': &str - 73..75 '{}': () - 80..99 'if let...y() {}': () - 87..88 '1': i32 - 87..88 '1': i32 - 91..94 'any': fn any() -> i32 - 91..96 'any()': i32 - 97..99 '{}': () - 104..126 'if let...y() {}': () - 111..115 '1u32': u32 - 111..115 '1u32': u32 - 118..121 'any': fn any() -> u32 - 118..123 'any()': u32 - 124..126 '{}': () - 131..153 'if let...y() {}': () - 138..142 '1f32': f32 - 138..142 '1f32': f32 - 145..148 'any': fn any() -> f32 - 145..150 'any()': f32 - 151..153 '{}': () - 158..179 'if let...y() {}': () - 165..168 '1.0': f64 - 165..168 '1.0': f64 - 171..174 'any': fn any() -> f64 - 171..176 'any()': f64 - 177..179 '{}': () - 184..206 'if let...y() {}': () - 191..195 'true': bool - 191..195 'true': bool - 198..201 'any': fn any() -> bool - 198..203 'any()': bool - 204..206 '{}': () - "### + check_infer_with_mismatches( + r#" + fn any() -> T { loop {} } + fn test(x: &i32) { + if let "foo" = any() {} + if let 1 = any() {} + if let 1u32 = any() {} + if let 1f32 = any() {} + if let 1.0 = any() {} + if let true = any() {} + } + "#, + expect![[r#" + 17..28 '{ loop {} }': T + 19..26 'loop {}': ! + 24..26 '{}': () + 37..38 'x': &i32 + 46..208 '{ ...) {} }': () + 52..75 'if let...y() {}': () + 59..64 '"foo"': &str + 59..64 '"foo"': &str + 67..70 'any': fn any<&str>() -> &str + 67..72 'any()': &str + 73..75 '{}': () + 80..99 'if let...y() {}': () + 87..88 '1': i32 + 87..88 '1': i32 + 91..94 'any': fn any() -> i32 + 91..96 'any()': i32 + 97..99 '{}': () + 104..126 'if let...y() {}': () + 111..115 '1u32': u32 + 111..115 '1u32': u32 + 118..121 'any': fn any() -> u32 + 118..123 'any()': u32 + 124..126 '{}': () + 131..153 'if let...y() {}': () + 138..142 '1f32': f32 + 138..142 '1f32': f32 + 145..148 'any': fn any() -> f32 + 145..150 'any()': f32 + 151..153 '{}': () + 158..179 'if let...y() {}': () + 165..168 '1.0': f64 + 165..168 '1.0': f64 + 171..174 'any': fn any() -> f64 + 171..176 'any()': f64 + 177..179 '{}': () + 184..206 'if let...y() {}': () + 191..195 'true': bool + 191..195 'true': bool + 198..201 'any': fn any() -> bool + 198..203 'any()': bool + 204..206 '{}': () + "#]], ); } #[test] fn infer_range_pattern() { - assert_snapshot!( - infer_with_mismatches(r#" -fn test(x: &i32) { - if let 1..76 = 2u32 {} - if let 1..=76 = 2u32 {} -} -"#, true), - @r###" - 8..9 'x': &i32 - 17..75 '{ ...2 {} }': () - 23..45 'if let...u32 {}': () - 30..35 '1..76': u32 - 38..42 '2u32': u32 - 43..45 '{}': () - 50..73 'if let...u32 {}': () - 57..63 '1..=76': u32 - 66..70 '2u32': u32 - 71..73 '{}': () - "### + check_infer_with_mismatches( + r#" + fn test(x: &i32) { + if let 1..76 = 2u32 {} + if let 1..=76 = 2u32 {} + } + "#, + expect![[r#" + 8..9 'x': &i32 + 17..75 '{ ...2 {} }': () + 23..45 'if let...u32 {}': () + 30..35 '1..76': u32 + 38..42 '2u32': u32 + 43..45 '{}': () + 50..73 'if let...u32 {}': () + 57..63 '1..=76': u32 + 66..70 '2u32': u32 + 71..73 '{}': () + "#]], ); } #[test] fn infer_pattern_match_ergonomics() { - assert_snapshot!( - infer(r#" -struct A(T); + check_infer( + r#" + struct A(T); -fn test() { - let A(n) = &A(1); - let A(n) = &mut A(1); -} -"#), - @r###" - 27..78 '{ ...(1); }': () - 37..41 'A(n)': A - 39..40 'n': &i32 - 44..49 '&A(1)': &A - 45..46 'A': A(i32) -> A - 45..49 'A(1)': A - 47..48 '1': i32 - 59..63 'A(n)': A - 61..62 'n': &mut i32 - 66..75 '&mut A(1)': &mut A - 71..72 'A': A(i32) -> A - 71..75 'A(1)': A - 73..74 '1': i32 - "### + fn test() { + let A(n) = &A(1); + let A(n) = &mut A(1); + } + "#, + expect![[r#" + 27..78 '{ ...(1); }': () + 37..41 'A(n)': A + 39..40 'n': &i32 + 44..49 '&A(1)': &A + 45..46 'A': A(i32) -> A + 45..49 'A(1)': A + 47..48 '1': i32 + 59..63 'A(n)': A + 61..62 'n': &mut i32 + 66..75 '&mut A(1)': &mut A + 71..72 'A': A(i32) -> A + 71..75 'A(1)': A + 73..74 '1': i32 + "#]], ); } #[test] fn infer_pattern_match_ergonomics_ref() { mark::check!(match_ergonomics_ref); - assert_snapshot!( - infer(r#" -fn test() { - let v = &(1, &2); - let (_, &w) = v; -} -"#), - @r###" - 10..56 '{ ...= v; }': () - 20..21 'v': &(i32, &i32) - 24..32 '&(1, &2)': &(i32, &i32) - 25..32 '(1, &2)': (i32, &i32) - 26..27 '1': i32 - 29..31 '&2': &i32 - 30..31 '2': i32 - 42..49 '(_, &w)': (i32, &i32) - 43..44 '_': i32 - 46..48 '&w': &i32 - 47..48 'w': i32 - 52..53 'v': &(i32, &i32) - "### + check_infer( + r#" + fn test() { + let v = &(1, &2); + let (_, &w) = v; + } + "#, + expect![[r#" + 10..56 '{ ...= v; }': () + 20..21 'v': &(i32, &i32) + 24..32 '&(1, &2)': &(i32, &i32) + 25..32 '(1, &2)': (i32, &i32) + 26..27 '1': i32 + 29..31 '&2': &i32 + 30..31 '2': i32 + 42..49 '(_, &w)': (i32, &i32) + 43..44 '_': i32 + 46..48 '&w': &i32 + 47..48 'w': i32 + 52..53 'v': &(i32, &i32) + "#]], ); } #[test] fn infer_pattern_match_slice() { - assert_snapshot!( - infer(r#" -fn test() { - let slice: &[f64] = &[0.0]; - match slice { - &[] => {}, - &[a] => { - a; - }, - &[b, c] => { - b; - c; + check_infer( + r#" + fn test() { + let slice: &[f64] = &[0.0]; + match slice { + &[] => {}, + &[a] => { + a; + }, + &[b, c] => { + b; + c; + } + _ => {} + } } - _ => {} - } -} -"#), - @r###" - 10..209 '{ ... } }': () - 20..25 'slice': &[f64] - 36..42 '&[0.0]': &[f64; _] - 37..42 '[0.0]': [f64; _] - 38..41 '0.0': f64 - 48..207 'match ... }': () - 54..59 'slice': &[f64] - 70..73 '&[]': &[f64] - 71..73 '[]': [f64] - 77..79 '{}': () - 89..93 '&[a]': &[f64] - 90..93 '[a]': [f64] - 91..92 'a': f64 - 97..123 '{ ... }': () - 111..112 'a': f64 - 133..140 '&[b, c]': &[f64] - 134..140 '[b, c]': [f64] - 135..136 'b': f64 - 138..139 'c': f64 - 144..185 '{ ... }': () - 158..159 'b': f64 - 173..174 'c': f64 - 194..195 '_': &[f64] - 199..201 '{}': () - "### + "#, + expect![[r#" + 10..209 '{ ... } }': () + 20..25 'slice': &[f64] + 36..42 '&[0.0]': &[f64; _] + 37..42 '[0.0]': [f64; _] + 38..41 '0.0': f64 + 48..207 'match ... }': () + 54..59 'slice': &[f64] + 70..73 '&[]': &[f64] + 71..73 '[]': [f64] + 77..79 '{}': () + 89..93 '&[a]': &[f64] + 90..93 '[a]': [f64] + 91..92 'a': f64 + 97..123 '{ ... }': () + 111..112 'a': f64 + 133..140 '&[b, c]': &[f64] + 134..140 '[b, c]': [f64] + 135..136 'b': f64 + 138..139 'c': f64 + 144..185 '{ ... }': () + 158..159 'b': f64 + 173..174 'c': f64 + 194..195 '_': &[f64] + 199..201 '{}': () + "#]], ); } #[test] fn infer_pattern_match_string_literal() { - assert_snapshot!( - infer_with_mismatches(r#" -fn test() { - let s: &str = "hello"; - match s { - "hello" => {} - _ => {} - } -} -"#, true), - @r###" - 10..98 '{ ... } }': () - 20..21 's': &str - 30..37 '"hello"': &str - 43..96 'match ... }': () - 49..50 's': &str - 61..68 '"hello"': &str - 61..68 '"hello"': &str - 72..74 '{}': () - 83..84 '_': &str - 88..90 '{}': () - "### + check_infer_with_mismatches( + r#" + fn test() { + let s: &str = "hello"; + match s { + "hello" => {} + _ => {} + } + } + "#, + expect![[r#" + 10..98 '{ ... } }': () + 20..21 's': &str + 30..37 '"hello"': &str + 43..96 'match ... }': () + 49..50 's': &str + 61..68 '"hello"': &str + 61..68 '"hello"': &str + 72..74 '{}': () + 83..84 '_': &str + 88..90 '{}': () + "#]], ); } #[test] fn infer_pattern_match_or() { - assert_snapshot!( - infer_with_mismatches(r#" -fn test() { - let s: &str = "hello"; - match s { - "hello" | "world" => {} - _ => {} - } -} -"#, true), - @r###" - 10..108 '{ ... } }': () - 20..21 's': &str - 30..37 '"hello"': &str - 43..106 'match ... }': () - 49..50 's': &str - 61..68 '"hello"': &str - 61..68 '"hello"': &str - 61..78 '"hello...world"': &str - 71..78 '"world"': &str - 71..78 '"world"': &str - 82..84 '{}': () - 93..94 '_': &str - 98..100 '{}': () - "### + check_infer_with_mismatches( + r#" + fn test() { + let s: &str = "hello"; + match s { + "hello" | "world" => {} + _ => {} + } + } + "#, + expect![[r#" + 10..108 '{ ... } }': () + 20..21 's': &str + 30..37 '"hello"': &str + 43..106 'match ... }': () + 49..50 's': &str + 61..68 '"hello"': &str + 61..68 '"hello"': &str + 61..78 '"hello...world"': &str + 71..78 '"world"': &str + 71..78 '"world"': &str + 82..84 '{}': () + 93..94 '_': &str + 98..100 '{}': () + "#]], ); } #[test] fn infer_pattern_match_arr() { - assert_snapshot!( - infer(r#" -fn test() { - let arr: [f64; 2] = [0.0, 1.0]; - match arr { - [1.0, a] => { - a; - }, - [b, c] => { - b; - c; + check_infer( + r#" + fn test() { + let arr: [f64; 2] = [0.0, 1.0]; + match arr { + [1.0, a] => { + a; + }, + [b, c] => { + b; + c; + } + } } - } -} -"#), - @r###" - 10..179 '{ ... } }': () - 20..23 'arr': [f64; _] - 36..46 '[0.0, 1.0]': [f64; _] - 37..40 '0.0': f64 - 42..45 '1.0': f64 - 52..177 'match ... }': () - 58..61 'arr': [f64; _] - 72..80 '[1.0, a]': [f64; _] - 73..76 '1.0': f64 - 73..76 '1.0': f64 - 78..79 'a': f64 - 84..110 '{ ... }': () - 98..99 'a': f64 - 120..126 '[b, c]': [f64; _] - 121..122 'b': f64 - 124..125 'c': f64 - 130..171 '{ ... }': () - 144..145 'b': f64 - 159..160 'c': f64 - "### + "#, + expect![[r#" + 10..179 '{ ... } }': () + 20..23 'arr': [f64; _] + 36..46 '[0.0, 1.0]': [f64; _] + 37..40 '0.0': f64 + 42..45 '1.0': f64 + 52..177 'match ... }': () + 58..61 'arr': [f64; _] + 72..80 '[1.0, a]': [f64; _] + 73..76 '1.0': f64 + 73..76 '1.0': f64 + 78..79 'a': f64 + 84..110 '{ ... }': () + 98..99 'a': f64 + 120..126 '[b, c]': [f64; _] + 121..122 'b': f64 + 124..125 'c': f64 + 130..171 '{ ... }': () + 144..145 'b': f64 + 159..160 'c': f64 + "#]], ); } #[test] fn infer_adt_pattern() { - assert_snapshot!( - infer(r#" -enum E { - A { x: usize }, - B -} + check_infer( + r#" + enum E { + A { x: usize }, + B + } -struct S(u32, E); + struct S(u32, E); -fn test() { - let e = E::A { x: 3 }; + fn test() { + let e = E::A { x: 3 }; - let S(y, z) = foo; - let E::A { x: new_var } = e; + let S(y, z) = foo; + let E::A { x: new_var } = e; - match e { - E::A { x } => x, - E::B if foo => 1, - E::B => 10, - }; + match e { + E::A { x } => x, + E::B if foo => 1, + E::B => 10, + }; - let ref d @ E::A { .. } = e; - d; -} -"#), - @r###" - 67..288 '{ ... d; }': () - 77..78 'e': E - 81..94 'E::A { x: 3 }': E - 91..92 '3': usize - 105..112 'S(y, z)': S - 107..108 'y': u32 - 110..111 'z': E - 115..118 'foo': S - 128..147 'E::A {..._var }': E - 138..145 'new_var': usize - 150..151 'e': E - 158..244 'match ... }': usize - 164..165 'e': E - 176..186 'E::A { x }': E - 183..184 'x': usize - 190..191 'x': usize - 201..205 'E::B': E - 209..212 'foo': bool - 216..217 '1': usize - 227..231 'E::B': E - 235..237 '10': usize - 255..274 'ref d ...{ .. }': &E - 263..274 'E::A { .. }': E - 277..278 'e': E - 284..285 'd': &E - "### + let ref d @ E::A { .. } = e; + d; + } + "#, + expect![[r#" + 67..288 '{ ... d; }': () + 77..78 'e': E + 81..94 'E::A { x: 3 }': E + 91..92 '3': usize + 105..112 'S(y, z)': S + 107..108 'y': u32 + 110..111 'z': E + 115..118 'foo': S + 128..147 'E::A {..._var }': E + 138..145 'new_var': usize + 150..151 'e': E + 158..244 'match ... }': usize + 164..165 'e': E + 176..186 'E::A { x }': E + 183..184 'x': usize + 190..191 'x': usize + 201..205 'E::B': E + 209..212 'foo': bool + 216..217 '1': usize + 227..231 'E::B': E + 235..237 '10': usize + 255..274 'ref d ...{ .. }': &E + 263..274 'E::A { .. }': E + 277..278 'e': E + 284..285 'd': &E + "#]], ); } #[test] fn enum_variant_through_self_in_pattern() { - assert_snapshot!( - infer(r#" -enum E { - A { x: usize }, - B(usize), - C -} + check_infer( + r#" + enum E { + A { x: usize }, + B(usize), + C + } -impl E { - fn test() { - match (loop {}) { - Self::A { x } => { x; }, - Self::B(x) => { x; }, - Self::C => {}, - }; - } -} -"#), - @r###" - 75..217 '{ ... }': () - 85..210 'match ... }': () - 92..99 'loop {}': ! - 97..99 '{}': () - 115..128 'Self::A { x }': E - 125..126 'x': usize - 132..138 '{ x; }': () - 134..135 'x': usize - 152..162 'Self::B(x)': E - 160..161 'x': usize - 166..172 '{ x; }': () - 168..169 'x': usize - 186..193 'Self::C': E - 197..199 '{}': () - "### + impl E { + fn test() { + match (loop {}) { + Self::A { x } => { x; }, + Self::B(x) => { x; }, + Self::C => {}, + }; + } + } + "#, + expect![[r#" + 75..217 '{ ... }': () + 85..210 'match ... }': () + 92..99 'loop {}': ! + 97..99 '{}': () + 115..128 'Self::A { x }': E + 125..126 'x': usize + 132..138 '{ x; }': () + 134..135 'x': usize + 152..162 'Self::B(x)': E + 160..161 'x': usize + 166..172 '{ x; }': () + 168..169 'x': usize + 186..193 'Self::C': E + 197..199 '{}': () + "#]], ); } #[test] fn infer_generics_in_patterns() { - assert_snapshot!( - infer(r#" -struct A { - x: T, -} + check_infer( + r#" + struct A { + x: T, + } -enum Option { - Some(T), - None, -} + enum Option { + Some(T), + None, + } -fn test(a1: A, o: Option) { - let A { x: x2 } = a1; - let A:: { x: x3 } = A { x: 1 }; - match o { - Option::Some(t) => t, - _ => 1, - }; -} -"#), - @r###" - 78..80 'a1': A - 90..91 'o': Option - 106..243 '{ ... }; }': () - 116..127 'A { x: x2 }': A - 123..125 'x2': u32 - 130..132 'a1': A - 142..160 'A:: - 156..158 'x3': i64 - 163..173 'A { x: 1 }': A - 170..171 '1': i64 - 179..240 'match ... }': u64 - 185..186 'o': Option - 197..212 'Option::Some(t)': Option - 210..211 't': u64 - 216..217 't': u64 - 227..228 '_': Option - 232..233 '1': u64 - "### + fn test(a1: A, o: Option) { + let A { x: x2 } = a1; + let A:: { x: x3 } = A { x: 1 }; + match o { + Option::Some(t) => t, + _ => 1, + }; + } + "#, + expect![[r#" + 78..80 'a1': A + 90..91 'o': Option + 106..243 '{ ... }; }': () + 116..127 'A { x: x2 }': A + 123..125 'x2': u32 + 130..132 'a1': A + 142..160 'A:: + 156..158 'x3': i64 + 163..173 'A { x: 1 }': A + 170..171 '1': i64 + 179..240 'match ... }': u64 + 185..186 'o': Option + 197..212 'Option::Some(t)': Option + 210..211 't': u64 + 216..217 't': u64 + 227..228 '_': Option + 232..233 '1': u64 + "#]], ); } #[test] fn infer_const_pattern() { - assert_snapshot!( - infer_with_mismatches(r#" -enum Option { None } -use Option::None; -struct Foo; -const Bar: usize = 1; - -fn test() { - let a: Option = None; - let b: Option = match a { - None => None, - }; - let _: () = match () { Foo => Foo }; // Expected mismatch - let _: () = match () { Bar => Bar }; // Expected mismatch -} -"#, true), - @r###" - 73..74 '1': usize - 87..309 '{ ...atch }': () - 97..98 'a': Option - 114..118 'None': Option - 128..129 'b': Option - 145..182 'match ... }': Option - 151..152 'a': Option - 163..167 'None': Option - 171..175 'None': Option - 192..193 '_': () - 200..223 'match ... Foo }': Foo - 206..208 '()': () - 211..214 'Foo': Foo - 218..221 'Foo': Foo - 254..255 '_': () - 262..285 'match ... Bar }': usize - 268..270 '()': () - 273..276 'Bar': usize - 280..283 'Bar': usize - 200..223: expected (), got Foo - 262..285: expected (), got usize - "### + check_infer_with_mismatches( + r#" + enum Option { None } + use Option::None; + struct Foo; + const Bar: usize = 1; + + fn test() { + let a: Option = None; + let b: Option = match a { + None => None, + }; + let _: () = match () { Foo => Foo }; // Expected mismatch + let _: () = match () { Bar => Bar }; // Expected mismatch + } + "#, + expect![[r#" + 73..74 '1': usize + 87..309 '{ ...atch }': () + 97..98 'a': Option + 114..118 'None': Option + 128..129 'b': Option + 145..182 'match ... }': Option + 151..152 'a': Option + 163..167 'None': Option + 171..175 'None': Option + 192..193 '_': () + 200..223 'match ... Foo }': Foo + 206..208 '()': () + 211..214 'Foo': Foo + 218..221 'Foo': Foo + 254..255 '_': () + 262..285 'match ... Bar }': usize + 268..270 '()': () + 273..276 'Bar': usize + 280..283 'Bar': usize + 200..223: expected (), got Foo + 262..285: expected (), got usize + "#]], ); } #[test] fn infer_guard() { - assert_snapshot!( - infer(r#" + check_infer( + r#" struct S; impl S { fn foo(&self) -> bool { false } } @@ -564,91 +564,93 @@ fn main() { s if s.foo() => (), } } - "#), @r###" - 27..31 'self': &S - 41..50 '{ false }': bool - 43..48 'false': bool - 64..115 '{ ... } }': () - 70..113 'match ... }': () - 76..77 'S': S - 88..89 's': S - 93..94 's': S - 93..100 's.foo()': bool - 104..106 '()': () - "###) + "#, + expect![[r#" + 27..31 'self': &S + 41..50 '{ false }': bool + 43..48 'false': bool + 64..115 '{ ... } }': () + 70..113 'match ... }': () + 76..77 'S': S + 88..89 's': S + 93..94 's': S + 93..100 's.foo()': bool + 104..106 '()': () + "#]], + ) } #[test] fn match_ergonomics_in_closure_params() { - assert_snapshot!( - infer(r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} + check_infer( + r#" + #[lang = "fn_once"] + trait FnOnce { + type Output; + } -fn foo U>(t: T, f: F) -> U { loop {} } + fn foo U>(t: T, f: F) -> U { loop {} } -fn test() { - foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics - foo(&(1, "a"), |(x, y)| x); -} -"#), - @r###" - 93..94 't': T - 99..100 'f': F - 110..121 '{ loop {} }': U - 112..119 'loop {}': ! - 117..119 '{}': () - 133..232 '{ ... x); }': () - 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 - 139..166 'foo(&(...y)| x)': i32 - 143..152 '&(1, "a")': &(i32, &str) - 144..152 '(1, "a")': (i32, &str) - 145..146 '1': i32 - 148..151 '"a"': &str - 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 - 155..162 '&(x, y)': &(i32, &str) - 156..162 '(x, y)': (i32, &str) - 157..158 'x': i32 - 160..161 'y': &str - 164..165 'x': i32 - 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 - 203..229 'foo(&(...y)| x)': &i32 - 207..216 '&(1, "a")': &(i32, &str) - 208..216 '(1, "a")': (i32, &str) - 209..210 '1': i32 - 212..215 '"a"': &str - 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 - 219..225 '(x, y)': (i32, &str) - 220..221 'x': &i32 - 223..224 'y': &&str - 227..228 'x': &i32 - "### + fn test() { + foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics + foo(&(1, "a"), |(x, y)| x); + } + "#, + expect![[r#" + 93..94 't': T + 99..100 'f': F + 110..121 '{ loop {} }': U + 112..119 'loop {}': ! + 117..119 '{}': () + 133..232 '{ ... x); }': () + 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 + 139..166 'foo(&(...y)| x)': i32 + 143..152 '&(1, "a")': &(i32, &str) + 144..152 '(1, "a")': (i32, &str) + 145..146 '1': i32 + 148..151 '"a"': &str + 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 + 155..162 '&(x, y)': &(i32, &str) + 156..162 '(x, y)': (i32, &str) + 157..158 'x': i32 + 160..161 'y': &str + 164..165 'x': i32 + 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 + 203..229 'foo(&(...y)| x)': &i32 + 207..216 '&(1, "a")': &(i32, &str) + 208..216 '(1, "a")': (i32, &str) + 209..210 '1': i32 + 212..215 '"a"': &str + 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 + 219..225 '(x, y)': (i32, &str) + 220..221 'x': &i32 + 223..224 'y': &&str + 227..228 'x': &i32 + "#]], ); } #[test] fn slice_tail_pattern() { - assert_snapshot!( - infer(r#" -fn foo(params: &[i32]) { - match params { - [head, tail @ ..] => { + check_infer( + r#" + fn foo(params: &[i32]) { + match params { + [head, tail @ ..] => { + } + } } - } -} -"#), - @r###" - 7..13 'params': &[i32] - 23..92 '{ ... } }': () - 29..90 'match ... }': () - 35..41 'params': &[i32] - 52..69 '[head,... @ ..]': [i32] - 53..57 'head': &i32 - 59..68 'tail @ ..': &[i32] - 66..68 '..': [i32] - 73..84 '{ }': () - "### + "#, + expect![[r#" + 7..13 'params': &[i32] + 23..92 '{ ... } }': () + 29..90 'match ... }': () + 35..41 'params': &[i32] + 52..69 '[head,... @ ..]': [i32] + 53..57 'head': &i32 + 59..68 'tail @ ..': &[i32] + 66..68 '..': [i32] + 73..84 '{ }': () + "#]], ); } diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 4367621fc..b9ab0f357 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -1,87 +1,87 @@ -use insta::assert_snapshot; +use expect::expect; use test_utils::mark; -use super::{check_types, infer}; +use super::{check_infer, check_types}; #[test] fn bug_484() { - assert_snapshot!( - infer(r#" -fn test() { - let x = if true {}; -} -"#), - @r###" - 10..36 '{ l... {}; }': () - 19..20 'x': () - 23..33 'if true {}': () - 26..30 'true': bool - 31..33 '{}': () - "### + check_infer( + r#" + fn test() { + let x = if true {}; + } + "#, + expect![[r#" + 10..37 '{ ... {}; }': () + 20..21 'x': () + 24..34 'if true {}': () + 27..31 'true': bool + 32..34 '{}': () + "#]], ); } #[test] fn no_panic_on_field_of_enum() { - assert_snapshot!( - infer(r#" -enum X {} - -fn test(x: X) { - x.some_field; -} -"#), - @r###" - 19..20 'x': X - 25..46 '{ ...eld; }': () - 31..32 'x': X - 31..43 'x.some_field': {unknown} - "### + check_infer( + r#" + enum X {} + + fn test(x: X) { + x.some_field; + } + "#, + expect![[r#" + 19..20 'x': X + 25..46 '{ ...eld; }': () + 31..32 'x': X + 31..43 'x.some_field': {unknown} + "#]], ); } #[test] fn bug_585() { - assert_snapshot!( - infer(r#" -fn test() { - X {}; - match x { - A::B {} => (), - A::Y() => (), - } -} -"#), - @r###" - 10..88 '{ ... } }': () - 16..20 'X {}': {unknown} - 26..86 'match ... }': () - 32..33 'x': {unknown} - 44..51 'A::B {}': {unknown} - 55..57 '()': () - 67..73 'A::Y()': {unknown} - 77..79 '()': () - "### + check_infer( + r#" + fn test() { + X {}; + match x { + A::B {} => (), + A::Y() => (), + } + } + "#, + expect![[r#" + 10..88 '{ ... } }': () + 16..20 'X {}': {unknown} + 26..86 'match ... }': () + 32..33 'x': {unknown} + 44..51 'A::B {}': {unknown} + 55..57 '()': () + 67..73 'A::Y()': {unknown} + 77..79 '()': () + "#]], ); } #[test] fn bug_651() { - assert_snapshot!( - infer(r#" -fn quux() { - let y = 92; - 1 + y; -} -"#), - @r###" - 10..40 '{ ...+ y; }': () - 20..21 'y': i32 - 24..26 '92': i32 - 32..33 '1': i32 - 32..37 '1 + y': i32 - 36..37 'y': i32 - "### + check_infer( + r#" + fn quux() { + let y = 92; + 1 + y; + } + "#, + expect![[r#" + 10..40 '{ ...+ y; }': () + 20..21 'y': i32 + 24..26 '92': i32 + 32..33 '1': i32 + 32..37 '1 + y': i32 + 36..37 'y': i32 + "#]], ); } @@ -89,78 +89,78 @@ fn quux() { fn recursive_vars() { mark::check!(type_var_cycles_resolve_completely); mark::check!(type_var_cycles_resolve_as_possible); - assert_snapshot!( - infer(r#" -fn test() { - let y = unknown; - [y, &y]; -} -"#), - @r###" - 10..47 '{ ...&y]; }': () - 20..21 'y': &{unknown} - 24..31 'unknown': &{unknown} - 37..44 '[y, &y]': [&&{unknown}; _] - 38..39 'y': &{unknown} - 41..43 '&y': &&{unknown} - 42..43 'y': &{unknown} - "### + check_infer( + r#" + fn test() { + let y = unknown; + [y, &y]; + } + "#, + expect![[r#" + 10..47 '{ ...&y]; }': () + 20..21 'y': &{unknown} + 24..31 'unknown': &{unknown} + 37..44 '[y, &y]': [&&{unknown}; _] + 38..39 'y': &{unknown} + 41..43 '&y': &&{unknown} + 42..43 'y': &{unknown} + "#]], ); } #[test] fn recursive_vars_2() { - assert_snapshot!( - infer(r#" -fn test() { - let x = unknown; - let y = unknown; - [(x, y), (&y, &x)]; -} -"#), - @r###" - 10..79 '{ ...x)]; }': () - 20..21 'x': &&{unknown} - 24..31 'unknown': &&{unknown} - 41..42 'y': &&{unknown} - 45..52 'unknown': &&{unknown} - 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] - 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) - 60..61 'x': &&{unknown} - 63..64 'y': &&{unknown} - 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) - 68..70 '&y': &&&{unknown} - 69..70 'y': &&{unknown} - 72..74 '&x': &&&{unknown} - 73..74 'x': &&{unknown} - "### + check_infer( + r#" + fn test() { + let x = unknown; + let y = unknown; + [(x, y), (&y, &x)]; + } + "#, + expect![[r#" + 10..79 '{ ...x)]; }': () + 20..21 'x': &&{unknown} + 24..31 'unknown': &&{unknown} + 41..42 'y': &&{unknown} + 45..52 'unknown': &&{unknown} + 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] + 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) + 60..61 'x': &&{unknown} + 63..64 'y': &&{unknown} + 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) + 68..70 '&y': &&&{unknown} + 69..70 'y': &&{unknown} + 72..74 '&x': &&&{unknown} + 73..74 'x': &&{unknown} + "#]], ); } #[test] fn infer_std_crash_1() { // caused stack overflow, taken from std - assert_snapshot!( - infer(r#" -enum Maybe { - Real(T), - Fake, -} + check_infer( + r#" + enum Maybe { + Real(T), + Fake, + } -fn write() { - match something_unknown { - Maybe::Real(ref mut something) => (), - } -} -"#), - @r###" - 53..138 '{ ... } }': () - 59..136 'match ... }': () - 65..82 'someth...nknown': Maybe<{unknown}> - 93..123 'Maybe:...thing)': Maybe<{unknown}> - 105..122 'ref mu...ething': &mut {unknown} - 127..129 '()': () - "### + fn write() { + match something_unknown { + Maybe::Real(ref mut something) => (), + } + } + "#, + expect![[r#" + 53..138 '{ ... } }': () + 59..136 'match ... }': () + 65..82 'someth...nknown': Maybe<{unknown}> + 93..123 'Maybe:...thing)': Maybe<{unknown}> + 105..122 'ref mu...ething': &mut {unknown} + 127..129 '()': () + "#]], ); } @@ -168,234 +168,235 @@ fn write() { fn infer_std_crash_2() { mark::check!(type_var_resolves_to_int_var); // caused "equating two type variables, ...", taken from std - assert_snapshot!( - infer(r#" -fn test_line_buffer() { - &[0, b'\n', 1, b'\n']; -} -"#), - @r###" - 22..52 '{ ...n']; }': () - 28..49 '&[0, b...b'\n']': &[u8; _] - 29..49 '[0, b'...b'\n']': [u8; _] - 30..31 '0': u8 - 33..38 'b'\n'': u8 - 40..41 '1': u8 - 43..48 'b'\n'': u8 - "### + check_infer( + r#" + fn test_line_buffer() { + &[0, b'\n', 1, b'\n']; + } + "#, + expect![[r#" + 22..52 '{ ...n']; }': () + 28..49 '&[0, b...b'\n']': &[u8; _] + 29..49 '[0, b'...b'\n']': [u8; _] + 30..31 '0': u8 + 33..38 'b'\n'': u8 + 40..41 '1': u8 + 43..48 'b'\n'': u8 + "#]], ); } #[test] fn infer_std_crash_3() { // taken from rustc - assert_snapshot!( - infer(r#" -pub fn compute() { - match nope!() { - SizeSkeleton::Pointer { non_zero: true, tail } => {} - } -} -"#), - @r###" - 17..107 '{ ... } }': () - 23..105 'match ... }': () - 29..36 'nope!()': {unknown} - 47..93 'SizeSk...tail }': {unknown} - 81..85 'true': bool - 81..85 'true': bool - 87..91 'tail': {unknown} - 97..99 '{}': () - "### + check_infer( + r#" + pub fn compute() { + match nope!() { + SizeSkeleton::Pointer { non_zero: true, tail } => {} + } + } + "#, + expect![[r#" + 17..107 '{ ... } }': () + 23..105 'match ... }': () + 29..36 'nope!()': {unknown} + 47..93 'SizeSk...tail }': {unknown} + 81..85 'true': bool + 81..85 'true': bool + 87..91 'tail': {unknown} + 97..99 '{}': () + "#]], ); } #[test] fn infer_std_crash_4() { // taken from rustc - assert_snapshot!( - infer(r#" -pub fn primitive_type() { - match *self { - BorrowedRef { type_: Primitive(p), ..} => {}, - } -} -"#), - @r###" - 24..105 '{ ... } }': () - 30..103 'match ... }': () - 36..41 '*self': {unknown} - 37..41 'self': {unknown} - 52..90 'Borrow...), ..}': {unknown} - 73..85 'Primitive(p)': {unknown} - 83..84 'p': {unknown} - 94..96 '{}': () - "### + check_infer( + r#" + pub fn primitive_type() { + match *self { + BorrowedRef { type_: Primitive(p), ..} => {}, + } + } + "#, + expect![[r#" + 24..105 '{ ... } }': () + 30..103 'match ... }': () + 36..41 '*self': {unknown} + 37..41 'self': {unknown} + 52..90 'Borrow...), ..}': {unknown} + 73..85 'Primitive(p)': {unknown} + 83..84 'p': {unknown} + 94..96 '{}': () + "#]], ); } #[test] fn infer_std_crash_5() { // taken from rustc - assert_snapshot!( - infer(r#" -fn extra_compiler_flags() { - for content in doesnt_matter { - let name = if doesnt_matter { - first - } else { - &content - }; - - let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { - name - } else { - content - }; - } -} -"#), - @r###" - 26..322 '{ ... } }': () - 32..320 'for co... }': () - 36..43 'content': &{unknown} - 47..60 'doesnt_matter': {unknown} - 61..320 '{ ... }': () - 75..79 'name': &&{unknown} - 82..166 'if doe... }': &&{unknown} - 85..98 'doesnt_matter': bool - 99..128 '{ ... }': &&{unknown} - 113..118 'first': &&{unknown} - 134..166 '{ ... }': &&{unknown} - 148..156 '&content': &&{unknown} - 149..156 'content': &{unknown} - 181..188 'content': &{unknown} - 191..313 'if ICE... }': &{unknown} - 194..231 'ICE_RE..._VALUE': {unknown} - 194..247 'ICE_RE...&name)': bool - 241..246 '&name': &&&{unknown} - 242..246 'name': &&{unknown} - 248..276 '{ ... }': &&{unknown} - 262..266 'name': &&{unknown} - 282..313 '{ ... }': &{unknown} - 296..303 'content': &{unknown} - "### + check_infer( + r#" + fn extra_compiler_flags() { + for content in doesnt_matter { + let name = if doesnt_matter { + first + } else { + &content + }; + + let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { + name + } else { + content + }; + } + } + "#, + expect![[r#" + 26..322 '{ ... } }': () + 32..320 'for co... }': () + 36..43 'content': &{unknown} + 47..60 'doesnt_matter': {unknown} + 61..320 '{ ... }': () + 75..79 'name': &&{unknown} + 82..166 'if doe... }': &&{unknown} + 85..98 'doesnt_matter': bool + 99..128 '{ ... }': &&{unknown} + 113..118 'first': &&{unknown} + 134..166 '{ ... }': &&{unknown} + 148..156 '&content': &&{unknown} + 149..156 'content': &{unknown} + 181..188 'content': &{unknown} + 191..313 'if ICE... }': &{unknown} + 194..231 'ICE_RE..._VALUE': {unknown} + 194..247 'ICE_RE...&name)': bool + 241..246 '&name': &&&{unknown} + 242..246 'name': &&{unknown} + 248..276 '{ ... }': &&{unknown} + 262..266 'name': &&{unknown} + 282..313 '{ ... }': &{unknown} + 296..303 'content': &{unknown} + "#]], ); } #[test] fn infer_nested_generics_crash() { // another crash found typechecking rustc - assert_snapshot!( - infer(r#" -struct Canonical { - value: V, -} -struct QueryResponse { - value: V, -} -fn test(query_response: Canonical>) { - &query_response.value; -} -"#), - @r###" - 91..105 'query_response': Canonical> - 136..166 '{ ...lue; }': () - 142..163 '&query....value': &QueryResponse - 143..157 'query_response': Canonical> - 143..163 'query_....value': QueryResponse - "### + check_infer( + r#" + struct Canonical { + value: V, + } + struct QueryResponse { + value: V, + } + fn test(query_response: Canonical>) { + &query_response.value; + } + "#, + expect![[r#" + 91..105 'query_response': Canonical> + 136..166 '{ ...lue; }': () + 142..163 '&query....value': &QueryResponse + 143..157 'query_response': Canonical> + 143..163 'query_....value': QueryResponse + "#]], ); } #[test] fn infer_paren_macro_call() { - assert_snapshot!( - infer(r#" -macro_rules! bar { () => {0u32} } -fn test() { - let a = (bar!()); -} -"#), - @r###" - !0..4 '0u32': u32 - 44..69 '{ ...()); }': () - 54..55 'a': u32 - "### + check_infer( + r#" + macro_rules! bar { () => {0u32} } + fn test() { + let a = (bar!()); + } + "#, + expect![[r#" + !0..4 '0u32': u32 + 44..69 '{ ...()); }': () + 54..55 'a': u32 + "#]], ); } #[test] fn bug_1030() { - assert_snapshot!(infer(r#" -struct HashSet; -struct FxHasher; -type FxHashSet = HashSet; + check_infer( + r#" + struct HashSet; + struct FxHasher; + type FxHashSet = HashSet; -impl HashSet { - fn default() -> HashSet {} -} + impl HashSet { + fn default() -> HashSet {} + } -pub fn main_loop() { - FxHashSet::default(); -} -"#), - @r###" - 143..145 '{}': () - 168..197 '{ ...t(); }': () - 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> - 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> - "### + pub fn main_loop() { + FxHashSet::default(); + } + "#, + expect![[r#" + 143..145 '{}': () + 168..197 '{ ...t(); }': () + 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> + 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> + "#]], ); } #[test] fn issue_2669() { - assert_snapshot!( - infer( - r#"trait A {} - trait Write {} - struct Response {} - - trait D { - fn foo(); - } + check_infer( + r#" + trait A {} + trait Write {} + struct Response {} + + trait D { + fn foo(); + } - impl D for Response { - fn foo() { - end(); - fn end() { - let _x: T = loop {}; + impl D for Response { + fn foo() { + end(); + fn end() { + let _x: T = loop {}; + } } } - }"# - ), - @r###" - 147..262 '{ ... }': () - 161..164 'end': fn end<{unknown}>() - 161..166 'end()': () - 199..252 '{ ... }': () - 221..223 '_x': ! - 230..237 'loop {}': ! - 235..237 '{}': () - "### + "#, + expect![[r#" + 119..214 '{ ... }': () + 129..132 'end': fn end<{unknown}>() + 129..134 'end()': () + 163..208 '{ ... }': () + 181..183 '_x': ! + 190..197 'loop {}': ! + 195..197 '{}': () + "#]], ) } #[test] fn issue_2705() { - assert_snapshot!( - infer(r#" -trait Trait {} -fn test() { - >::foo() -} -"#), - @r###" - 25..52 '{ ...oo() }': () - 31..48 '::foo': {unknown} - 31..50 '>::foo() + } + "#, + expect![[r#" + 25..52 '{ ...oo() }': () + 31..48 '::foo': {unknown} + 31..50 ' {} - } -} -"#), - @r###" - 7..13 'params': &[usize] - 25..80 '{ ... } }': () - 31..78 'match ... }': () - 37..43 'params': &[usize] - 54..66 '[ps @ .., _]': [usize] - 55..62 'ps @ ..': &[usize] - 60..62 '..': [usize] - 64..65 '_': usize - 70..72 '{}': () - "### + check_infer( + r#" + fn foo(params: &[usize]) { + match params { + [ps @ .., _] => {} + } + } + "#, + expect![[r#" + 7..13 'params': &[usize] + 25..80 '{ ... } }': () + 31..78 'match ... }': () + 37..43 'params': &[usize] + 54..66 '[ps @ .., _]': [usize] + 55..62 'ps @ ..': &[usize] + 60..62 '..': [usize] + 64..65 '_': usize + 70..72 '{}': () + "#]], ); } @@ -505,334 +506,337 @@ fn foo(params: &[usize]) { fn issue_3999_struct() { // rust-analyzer should not panic on seeing this malformed // record pattern. - assert_snapshot!( - infer(r#" -struct Bar { - a: bool, -} -fn foo(b: Bar) { - match b { - Bar { a: .. } => {}, - } -} -"#), - @r###" - 35..36 'b': Bar - 43..95 '{ ... } }': () - 49..93 'match ... }': () - 55..56 'b': Bar - 67..80 'Bar { a: .. }': Bar - 76..78 '..': bool - 84..86 '{}': () - "### + check_infer( + r#" + struct Bar { + a: bool, + } + fn foo(b: Bar) { + match b { + Bar { a: .. } => {}, + } + } + "#, + expect![[r#" + 35..36 'b': Bar + 43..95 '{ ... } }': () + 49..93 'match ... }': () + 55..56 'b': Bar + 67..80 'Bar { a: .. }': Bar + 76..78 '..': bool + 84..86 '{}': () + "#]], ); } #[test] fn issue_4235_name_conflicts() { - assert_snapshot!( - infer(r#" -struct FOO {} -static FOO:FOO = FOO {}; + check_infer( + r#" + struct FOO {} + static FOO:FOO = FOO {}; -impl FOO { - fn foo(&self) {} -} + impl FOO { + fn foo(&self) {} + } -fn main() { - let a = &FOO; - a.foo(); -} -"#), @r###" - 31..37 'FOO {}': FOO - 63..67 'self': &FOO - 69..71 '{}': () - 85..119 '{ ...o(); }': () - 95..96 'a': &FOO - 99..103 '&FOO': &FOO - 100..103 'FOO': FOO - 109..110 'a': &FOO - 109..116 'a.foo()': () - "### + fn main() { + let a = &FOO; + a.foo(); + } + "#, + expect![[r#" + 31..37 'FOO {}': FOO + 63..67 'self': &FOO + 69..71 '{}': () + 85..119 '{ ...o(); }': () + 95..96 'a': &FOO + 99..103 '&FOO': &FOO + 100..103 'FOO': FOO + 109..110 'a': &FOO + 109..116 'a.foo()': () + "#]], ); } #[test] fn issue_4465_dollar_crate_at_type() { - assert_snapshot!( - infer(r#" -pub struct Foo {} -pub fn anything() -> T { - loop {} -} -macro_rules! foo { - () => {{ - let r: $crate::Foo = anything(); - r - }}; -} -fn main() { - let _a = foo!(); -} -"#), @r###" - 44..59 '{ loop {} }': T - 50..57 'loop {}': ! - 55..57 '{}': () - !0..31 '{letr:...g();r}': Foo - !4..5 'r': Foo - !18..26 'anything': fn anything() -> Foo - !18..28 'anything()': Foo - !29..30 'r': Foo - 163..187 '{ ...!(); }': () - 173..175 '_a': Foo - "###); + check_infer( + r#" + pub struct Foo {} + pub fn anything() -> T { + loop {} + } + macro_rules! foo { + () => {{ + let r: $crate::Foo = anything(); + r + }}; + } + fn main() { + let _a = foo!(); + } + "#, + expect![[r#" + 44..59 '{ loop {} }': T + 50..57 'loop {}': ! + 55..57 '{}': () + !0..31 '{letr:...g();r}': Foo + !4..5 'r': Foo + !18..26 'anything': fn anything() -> Foo + !18..28 'anything()': Foo + !29..30 'r': Foo + 163..187 '{ ...!(); }': () + 173..175 '_a': Foo + "#]], + ); } #[test] fn issue_4053_diesel_where_clauses() { - assert_snapshot!( - infer(r#" -trait BoxedDsl { - type Output; - fn internal_into_boxed(self) -> Self::Output; -} + check_infer( + r#" + trait BoxedDsl { + type Output; + fn internal_into_boxed(self) -> Self::Output; + } -struct SelectStatement { - order: Order, -} + struct SelectStatement { + order: Order, + } -trait QueryFragment {} + trait QueryFragment {} -trait Into { fn into(self) -> T; } + trait Into { fn into(self) -> T; } -impl BoxedDsl - for SelectStatement -where - O: Into>, -{ - type Output = XXX; + impl BoxedDsl + for SelectStatement + where + O: Into>, + { + type Output = XXX; - fn internal_into_boxed(self) -> Self::Output { - self.order.into(); - } -} -"#), - @r###" - 65..69 'self': Self - 267..271 'self': Self - 466..470 'self': SelectStatement - 488..522 '{ ... }': () - 498..502 'self': SelectStatement - 498..508 'self.order': O - 498..515 'self.o...into()': dyn QueryFragment - "### + fn internal_into_boxed(self) -> Self::Output { + self.order.into(); + } + } + "#, + expect![[r#" + 65..69 'self': Self + 267..271 'self': Self + 466..470 'self': SelectStatement + 488..522 '{ ... }': () + 498..502 'self': SelectStatement + 498..508 'self.order': O + 498..515 'self.o...into()': dyn QueryFragment + "#]], ); } #[test] fn issue_4953() { - assert_snapshot!( - infer(r#" -pub struct Foo(pub i64); -impl Foo { - fn test() -> Self { Self(0i64) } -} -"#), - @r###" - 58..72 '{ Self(0i64) }': Foo - 60..64 'Self': Foo(i64) -> Foo - 60..70 'Self(0i64)': Foo - 65..69 '0i64': i64 - "### + check_infer( + r#" + pub struct Foo(pub i64); + impl Foo { + fn test() -> Self { Self(0i64) } + } + "#, + expect![[r#" + 58..72 '{ Self(0i64) }': Foo + 60..64 'Self': Foo(i64) -> Foo + 60..70 'Self(0i64)': Foo + 65..69 '0i64': i64 + "#]], ); - assert_snapshot!( - infer(r#" -pub struct Foo(pub T); -impl Foo { - fn test() -> Self { Self(0i64) } -} -"#), - @r###" - 64..78 '{ Self(0i64) }': Foo - 66..70 'Self': Foo(i64) -> Foo - 66..76 'Self(0i64)': Foo - 71..75 '0i64': i64 - "### + check_infer( + r#" + pub struct Foo(pub T); + impl Foo { + fn test() -> Self { Self(0i64) } + } + "#, + expect![[r#" + 64..78 '{ Self(0i64) }': Foo + 66..70 'Self': Foo(i64) -> Foo + 66..76 'Self(0i64)': Foo + 71..75 '0i64': i64 + "#]], ); } #[test] fn issue_4931() { - assert_snapshot!( - infer(r#" -trait Div { - type Output; -} + check_infer( + r#" + trait Div { + type Output; + } -trait CheckedDiv: Div<()> {} + trait CheckedDiv: Div<()> {} -trait PrimInt: CheckedDiv { - fn pow(self); -} + trait PrimInt: CheckedDiv { + fn pow(self); + } -fn check(i: T) { - i.pow(); -} -"#), - @r###" - 117..121 'self': Self - 148..149 'i': T - 154..170 '{ ...w(); }': () - 160..161 'i': T - 160..167 'i.pow()': () - "### + fn check(i: T) { + i.pow(); + } + "#, + expect![[r#" + 117..121 'self': Self + 148..149 'i': T + 154..170 '{ ...w(); }': () + 160..161 'i': T + 160..167 'i.pow()': () + "#]], ); } #[test] fn issue_4885() { - assert_snapshot!( - infer(r#" -#[lang = "coerce_unsized"] -pub trait CoerceUnsized {} - -trait Future { - type Output; -} -trait Foo { - type Bar; -} -fn foo(key: &K) -> impl Future -where - K: Foo, -{ - bar(key) -} -fn bar(key: &K) -> impl Future -where - K: Foo, -{ -} -"#), - @r###" - 136..139 'key': &K - 198..214 '{ ...key) }': impl Future>::Bar> - 204..207 'bar': fn bar(&K) -> impl Future>::Bar> - 204..212 'bar(key)': impl Future>::Bar> - 208..211 'key': &K - 228..231 'key': &K - 290..293 '{ }': () - "### + check_infer( + r#" + #[lang = "coerce_unsized"] + pub trait CoerceUnsized {} + + trait Future { + type Output; + } + trait Foo { + type Bar; + } + fn foo(key: &K) -> impl Future + where + K: Foo, + { + bar(key) + } + fn bar(key: &K) -> impl Future + where + K: Foo, + { + } + "#, + expect![[r#" + 136..139 'key': &K + 198..214 '{ ...key) }': impl Future>::Bar> + 204..207 'bar': fn bar(&K) -> impl Future>::Bar> + 204..212 'bar(key)': impl Future>::Bar> + 208..211 'key': &K + 228..231 'key': &K + 290..293 '{ }': () + "#]], ); } #[test] fn issue_4800() { - assert_snapshot!( - infer(r#" -trait Debug {} + check_infer( + r#" + trait Debug {} -struct Foo; + struct Foo; -type E1 = (T, T, T); -type E2 = E1>>; + type E1 = (T, T, T); + type E2 = E1>>; -impl Debug for Foo> {} + impl Debug for Foo> {} -struct Request; + struct Request; -pub trait Future { - type Output; -} + pub trait Future { + type Output; + } -pub struct PeerSet; + pub struct PeerSet; -impl Service for PeerSet -where - D: Discover, - D::Key: Debug, -{ - type Error = (); - type Future = dyn Future; + impl Service for PeerSet + where + D: Discover, + D::Key: Debug, + { + type Error = (); + type Future = dyn Future; - fn call(&mut self) -> Self::Future { - loop {} - } -} + fn call(&mut self) -> Self::Future { + loop {} + } + } -pub trait Discover { - type Key; -} + pub trait Discover { + type Key; + } -pub trait Service { - type Error; - type Future: Future; - fn call(&mut self) -> Self::Future; -} -"#), - @r###" - 379..383 'self': &mut PeerSet - 401..424 '{ ... }': dyn Future - 411..418 'loop {}': ! - 416..418 '{}': () - 575..579 'self': &mut Self - "### + pub trait Service { + type Error; + type Future: Future; + fn call(&mut self) -> Self::Future; + } + "#, + expect![[r#" + 379..383 'self': &mut PeerSet + 401..424 '{ ... }': dyn Future + 411..418 'loop {}': ! + 416..418 '{}': () + 575..579 'self': &mut Self + "#]], ); } #[test] fn issue_4966() { - assert_snapshot!( - infer(r#" -pub trait IntoIterator { - type Item; -} + check_infer( + r#" + pub trait IntoIterator { + type Item; + } -struct Repeat { element: A } + struct Repeat { element: A } -struct Map { f: F } + struct Map { f: F } -struct Vec {} + struct Vec {} -#[lang = "deref"] -pub trait Deref { - type Target; -} + #[lang = "deref"] + pub trait Deref { + type Target; + } -impl Deref for Vec { - type Target = [T]; -} + impl Deref for Vec { + type Target = [T]; + } -fn from_iter>(iter: T) -> Vec {} + fn from_iter>(iter: T) -> Vec {} -fn main() { - let inner = Map { f: |_: &f64| 0.0 }; - - let repeat = Repeat { element: inner }; - - let vec = from_iter(repeat); - - vec.foo_bar(); -} -"#), - @r###" - 270..274 'iter': T - 289..291 '{}': () - 303..447 '{ ...r(); }': () - 313..318 'inner': Map<|&f64| -> f64> - 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> - 330..343 '|_: &f64| 0.0': |&f64| -> f64 - 331..332 '_': &f64 - 340..343 '0.0': f64 - 356..362 'repeat': Repeat f64>> - 365..390 'Repeat...nner }': Repeat f64>> - 383..388 'inner': Map<|&f64| -> f64> - 401..404 'vec': Vec f64>>>> - 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec f64>>>> - 407..424 'from_i...epeat)': Vec f64>>>> - 417..423 'repeat': Repeat f64>> - 431..434 'vec': Vec f64>>>> - 431..444 'vec.foo_bar()': {unknown} - "### + fn main() { + let inner = Map { f: |_: &f64| 0.0 }; + + let repeat = Repeat { element: inner }; + + let vec = from_iter(repeat); + + vec.foo_bar(); + } + "#, + expect![[r#" + 270..274 'iter': T + 289..291 '{}': () + 303..447 '{ ...r(); }': () + 313..318 'inner': Map<|&f64| -> f64> + 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> + 330..343 '|_: &f64| 0.0': |&f64| -> f64 + 331..332 '_': &f64 + 340..343 '0.0': f64 + 356..362 'repeat': Repeat f64>> + 365..390 'Repeat...nner }': Repeat f64>> + 383..388 'inner': Map<|&f64| -> f64> + 401..404 'vec': Vec f64>>>> + 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec f64>>>> + 407..424 'from_i...epeat)': Vec f64>>>> + 417..423 'repeat': Repeat f64>> + 431..434 'vec': Vec f64>>>> + 431..444 'vec.foo_bar()': {unknown} + "#]], ); } diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index 6d3e264af..3fd7d5cd4 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -1,6 +1,6 @@ -use insta::assert_snapshot; +use expect::expect; -use super::{check_types, infer}; +use super::{check_infer, check_types}; #[test] fn infer_box() { @@ -45,43 +45,44 @@ fn test() { #[test] fn self_in_struct_lit() { - assert_snapshot!(infer( + check_infer( r#" -//- /main.rs -struct S { x: T } + //- /main.rs + struct S { x: T } -impl S { - fn foo() { - Self { x: 1 }; - } -} -"#, - ), @r###" - 49..79 '{ ... }': () - 59..72 'Self { x: 1 }': S - 69..70 '1': u32 - "###); + impl S { + fn foo() { + Self { x: 1 }; + } + } + "#, + expect![[r#" + 49..79 '{ ... }': () + 59..72 'Self { x: 1 }': S + 69..70 '1': u32 + "#]], + ); } #[test] fn type_alias_in_struct_lit() { - assert_snapshot!(infer( + check_infer( r#" -//- /main.rs -struct S { x: T } + //- /main.rs + struct S { x: T } -type SS = S; + type SS = S; -fn foo() { - SS { x: 1 }; -} - -"#, - ), @r###" - 50..70 '{ ...1 }; }': () - 56..67 'SS { x: 1 }': S - 64..65 '1': u32 - "###); + fn foo() { + SS { x: 1 }; + } + "#, + expect![[r#" + 50..70 '{ ...1 }; }': () + 56..67 'SS { x: 1 }': S + 64..65 '1': u32 + "#]], + ); } #[test] @@ -148,1549 +149,1549 @@ fn test() { #[test] fn infer_basics() { - assert_snapshot!( - infer(r#" -fn test(a: u32, b: isize, c: !, d: &str) { - a; - b; - c; - d; - 1usize; - 1isize; - "test"; - 1.0f32; -}"#), - @r###" - 8..9 'a': u32 - 16..17 'b': isize - 26..27 'c': ! - 32..33 'd': &str - 41..120 '{ ...f32; }': () - 47..48 'a': u32 - 54..55 'b': isize - 61..62 'c': ! - 68..69 'd': &str - 75..81 '1usize': usize - 87..93 '1isize': isize - 99..105 '"test"': &str - 111..117 '1.0f32': f32 - "### + check_infer( + r#" + 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 + 26..27 'c': ! + 32..33 'd': &str + 41..120 '{ ...f32; }': () + 47..48 'a': u32 + 54..55 'b': isize + 61..62 'c': ! + 68..69 'd': &str + 75..81 '1usize': usize + 87..93 '1isize': isize + 99..105 '"test"': &str + 111..117 '1.0f32': f32 + "#]], ); } #[test] fn infer_let() { - assert_snapshot!( - infer(r#" -fn test() { - let a = 1isize; - let b: usize = 1; - let c = b; - let d: u32; - let e; - let f: i32 = e; -} -"#), - @r###" - 10..117 '{ ...= e; }': () - 20..21 'a': isize - 24..30 '1isize': isize - 40..41 'b': usize - 51..52 '1': usize - 62..63 'c': usize - 66..67 'b': usize - 77..78 'd': u32 - 93..94 'e': i32 - 104..105 'f': i32 - 113..114 'e': i32 - "### + check_infer( + r#" + 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 + 24..30 '1isize': isize + 40..41 'b': usize + 51..52 '1': usize + 62..63 'c': usize + 66..67 'b': usize + 77..78 'd': u32 + 93..94 'e': i32 + 104..105 'f': i32 + 113..114 'e': i32 + "#]], ); } #[test] fn infer_paths() { - assert_snapshot!( - infer(r#" -fn a() -> u32 { 1 } + check_infer( + r#" + fn a() -> u32 { 1 } -mod b { - fn c() -> u32 { 1 } -} + mod b { + fn c() -> u32 { 1 } + } -fn test() { - a(); - b::c(); -} -"#), - @r###" - 14..19 '{ 1 }': u32 - 16..17 '1': u32 - 47..52 '{ 1 }': u32 - 49..50 '1': u32 - 66..90 '{ ...c(); }': () - 72..73 'a': fn a() -> u32 - 72..75 'a()': u32 - 81..85 'b::c': fn c() -> u32 - 81..87 'b::c()': u32 - "### + fn test() { + a(); + b::c(); + } + "#, + expect![[r#" + 14..19 '{ 1 }': u32 + 16..17 '1': u32 + 47..52 '{ 1 }': u32 + 49..50 '1': u32 + 66..90 '{ ...c(); }': () + 72..73 'a': fn a() -> u32 + 72..75 'a()': u32 + 81..85 'b::c': fn c() -> u32 + 81..87 'b::c()': u32 + "#]], ); } #[test] fn infer_path_type() { - assert_snapshot!( - infer(r#" -struct S; + check_infer( + r#" + struct S; -impl S { - fn foo() -> i32 { 1 } -} + impl S { + fn foo() -> i32 { 1 } + } -fn test() { - S::foo(); - ::foo(); -} -"#), - @r###" - 40..45 '{ 1 }': i32 - 42..43 '1': i32 - 59..92 '{ ...o(); }': () - 65..71 'S::foo': fn foo() -> i32 - 65..73 'S::foo()': i32 - 79..87 '::foo': fn foo() -> i32 - 79..89 '::foo()': i32 - "### + fn test() { + S::foo(); + ::foo(); + } + "#, + expect![[r#" + 40..45 '{ 1 }': i32 + 42..43 '1': i32 + 59..92 '{ ...o(); }': () + 65..71 'S::foo': fn foo() -> i32 + 65..73 'S::foo()': i32 + 79..87 '::foo': fn foo() -> i32 + 79..89 '::foo()': i32 + "#]], ); } #[test] fn infer_struct() { - assert_snapshot!( - infer(r#" -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; -} -"#), - @r###" - 71..153 '{ ...a.c; }': () - 81..82 'c': C - 85..86 'C': C(usize) -> C - 85..89 'C(1)': C - 87..88 '1': usize - 95..96 'B': B - 106..107 'a': A - 113..132 'A { b:...C(1) }': A - 120..121 'B': B - 126..127 'C': C(usize) -> C - 126..130 'C(1)': C - 128..129 '1': usize - 138..139 'a': A - 138..141 'a.b': B - 147..148 'a': A - 147..150 'a.c': C - "### + check_infer( + r#" + 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; + } + "#, + expect![[r#" + 71..153 '{ ...a.c; }': () + 81..82 'c': C + 85..86 'C': C(usize) -> C + 85..89 'C(1)': C + 87..88 '1': usize + 95..96 'B': B + 106..107 'a': A + 113..132 'A { b:...C(1) }': A + 120..121 'B': B + 126..127 'C': C(usize) -> C + 126..130 'C(1)': C + 128..129 '1': usize + 138..139 'a': A + 138..141 'a.b': B + 147..148 'a': A + 147..150 'a.c': C + "#]], ); } #[test] fn infer_enum() { - assert_snapshot!( - infer(r#" -enum E { - V1 { field: u32 }, - V2 -} -fn test() { - E::V1 { field: 1 }; - E::V2; -}"#), - @r###" - 47..81 '{ E:...:V2; }': () - 51..69 'E::V1 ...d: 1 }': E - 66..67 '1': u32 - 73..78 'E::V2': E - "### + check_infer( + r#" + 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 + 72..73 '1': u32 + 81..86 'E::V2': E + "#]], ); } #[test] fn infer_union() { - assert_snapshot!( - infer(r#" -union MyUnion { - foo: u32, - bar: f32, -} - -unsafe fn baz(u: MyUnion) { - let inner = u.foo; -} -"#), - @r###" - 61..62 'u': MyUnion - 73..99 '{ ...foo; }': () - 83..88 'inner': u32 - 91..92 'u': MyUnion - 91..96 'u.foo': u32 - "### + check_infer( + r#" + union MyUnion { + foo: u32, + bar: f32, + } + + unsafe fn baz(u: MyUnion) { + let inner = u.foo; + } + "#, + expect![[r#" + 61..62 'u': MyUnion + 73..99 '{ ...foo; }': () + 83..88 'inner': u32 + 91..92 'u': MyUnion + 91..96 'u.foo': u32 + "#]], ); } #[test] fn infer_refs() { - assert_snapshot!( - 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; -} -"#), - @r###" - 8..9 'a': &u32 - 17..18 'b': &mut u32 - 30..31 'c': *const u32 - 45..46 'd': *mut u32 - 58..149 '{ ... *d; }': () - 64..65 'a': &u32 - 71..73 '*a': u32 - 72..73 'a': &u32 - 79..81 '&a': &&u32 - 80..81 'a': &u32 - 87..93 '&mut a': &mut &u32 - 92..93 'a': &u32 - 99..100 'b': &mut u32 - 106..108 '*b': u32 - 107..108 'b': &mut u32 - 114..116 '&b': &&mut u32 - 115..116 'b': &mut u32 - 122..123 'c': *const u32 - 129..131 '*c': u32 - 130..131 'c': *const u32 - 137..138 'd': *mut u32 - 144..146 '*d': u32 - 145..146 'd': *mut u32 - "### + 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; + } + "#, + expect![[r#" + 8..9 'a': &u32 + 17..18 'b': &mut u32 + 30..31 'c': *const u32 + 45..46 'd': *mut u32 + 58..149 '{ ... *d; }': () + 64..65 'a': &u32 + 71..73 '*a': u32 + 72..73 'a': &u32 + 79..81 '&a': &&u32 + 80..81 'a': &u32 + 87..93 '&mut a': &mut &u32 + 92..93 'a': &u32 + 99..100 'b': &mut u32 + 106..108 '*b': u32 + 107..108 'b': &mut u32 + 114..116 '&b': &&mut u32 + 115..116 'b': &mut u32 + 122..123 'c': *const u32 + 129..131 '*c': u32 + 130..131 'c': *const u32 + 137..138 'd': *mut u32 + 144..146 '*d': u32 + 145..146 'd': *mut u32 + "#]], ); } #[test] fn infer_raw_ref() { - assert_snapshot!( - infer(r#" -fn test(a: i32) { - &raw mut a; - &raw const a; -} -"#), - @r###" - 8..9 'a': i32 - 16..53 '{ ...t a; }': () - 22..32 '&raw mut a': *mut i32 - 31..32 'a': i32 - 38..50 '&raw const a': *const i32 - 49..50 'a': i32 - "### + check_infer( + r#" + fn test(a: i32) { + &raw mut a; + &raw const a; + } + "#, + expect![[r#" + 8..9 'a': i32 + 16..53 '{ ...t a; }': () + 22..32 '&raw mut a': *mut i32 + 31..32 'a': i32 + 38..50 '&raw const a': *const i32 + 49..50 'a': i32 + "#]], ); } #[test] fn infer_literals() { - assert_snapshot!( - infer(r##" -fn test() { - 5i32; - 5f32; - 5f64; - "hello"; - b"bytes"; - 'c'; - b'b'; - 3.14; - 5000; - false; - true; - r#" - //! doc - // non-doc - mod foo {} - "#; - br#"yolo"#; -} -"##), - @r###" - 10..220 '{ ...o"#; }': () - 16..20 '5i32': i32 - 26..30 '5f32': f32 - 36..40 '5f64': f64 - 46..53 '"hello"': &str - 59..67 'b"bytes"': &[u8; _] - 73..76 ''c'': char - 82..86 'b'b'': u8 - 92..96 '3.14': f64 - 102..106 '5000': i32 - 112..117 'false': bool - 123..127 'true': bool - 133..201 'r#" ... "#': &str - 207..217 'br#"yolo"#': &[u8; _] - "### + check_infer( + r##" + fn test() { + 5i32; + 5f32; + 5f64; + "hello"; + b"bytes"; + 'c'; + b'b'; + 3.14; + 5000; + false; + true; + r#" + //! doc + // non-doc + mod foo {} + "#; + br#"yolo"#; + } + "##, + expect![[r##" + 10..216 '{ ...o"#; }': () + 16..20 '5i32': i32 + 26..30 '5f32': f32 + 36..40 '5f64': f64 + 46..53 '"hello"': &str + 59..67 'b"bytes"': &[u8; _] + 73..76 ''c'': char + 82..86 'b'b'': u8 + 92..96 '3.14': f64 + 102..106 '5000': i32 + 112..117 'false': bool + 123..127 'true': bool + 133..197 'r#" ... "#': &str + 203..213 'br#"yolo"#': &[u8; _] + "##]], ); } #[test] fn infer_unary_op() { - assert_snapshot!( - 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"; -} -"#), - @r###" - 26..27 'x': SomeType - 39..271 '{ ...lo"; }': () - 49..50 'b': bool - 53..58 'false': bool - 68..69 'c': bool - 72..74 '!b': bool - 73..74 'b': bool - 84..85 'a': i128 - 88..91 '100': i128 - 101..102 'd': i128 - 111..113 '-a': i128 - 112..113 'a': i128 - 123..124 'e': i32 - 127..131 '-100': i32 - 128..131 '100': i32 - 141..142 'f': bool - 145..152 '!!!true': bool - 146..152 '!!true': bool - 147..152 '!true': bool - 148..152 'true': bool - 162..163 'g': i32 - 166..169 '!42': i32 - 167..169 '42': i32 - 179..180 'h': u32 - 183..189 '!10u32': u32 - 184..189 '10u32': u32 - 199..200 'j': i128 - 203..205 '!a': i128 - 204..205 'a': i128 - 211..216 '-3.14': f64 - 212..216 '3.14': f64 - 222..224 '!3': i32 - 223..224 '3': i32 - 230..232 '-x': {unknown} - 231..232 'x': SomeType - 238..240 '!x': {unknown} - 239..240 'x': SomeType - 246..254 '-"hello"': {unknown} - 247..254 '"hello"': &str - 260..268 '!"hello"': {unknown} - 261..268 '"hello"': &str - "### + 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"; + } + "#, + expect![[r#" + 26..27 'x': SomeType + 39..271 '{ ...lo"; }': () + 49..50 'b': bool + 53..58 'false': bool + 68..69 'c': bool + 72..74 '!b': bool + 73..74 'b': bool + 84..85 'a': i128 + 88..91 '100': i128 + 101..102 'd': i128 + 111..113 '-a': i128 + 112..113 'a': i128 + 123..124 'e': i32 + 127..131 '-100': i32 + 128..131 '100': i32 + 141..142 'f': bool + 145..152 '!!!true': bool + 146..152 '!!true': bool + 147..152 '!true': bool + 148..152 'true': bool + 162..163 'g': i32 + 166..169 '!42': i32 + 167..169 '42': i32 + 179..180 'h': u32 + 183..189 '!10u32': u32 + 184..189 '10u32': u32 + 199..200 'j': i128 + 203..205 '!a': i128 + 204..205 'a': i128 + 211..216 '-3.14': f64 + 212..216 '3.14': f64 + 222..224 '!3': i32 + 223..224 '3': i32 + 230..232 '-x': {unknown} + 231..232 'x': SomeType + 238..240 '!x': {unknown} + 239..240 'x': SomeType + 246..254 '-"hello"': {unknown} + 247..254 '"hello"': &str + 260..268 '!"hello"': {unknown} + 261..268 '"hello"': &str + "#]], ); } #[test] fn infer_backwards() { - assert_snapshot!( - infer(r#" -fn takes_u32(x: u32) {} - -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 -} -"#), - @r###" - 13..14 'x': u32 - 21..23 '{}': () - 77..230 '{ ...t &c }': &mut &f64 - 87..88 'a': u32 - 91..107 'unknow...nction': {unknown} - 91..109 'unknow...tion()': u32 - 115..124 'takes_u32': fn takes_u32(u32) - 115..127 'takes_u32(a)': () - 125..126 'a': u32 - 137..138 'b': i32 - 141..157 'unknow...nction': {unknown} - 141..159 'unknow...tion()': i32 - 165..183 'S { i3...d: b }': S - 180..181 'b': i32 - 193..194 'c': f64 - 197..213 'unknow...nction': {unknown} - 197..215 'unknow...tion()': f64 - 221..228 '&mut &c': &mut &f64 - 226..228 '&c': &f64 - 227..228 'c': f64 - "### + check_infer( + r#" + fn takes_u32(x: u32) {} + + 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 + } + "#, + expect![[r#" + 13..14 'x': u32 + 21..23 '{}': () + 77..230 '{ ...t &c }': &mut &f64 + 87..88 'a': u32 + 91..107 'unknow...nction': {unknown} + 91..109 'unknow...tion()': u32 + 115..124 'takes_u32': fn takes_u32(u32) + 115..127 'takes_u32(a)': () + 125..126 'a': u32 + 137..138 'b': i32 + 141..157 'unknow...nction': {unknown} + 141..159 'unknow...tion()': i32 + 165..183 'S { i3...d: b }': S + 180..181 'b': i32 + 193..194 'c': f64 + 197..213 'unknow...nction': {unknown} + 197..215 'unknow...tion()': f64 + 221..228 '&mut &c': &mut &f64 + 226..228 '&c': &f64 + 227..228 'c': f64 + "#]], ); } #[test] fn infer_self() { - assert_snapshot!( - infer(r#" -struct S; + check_infer( + r#" + struct S; -impl S { - fn test(&self) { - self; - } - fn test2(self: &Self) { - self; - } - fn test3() -> Self { - S {} - } - fn test4() -> Self { - Self {} - } -} -"#), - @r###" - 33..37 'self': &S - 39..60 '{ ... }': () - 49..53 'self': &S - 74..78 'self': &S - 87..108 '{ ... }': () - 97..101 'self': &S - 132..152 '{ ... }': S - 142..146 'S {}': S - 176..199 '{ ... }': S - 186..193 'Self {}': S - "### + 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 '{ ... }': () + 49..53 'self': &S + 74..78 'self': &S + 87..108 '{ ... }': () + 97..101 'self': &S + 132..152 '{ ... }': S + 142..146 'S {}': S + 176..199 '{ ... }': S + 186..193 'Self {}': S + "#]], ); } #[test] fn infer_self_as_path() { - assert_snapshot!( - infer(r#" -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); - } -} -"#), - @r###" - 86..107 '{ ... }': () - 96..100 'Self': S1 - 134..158 '{ ... }': () - 144..148 'Self': S2(isize) -> S2 - 144..151 'Self(1)': S2 - 149..150 '1': isize - 184..230 '{ ... }': () - 194..202 'Self::V1': E - 212..220 'Self::V2': V2(u32) -> E - 212..223 'Self::V2(1)': E - 221..222 '1': u32 - "### + check_infer( + r#" + 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); + } + } + "#, + expect![[r#" + 86..107 '{ ... }': () + 96..100 'Self': S1 + 134..158 '{ ... }': () + 144..148 'Self': S2(isize) -> S2 + 144..151 'Self(1)': S2 + 149..150 '1': isize + 184..230 '{ ... }': () + 194..202 'Self::V1': E + 212..220 'Self::V2': V2(u32) -> E + 212..223 'Self::V2(1)': E + 221..222 '1': u32 + "#]], ); } #[test] fn infer_binary_op() { - assert_snapshot!( - infer(r#" -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 -} -"#), - @r###" - 5..6 'x': bool - 21..33 '{ 0i32 }': i32 - 27..31 '0i32': i32 - 53..369 '{ ... < 3 }': bool - 63..64 'x': bool - 67..68 'a': bool - 67..73 'a && b': bool - 72..73 'b': bool - 83..84 'y': bool - 87..91 'true': bool - 87..100 'true || false': bool - 95..100 'false': bool - 110..111 'z': bool - 114..115 'x': bool - 114..120 'x == y': bool - 119..120 'y': bool - 130..131 't': bool - 134..135 'x': bool - 134..140 'x != y': bool - 139..140 'y': bool - 150..161 'minus_forty': isize - 171..179 '-40isize': isize - 172..179 '40isize': isize - 189..190 'h': bool - 193..204 'minus_forty': isize - 193..215 'minus_...ONST_2': bool - 208..215 'CONST_2': isize - 225..226 'c': i32 - 229..230 'f': fn f(bool) -> i32 - 229..238 'f(z || y)': i32 - 229..242 'f(z || y) + 5': i32 - 231..232 'z': bool - 231..237 'z || y': bool - 236..237 'y': bool - 241..242 '5': i32 - 252..253 'd': {unknown} - 256..257 'b': {unknown} - 267..268 'g': () - 271..282 'minus_forty': isize - 271..287 'minus_...y ^= i': () - 286..287 'i': isize - 297..300 'ten': usize - 310..312 '10': usize - 322..335 'ten_is_eleven': bool - 338..341 'ten': usize - 338..353 'ten == some_num': bool - 345..353 'some_num': usize - 360..363 'ten': usize - 360..367 'ten < 3': bool - 366..367 '3': usize - "### + check_infer( + r#" + 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 + } + "#, + expect![[r#" + 5..6 'x': bool + 21..33 '{ 0i32 }': i32 + 27..31 '0i32': i32 + 53..369 '{ ... < 3 }': bool + 63..64 'x': bool + 67..68 'a': bool + 67..73 'a && b': bool + 72..73 'b': bool + 83..84 'y': bool + 87..91 'true': bool + 87..100 'true || false': bool + 95..100 'false': bool + 110..111 'z': bool + 114..115 'x': bool + 114..120 'x == y': bool + 119..120 'y': bool + 130..131 't': bool + 134..135 'x': bool + 134..140 'x != y': bool + 139..140 'y': bool + 150..161 'minus_forty': isize + 171..179 '-40isize': isize + 172..179 '40isize': isize + 189..190 'h': bool + 193..204 'minus_forty': isize + 193..215 'minus_...ONST_2': bool + 208..215 'CONST_2': isize + 225..226 'c': i32 + 229..230 'f': fn f(bool) -> i32 + 229..238 'f(z || y)': i32 + 229..242 'f(z || y) + 5': i32 + 231..232 'z': bool + 231..237 'z || y': bool + 236..237 'y': bool + 241..242 '5': i32 + 252..253 'd': {unknown} + 256..257 'b': {unknown} + 267..268 'g': () + 271..282 'minus_forty': isize + 271..287 'minus_...y ^= i': () + 286..287 'i': isize + 297..300 'ten': usize + 310..312 '10': usize + 322..335 'ten_is_eleven': bool + 338..341 'ten': usize + 338..353 'ten == some_num': bool + 345..353 'some_num': usize + 360..363 'ten': usize + 360..367 'ten < 3': bool + 366..367 '3': usize + "#]], ); } #[test] fn infer_shift_op() { - assert_snapshot!( - infer(r#" -fn test() { - 1u32 << 5u8; - 1u32 >> 5u8; -} -"#), - @r###" - 10..47 '{ ...5u8; }': () - 16..20 '1u32': u32 - 16..27 '1u32 << 5u8': u32 - 24..27 '5u8': u8 - 33..37 '1u32': u32 - 33..44 '1u32 >> 5u8': u32 - 41..44 '5u8': u8 - "### + check_infer( + r#" + fn test() { + 1u32 << 5u8; + 1u32 >> 5u8; + } + "#, + expect![[r#" + 10..47 '{ ...5u8; }': () + 16..20 '1u32': u32 + 16..27 '1u32 << 5u8': u32 + 24..27 '5u8': u8 + 33..37 '1u32': u32 + 33..44 '1u32 >> 5u8': u32 + 41..44 '5u8': u8 + "#]], ); } #[test] fn infer_field_autoderef() { - assert_snapshot!( - 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; -} - -fn test2(a1: *const A, a2: *mut A) { - a1.b; - a2.b; -} -"#), - @r###" - 43..44 'a': A - 49..212 '{ ...5.b; }': () - 59..61 'a1': A - 64..65 'a': A - 71..73 'a1': A - 71..75 'a1.b': B - 85..87 'a2': &A - 90..92 '&a': &A - 91..92 'a': A - 98..100 'a2': &A - 98..102 'a2.b': B - 112..114 'a3': &mut A - 117..123 '&mut a': &mut A - 122..123 'a': A - 129..131 'a3': &mut A - 129..133 'a3.b': B - 143..145 'a4': &&&&&&&A - 148..156 '&&&&&&&a': &&&&&&&A - 149..156 '&&&&&&a': &&&&&&A - 150..156 '&&&&&a': &&&&&A - 151..156 '&&&&a': &&&&A - 152..156 '&&&a': &&&A - 153..156 '&&a': &&A - 154..156 '&a': &A - 155..156 'a': A - 162..164 'a4': &&&&&&&A - 162..166 'a4.b': B - 176..178 'a5': &mut &&mut &&mut A - 181..199 '&mut &...&mut a': &mut &&mut &&mut A - 186..199 '&&mut &&mut a': &&mut &&mut A - 187..199 '&mut &&mut a': &mut &&mut A - 192..199 '&&mut a': &&mut A - 193..199 '&mut a': &mut A - 198..199 'a': A - 205..207 'a5': &mut &&mut &&mut A - 205..209 'a5.b': B - 223..225 'a1': *const A - 237..239 'a2': *mut A - 249..272 '{ ...2.b; }': () - 255..257 'a1': *const A - 255..259 'a1.b': B - 265..267 'a2': *mut A - 265..269 'a2.b': B - "### + 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; + } + + fn test2(a1: *const A, a2: *mut A) { + a1.b; + a2.b; + } + "#, + expect![[r#" + 43..44 'a': A + 49..212 '{ ...5.b; }': () + 59..61 'a1': A + 64..65 'a': A + 71..73 'a1': A + 71..75 'a1.b': B + 85..87 'a2': &A + 90..92 '&a': &A + 91..92 'a': A + 98..100 'a2': &A + 98..102 'a2.b': B + 112..114 'a3': &mut A + 117..123 '&mut a': &mut A + 122..123 'a': A + 129..131 'a3': &mut A + 129..133 'a3.b': B + 143..145 'a4': &&&&&&&A + 148..156 '&&&&&&&a': &&&&&&&A + 149..156 '&&&&&&a': &&&&&&A + 150..156 '&&&&&a': &&&&&A + 151..156 '&&&&a': &&&&A + 152..156 '&&&a': &&&A + 153..156 '&&a': &&A + 154..156 '&a': &A + 155..156 'a': A + 162..164 'a4': &&&&&&&A + 162..166 'a4.b': B + 176..178 'a5': &mut &&mut &&mut A + 181..199 '&mut &...&mut a': &mut &&mut &&mut A + 186..199 '&&mut &&mut a': &&mut &&mut A + 187..199 '&mut &&mut a': &mut &&mut A + 192..199 '&&mut a': &&mut A + 193..199 '&mut a': &mut A + 198..199 'a': A + 205..207 'a5': &mut &&mut &&mut A + 205..209 'a5.b': B + 223..225 'a1': *const A + 237..239 'a2': *mut A + 249..272 '{ ...2.b; }': () + 255..257 'a1': *const A + 255..259 'a1.b': B + 265..267 'a2': *mut A + 265..269 'a2.b': B + "#]], ); } #[test] fn infer_argument_autoderef() { - assert_snapshot!( - infer(r#" -#[lang = "deref"] -pub trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} + check_infer( + r#" + #[lang = "deref"] + pub trait Deref { + type Target; + fn deref(&self) -> &Self::Target; + } -struct A(T); + struct A(T); -impl A { - fn foo(&self) -> &T { - &self.0 - } -} + impl A { + fn foo(&self) -> &T { + &self.0 + } + } -struct B(T); + struct B(T); -impl Deref for B { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } -} + impl Deref for B { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } -fn test() { - let t = A::foo(&&B(B(A(42)))); -} -"#), - @r###" - 67..71 'self': &Self - 138..142 'self': &A - 150..173 '{ ... }': &T - 160..167 '&self.0': &T - 161..165 'self': &A - 161..167 'self.0': T - 254..258 'self': &B - 277..300 '{ ... }': &T - 287..294 '&self.0': &T - 288..292 'self': &B - 288..294 'self.0': T - 314..352 '{ ...))); }': () - 324..325 't': &i32 - 328..334 'A::foo': fn foo(&A) -> &i32 - 328..349 'A::foo...42))))': &i32 - 335..348 '&&B(B(A(42)))': &&B>> - 336..348 '&B(B(A(42)))': &B>> - 337..338 'B': B>>(B>) -> B>> - 337..348 'B(B(A(42)))': B>> - 339..340 'B': B>(A) -> B> - 339..347 'B(A(42))': B> - 341..342 'A': A(i32) -> A - 341..346 'A(42)': A - 343..345 '42': i32 - "### + fn test() { + let t = A::foo(&&B(B(A(42)))); + } + "#, + expect![[r#" + 67..71 'self': &Self + 138..142 'self': &A + 150..173 '{ ... }': &T + 160..167 '&self.0': &T + 161..165 'self': &A + 161..167 'self.0': T + 254..258 'self': &B + 277..300 '{ ... }': &T + 287..294 '&self.0': &T + 288..292 'self': &B + 288..294 'self.0': T + 314..352 '{ ...))); }': () + 324..325 't': &i32 + 328..334 'A::foo': fn foo(&A) -> &i32 + 328..349 'A::foo...42))))': &i32 + 335..348 '&&B(B(A(42)))': &&B>> + 336..348 '&B(B(A(42)))': &B>> + 337..338 'B': B>>(B>) -> B>> + 337..348 'B(B(A(42)))': B>> + 339..340 'B': B>(A) -> B> + 339..347 'B(A(42))': B> + 341..342 'A': A(i32) -> A + 341..346 'A(42)': A + 343..345 '42': i32 + "#]], ); } #[test] fn infer_method_argument_autoderef() { - assert_snapshot!( - infer(r#" -#[lang = "deref"] -pub trait Deref { - type Target; - fn deref(&self) -> &Self::Target; -} + check_infer( + r#" + #[lang = "deref"] + pub trait Deref { + type Target; + fn deref(&self) -> &Self::Target; + } -struct A(*mut T); + struct A(*mut T); -impl A { - fn foo(&self, x: &A) -> &T { - &*x.0 - } -} + impl A { + fn foo(&self, x: &A) -> &T { + &*x.0 + } + } -struct B(T); + struct B(T); -impl Deref for B { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } -} + impl Deref for B { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } + } -fn test(a: A) { - let t = A(0 as *mut _).foo(&&B(B(a))); -} -"#), - @r###" - 67..71 'self': &Self - 143..147 'self': &A - 149..150 'x': &A - 165..186 '{ ... }': &T - 175..180 '&*x.0': &T - 176..180 '*x.0': T - 177..178 'x': &A - 177..180 'x.0': *mut T - 267..271 'self': &B - 290..313 '{ ... }': &T - 300..307 '&self.0': &T - 301..305 'self': &B - 301..307 'self.0': T - 325..326 'a': A - 336..382 '{ ...))); }': () - 346..347 't': &i32 - 350..351 'A': A(*mut i32) -> A - 350..364 'A(0 as *mut _)': A - 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>> - 370..378 '&B(B(a))': &B>> - 371..372 'B': B>>(B>) -> B>> - 371..378 'B(B(a))': B>> - 373..374 'B': B>(A) -> B> - 373..377 'B(a)': B> - 375..376 'a': A - "### + fn test(a: A) { + let t = A(0 as *mut _).foo(&&B(B(a))); + } + "#, + expect![[r#" + 67..71 'self': &Self + 143..147 'self': &A + 149..150 'x': &A + 165..186 '{ ... }': &T + 175..180 '&*x.0': &T + 176..180 '*x.0': T + 177..178 'x': &A + 177..180 'x.0': *mut T + 267..271 'self': &B + 290..313 '{ ... }': &T + 300..307 '&self.0': &T + 301..305 'self': &B + 301..307 'self.0': T + 325..326 'a': A + 336..382 '{ ...))); }': () + 346..347 't': &i32 + 350..351 'A': A(*mut i32) -> A + 350..364 'A(0 as *mut _)': A + 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>> + 370..378 '&B(B(a))': &B>> + 371..372 'B': B>>(B>) -> B>> + 371..378 'B(B(a))': B>> + 373..374 'B': B>(A) -> B> + 373..377 'B(a)': B> + 375..376 'a': A + "#]], ); } #[test] fn infer_in_elseif() { - assert_snapshot!( - infer(r#" -struct Foo { field: i32 } -fn main(foo: Foo) { - if true { - - } else if false { - foo.field - } -} -"#), - @r###" - 34..37 'foo': Foo - 44..108 '{ ... } }': () - 50..106 'if tru... }': () - 53..57 'true': bool - 58..66 '{ }': () - 72..106 'if fal... }': i32 - 75..80 'false': bool - 81..106 '{ ... }': i32 - 91..94 'foo': Foo - 91..100 'foo.field': i32 - "### + check_infer( + r#" + struct Foo { field: i32 } + fn main(foo: Foo) { + if true { + + } else if false { + foo.field + } + } + "#, + expect![[r#" + 34..37 'foo': Foo + 44..108 '{ ... } }': () + 50..106 'if tru... }': () + 53..57 'true': bool + 58..66 '{ }': () + 72..106 'if fal... }': i32 + 75..80 'false': bool + 81..106 '{ ... }': i32 + 91..94 'foo': Foo + 91..100 'foo.field': i32 + "#]], ) } #[test] fn infer_if_match_with_return() { - assert_snapshot!( - 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 - }; -}"#), - @r###" - 9..322 '{ ... }; }': () - 19..22 '_x1': i32 - 25..79 'if tru... }': i32 - 28..32 'true': bool - 33..50 '{ ... }': i32 - 43..44 '1': i32 - 56..79 '{ ... }': i32 - 66..72 'return': ! - 89..92 '_x2': i32 - 95..148 'if tru... }': i32 - 98..102 'true': bool - 103..120 '{ ... }': i32 - 113..114 '2': i32 - 126..148 '{ ... }': ! - 136..142 'return': ! - 158..161 '_x3': i32 - 164..246 'match ... }': i32 - 170..174 'true': bool - 185..189 'true': bool - 185..189 'true': bool - 193..194 '3': i32 - 204..205 '_': bool - 209..240 '{ ... }': i32 - 223..229 'return': ! - 256..259 '_x4': i32 - 262..319 'match ... }': i32 - 268..272 'true': bool - 283..287 'true': bool - 283..287 'true': bool - 291..292 '4': i32 - 302..303 '_': bool - 307..313 '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 + }; + }"#, + expect![[r#" + 9..322 '{ ... }; }': () + 19..22 '_x1': i32 + 25..79 'if tru... }': i32 + 28..32 'true': bool + 33..50 '{ ... }': i32 + 43..44 '1': i32 + 56..79 '{ ... }': i32 + 66..72 'return': ! + 89..92 '_x2': i32 + 95..148 'if tru... }': i32 + 98..102 'true': bool + 103..120 '{ ... }': i32 + 113..114 '2': i32 + 126..148 '{ ... }': ! + 136..142 'return': ! + 158..161 '_x3': i32 + 164..246 'match ... }': i32 + 170..174 'true': bool + 185..189 'true': bool + 185..189 'true': bool + 193..194 '3': i32 + 204..205 '_': bool + 209..240 '{ ... }': i32 + 223..229 'return': ! + 256..259 '_x4': i32 + 262..319 'match ... }': i32 + 268..272 'true': bool + 283..287 'true': bool + 283..287 'true': bool + 291..292 '4': i32 + 302..303 '_': bool + 307..313 'return': ! + "#]], ) } #[test] fn infer_inherent_method() { - assert_snapshot!( - infer(r#" -struct A; + check_infer( + r#" + struct A; -impl A { - fn foo(self, x: u32) -> i32 {} -} + impl A { + fn foo(self, x: u32) -> i32 {} + } -mod b { - impl super::A { - fn bar(&self, x: u64) -> i64 {} - } -} + mod b { + impl super::A { + fn bar(&self, x: u64) -> i64 {} + } + } -fn test(a: A) { - a.foo(1); - (&a).bar(1); - a.bar(1); -} -"#), - @r###" - 31..35 'self': A - 37..38 'x': u32 - 52..54 '{}': () - 102..106 'self': &A - 108..109 'x': u64 - 123..125 '{}': () - 143..144 'a': A - 149..197 '{ ...(1); }': () - 155..156 'a': A - 155..163 'a.foo(1)': i32 - 161..162 '1': u32 - 169..180 '(&a).bar(1)': i64 - 170..172 '&a': &A - 171..172 'a': A - 178..179 '1': u64 - 186..187 'a': A - 186..194 'a.bar(1)': i64 - 192..193 '1': u64 - "### + fn test(a: A) { + a.foo(1); + (&a).bar(1); + a.bar(1); + } + "#, + expect![[r#" + 31..35 'self': A + 37..38 'x': u32 + 52..54 '{}': () + 102..106 'self': &A + 108..109 'x': u64 + 123..125 '{}': () + 143..144 'a': A + 149..197 '{ ...(1); }': () + 155..156 'a': A + 155..163 'a.foo(1)': i32 + 161..162 '1': u32 + 169..180 '(&a).bar(1)': i64 + 170..172 '&a': &A + 171..172 'a': A + 178..179 '1': u64 + 186..187 'a': A + 186..194 'a.bar(1)': i64 + 192..193 '1': u64 + "#]], ); } #[test] fn infer_inherent_method_str() { - assert_snapshot!( - infer(r#" -#[lang = "str"] -impl str { - fn foo(&self) -> i32 {} -} + check_infer( + r#" + #[lang = "str"] + impl str { + fn foo(&self) -> i32 {} + } -fn test() { - "foo".foo(); -} -"#), - @r###" - 39..43 'self': &str - 52..54 '{}': () - 68..88 '{ ...o(); }': () - 74..79 '"foo"': &str - 74..85 '"foo".foo()': i32 - "### + fn test() { + "foo".foo(); + } + "#, + expect![[r#" + 39..43 'self': &str + 52..54 '{}': () + 68..88 '{ ...o(); }': () + 74..79 '"foo"': &str + 74..85 '"foo".foo()': i32 + "#]], ); } #[test] fn infer_tuple() { - assert_snapshot!( - infer(r#" -fn test(x: &str, y: isize) { - let a: (u32, &str) = (1, "a"); - let b = (a, x); - let c = (y, x); - let d = (c, x); - let e = (1, "e"); - let f = (e, "d"); -} -"#), - @r###" - 8..9 'x': &str - 17..18 'y': isize - 27..169 '{ ...d"); }': () - 37..38 'a': (u32, &str) - 54..62 '(1, "a")': (u32, &str) - 55..56 '1': u32 - 58..61 '"a"': &str - 72..73 'b': ((u32, &str), &str) - 76..82 '(a, x)': ((u32, &str), &str) - 77..78 'a': (u32, &str) - 80..81 'x': &str - 92..93 'c': (isize, &str) - 96..102 '(y, x)': (isize, &str) - 97..98 'y': isize - 100..101 'x': &str - 112..113 'd': ((isize, &str), &str) - 116..122 '(c, x)': ((isize, &str), &str) - 117..118 'c': (isize, &str) - 120..121 'x': &str - 132..133 'e': (i32, &str) - 136..144 '(1, "e")': (i32, &str) - 137..138 '1': i32 - 140..143 '"e"': &str - 154..155 'f': ((i32, &str), &str) - 158..166 '(e, "d")': ((i32, &str), &str) - 159..160 'e': (i32, &str) - 162..165 '"d"': &str - "### + check_infer( + r#" + fn test(x: &str, y: isize) { + let a: (u32, &str) = (1, "a"); + let b = (a, x); + let c = (y, x); + let d = (c, x); + let e = (1, "e"); + let f = (e, "d"); + } + "#, + expect![[r#" + 8..9 'x': &str + 17..18 'y': isize + 27..169 '{ ...d"); }': () + 37..38 'a': (u32, &str) + 54..62 '(1, "a")': (u32, &str) + 55..56 '1': u32 + 58..61 '"a"': &str + 72..73 'b': ((u32, &str), &str) + 76..82 '(a, x)': ((u32, &str), &str) + 77..78 'a': (u32, &str) + 80..81 'x': &str + 92..93 'c': (isize, &str) + 96..102 '(y, x)': (isize, &str) + 97..98 'y': isize + 100..101 'x': &str + 112..113 'd': ((isize, &str), &str) + 116..122 '(c, x)': ((isize, &str), &str) + 117..118 'c': (isize, &str) + 120..121 'x': &str + 132..133 'e': (i32, &str) + 136..144 '(1, "e")': (i32, &str) + 137..138 '1': i32 + 140..143 '"e"': &str + 154..155 'f': ((i32, &str), &str) + 158..166 '(e, "d")': ((i32, &str), &str) + 159..160 'e': (i32, &str) + 162..165 '"d"': &str + "#]], ); } #[test] fn infer_array() { - assert_snapshot!( - infer(r#" -fn test(x: &str, y: isize) { - let a = [x]; - let b = [a, a]; - let c = [b, b]; - - let d = [y, 1, 2, 3]; - let d = [1, y, 2, 3]; - let e = [y]; - let f = [d, d]; - let g = [e, e]; - - let h = [1, 2]; - let i = ["a", "b"]; - - let b = [a, ["b"]]; - let x: [u8; 0] = []; -} -"#), - @r###" - 8..9 'x': &str - 17..18 'y': isize - 27..292 '{ ... []; }': () - 37..38 'a': [&str; _] - 41..44 '[x]': [&str; _] - 42..43 'x': &str - 54..55 'b': [[&str; _]; _] - 58..64 '[a, a]': [[&str; _]; _] - 59..60 'a': [&str; _] - 62..63 'a': [&str; _] - 74..75 'c': [[[&str; _]; _]; _] - 78..84 '[b, b]': [[[&str; _]; _]; _] - 79..80 'b': [[&str; _]; _] - 82..83 'b': [[&str; _]; _] - 95..96 'd': [isize; _] - 99..111 '[y, 1, 2, 3]': [isize; _] - 100..101 'y': isize - 103..104 '1': isize - 106..107 '2': isize - 109..110 '3': isize - 121..122 'd': [isize; _] - 125..137 '[1, y, 2, 3]': [isize; _] - 126..127 '1': isize - 129..130 'y': isize - 132..133 '2': isize - 135..136 '3': isize - 147..148 'e': [isize; _] - 151..154 '[y]': [isize; _] - 152..153 'y': isize - 164..165 'f': [[isize; _]; _] - 168..174 '[d, d]': [[isize; _]; _] - 169..170 'd': [isize; _] - 172..173 'd': [isize; _] - 184..185 'g': [[isize; _]; _] - 188..194 '[e, e]': [[isize; _]; _] - 189..190 'e': [isize; _] - 192..193 'e': [isize; _] - 205..206 'h': [i32; _] - 209..215 '[1, 2]': [i32; _] - 210..211 '1': i32 - 213..214 '2': i32 - 225..226 'i': [&str; _] - 229..239 '["a", "b"]': [&str; _] - 230..233 '"a"': &str - 235..238 '"b"': &str - 250..251 'b': [[&str; _]; _] - 254..264 '[a, ["b"]]': [[&str; _]; _] - 255..256 'a': [&str; _] - 258..263 '["b"]': [&str; _] - 259..262 '"b"': &str - 274..275 'x': [u8; _] - 287..289 '[]': [u8; _] - "### + check_infer( + r#" + fn test(x: &str, y: isize) { + let a = [x]; + let b = [a, a]; + let c = [b, b]; + + let d = [y, 1, 2, 3]; + let d = [1, y, 2, 3]; + let e = [y]; + let f = [d, d]; + let g = [e, e]; + + let h = [1, 2]; + let i = ["a", "b"]; + + let b = [a, ["b"]]; + let x: [u8; 0] = []; + } + "#, + expect![[r#" + 8..9 'x': &str + 17..18 'y': isize + 27..292 '{ ... []; }': () + 37..38 'a': [&str; _] + 41..44 '[x]': [&str; _] + 42..43 'x': &str + 54..55 'b': [[&str; _]; _] + 58..64 '[a, a]': [[&str; _]; _] + 59..60 'a': [&str; _] + 62..63 'a': [&str; _] + 74..75 'c': [[[&str; _]; _]; _] + 78..84 '[b, b]': [[[&str; _]; _]; _] + 79..80 'b': [[&str; _]; _] + 82..83 'b': [[&str; _]; _] + 95..96 'd': [isize; _] + 99..111 '[y, 1, 2, 3]': [isize; _] + 100..101 'y': isize + 103..104 '1': isize + 106..107 '2': isize + 109..110 '3': isize + 121..122 'd': [isize; _] + 125..137 '[1, y, 2, 3]': [isize; _] + 126..127 '1': isize + 129..130 'y': isize + 132..133 '2': isize + 135..136 '3': isize + 147..148 'e': [isize; _] + 151..154 '[y]': [isize; _] + 152..153 'y': isize + 164..165 'f': [[isize; _]; _] + 168..174 '[d, d]': [[isize; _]; _] + 169..170 'd': [isize; _] + 172..173 'd': [isize; _] + 184..185 'g': [[isize; _]; _] + 188..194 '[e, e]': [[isize; _]; _] + 189..190 'e': [isize; _] + 192..193 'e': [isize; _] + 205..206 'h': [i32; _] + 209..215 '[1, 2]': [i32; _] + 210..211 '1': i32 + 213..214 '2': i32 + 225..226 'i': [&str; _] + 229..239 '["a", "b"]': [&str; _] + 230..233 '"a"': &str + 235..238 '"b"': &str + 250..251 'b': [[&str; _]; _] + 254..264 '[a, ["b"]]': [[&str; _]; _] + 255..256 'a': [&str; _] + 258..263 '["b"]': [&str; _] + 259..262 '"b"': &str + 274..275 'x': [u8; _] + 287..289 '[]': [u8; _] + "#]], ); } #[test] fn infer_struct_generics() { - assert_snapshot!( - infer(r#" -struct A { - x: T, -} - -fn test(a1: A, i: i32) { - a1.x; - let a2 = A { x: i }; - a2.x; - let a3 = A:: { x: 1 }; - a3.x; -} -"#), - @r###" - 35..37 'a1': A - 47..48 'i': i32 - 55..146 '{ ...3.x; }': () - 61..63 'a1': A - 61..65 'a1.x': u32 - 75..77 'a2': A - 80..90 'A { x: i }': A - 87..88 'i': i32 - 96..98 'a2': A - 96..100 'a2.x': i32 - 110..112 'a3': A - 115..133 'A:: - 130..131 '1': i128 - 139..141 'a3': A - 139..143 'a3.x': i128 - "### + check_infer( + r#" + struct A { + x: T, + } + + fn test(a1: A, i: i32) { + a1.x; + let a2 = A { x: i }; + a2.x; + let a3 = A:: { x: 1 }; + a3.x; + } + "#, + expect![[r#" + 35..37 'a1': A + 47..48 'i': i32 + 55..146 '{ ...3.x; }': () + 61..63 'a1': A + 61..65 'a1.x': u32 + 75..77 'a2': A + 80..90 'A { x: i }': A + 87..88 'i': i32 + 96..98 'a2': A + 96..100 'a2.x': i32 + 110..112 'a3': A + 115..133 'A:: + 130..131 '1': i128 + 139..141 'a3': A + 139..143 'a3.x': i128 + "#]], ); } #[test] fn infer_tuple_struct_generics() { - assert_snapshot!( - infer(r#" -struct A(T); -enum Option { Some(T), None } -use Option::*; - -fn test() { - A(42); - A(42u128); - Some("x"); - Option::Some("x"); - None; - let x: Option = None; -} -"#), - @r###" - 75..183 '{ ...one; }': () - 81..82 'A': A(i32) -> A - 81..86 'A(42)': A - 83..85 '42': i32 - 92..93 'A': A(u128) -> A - 92..101 'A(42u128)': A - 94..100 '42u128': u128 - 107..111 'Some': Some<&str>(&str) -> Option<&str> - 107..116 'Some("x")': Option<&str> - 112..115 '"x"': &str - 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> - 122..139 'Option...e("x")': Option<&str> - 135..138 '"x"': &str - 145..149 'None': Option<{unknown}> - 159..160 'x': Option - 176..180 'None': Option - "### + check_infer( + r#" + struct A(T); + enum Option { Some(T), None } + use Option::*; + + fn test() { + A(42); + A(42u128); + Some("x"); + Option::Some("x"); + None; + let x: Option = None; + } + "#, + expect![[r#" + 75..183 '{ ...one; }': () + 81..82 'A': A(i32) -> A + 81..86 'A(42)': A + 83..85 '42': i32 + 92..93 'A': A(u128) -> A + 92..101 'A(42u128)': A + 94..100 '42u128': u128 + 107..111 'Some': Some<&str>(&str) -> Option<&str> + 107..116 'Some("x")': Option<&str> + 112..115 '"x"': &str + 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> + 122..139 'Option...e("x")': Option<&str> + 135..138 '"x"': &str + 145..149 'None': Option<{unknown}> + 159..160 'x': Option + 176..180 'None': Option + "#]], ); } #[test] fn infer_function_generics() { - assert_snapshot!( - infer(r#" -fn id(t: T) -> T { t } + check_infer( + r#" + fn id(t: T) -> T { t } -fn test() { - id(1u32); - id::(1); - let x: u64 = id(1); -} -"#), - @r###" - 9..10 't': T - 20..25 '{ t }': T - 22..23 't': T - 37..97 '{ ...(1); }': () - 43..45 'id': fn id(u32) -> u32 - 43..51 'id(1u32)': u32 - 46..50 '1u32': u32 - 57..67 'id::': fn id(i128) -> i128 - 57..70 'id::(1)': i128 - 68..69 '1': i128 - 80..81 'x': u64 - 89..91 'id': fn id(u64) -> u64 - 89..94 'id(1)': u64 - 92..93 '1': u64 - "### + fn test() { + id(1u32); + id::(1); + let x: u64 = id(1); + } + "#, + expect![[r#" + 9..10 't': T + 20..25 '{ t }': T + 22..23 't': T + 37..97 '{ ...(1); }': () + 43..45 'id': fn id(u32) -> u32 + 43..51 'id(1u32)': u32 + 46..50 '1u32': u32 + 57..67 'id::': fn id(i128) -> i128 + 57..70 'id::(1)': i128 + 68..69 '1': i128 + 80..81 'x': u64 + 89..91 'id': fn id(u64) -> u64 + 89..94 'id(1)': u64 + 92..93 '1': u64 + "#]], ); } #[test] fn infer_impl_generics_basic() { - assert_snapshot!( - infer(r#" -struct A { - x: T1, - y: T2, -} -impl A { - fn x(self) -> X { - self.x - } - fn y(self) -> Y { - self.y - } - fn z(self, t: T) -> (X, Y, T) { - (self.x, self.y, t) - } -} + check_infer( + r#" + struct A { + x: T1, + y: T2, + } + impl A { + fn x(self) -> X { + self.x + } + fn y(self) -> Y { + self.y + } + fn z(self, t: T) -> (X, Y, T) { + (self.x, self.y, t) + } + } -fn test() -> i128 { - let a = A { x: 1u64, y: 1i64 }; - a.x(); - a.y(); - a.z(1i128); - a.z::(1); -} -"#), - @r###" - 73..77 'self': A - 84..106 '{ ... }': X - 94..98 'self': A - 94..100 'self.x': X - 116..120 'self': A - 127..149 '{ ... }': Y - 137..141 'self': A - 137..143 'self.y': Y - 162..166 'self': A - 168..169 't': T - 187..222 '{ ... }': (X, Y, T) - 197..216 '(self.....y, t)': (X, Y, T) - 198..202 'self': A - 198..204 'self.x': X - 206..210 'self': A - 206..212 'self.y': Y - 214..215 't': T - 244..341 '{ ...(1); }': () - 254..255 'a': A - 258..280 'A { x:...1i64 }': A - 265..269 '1u64': u64 - 274..278 '1i64': i64 - 286..287 'a': A - 286..291 'a.x()': u64 - 297..298 'a': A - 297..302 'a.y()': i64 - 308..309 'a': A - 308..318 'a.z(1i128)': (u64, i64, i128) - 312..317 '1i128': i128 - 324..325 'a': A - 324..338 'a.z::(1)': (u64, i64, u128) - 336..337 '1': u128 - "### + fn test() -> i128 { + let a = A { x: 1u64, y: 1i64 }; + a.x(); + a.y(); + a.z(1i128); + a.z::(1); + } + "#, + expect![[r#" + 73..77 'self': A + 84..106 '{ ... }': X + 94..98 'self': A + 94..100 'self.x': X + 116..120 'self': A + 127..149 '{ ... }': Y + 137..141 'self': A + 137..143 'self.y': Y + 162..166 'self': A + 168..169 't': T + 187..222 '{ ... }': (X, Y, T) + 197..216 '(self.....y, t)': (X, Y, T) + 198..202 'self': A + 198..204 'self.x': X + 206..210 'self': A + 206..212 'self.y': Y + 214..215 't': T + 244..341 '{ ...(1); }': () + 254..255 'a': A + 258..280 'A { x:...1i64 }': A + 265..269 '1u64': u64 + 274..278 '1i64': i64 + 286..287 'a': A + 286..291 'a.x()': u64 + 297..298 'a': A + 297..302 'a.y()': i64 + 308..309 'a': A + 308..318 'a.z(1i128)': (u64, i64, i128) + 312..317 '1i128': i128 + 324..325 'a': A + 324..338 'a.z::(1)': (u64, i64, u128) + 336..337 '1': u128 + "#]], ); } #[test] fn infer_impl_generics_with_autoderef() { - assert_snapshot!( - infer(r#" -enum Option { - Some(T), - None, -} -impl Option { - fn as_ref(&self) -> Option<&T> {} -} -fn test(o: Option) { - (&o).as_ref(); - o.as_ref(); -} -"#), - @r###" - 77..81 'self': &Option - 97..99 '{}': () - 110..111 'o': Option - 126..164 '{ ...f(); }': () - 132..145 '(&o).as_ref()': Option<&u32> - 133..135 '&o': &Option - 134..135 'o': Option - 151..152 'o': Option - 151..161 'o.as_ref()': Option<&u32> - "### + check_infer( + r#" + enum Option { + Some(T), + None, + } + impl Option { + fn as_ref(&self) -> Option<&T> {} + } + fn test(o: Option) { + (&o).as_ref(); + o.as_ref(); + } + "#, + expect![[r#" + 77..81 'self': &Option + 97..99 '{}': () + 110..111 'o': Option + 126..164 '{ ...f(); }': () + 132..145 '(&o).as_ref()': Option<&u32> + 133..135 '&o': &Option + 134..135 'o': Option + 151..152 'o': Option + 151..161 'o.as_ref()': Option<&u32> + "#]], ); } #[test] fn infer_generic_chain() { - assert_snapshot!( - infer(r#" -struct A { - x: T, -} -impl A { - fn x(self) -> T2 { - self.x - } -} -fn id(t: T) -> T { t } - -fn test() -> i128 { - let x = 1; - let y = id(x); - let a = A { x: id(y) }; - let z = id(a.x); - let b = A { x: z }; - b.x() -} -"#), - @r###" - 52..56 'self': A - 64..86 '{ ... }': T2 - 74..78 'self': A - 74..80 'self.x': T2 - 98..99 't': T - 109..114 '{ t }': T - 111..112 't': T - 134..260 '{ ....x() }': i128 - 145..146 'x': i128 - 149..150 '1': i128 - 161..162 'y': i128 - 165..167 'id': fn id(i128) -> i128 - 165..170 'id(x)': i128 - 168..169 'x': i128 - 181..182 'a': A - 185..199 'A { x: id(y) }': A - 192..194 'id': fn id(i128) -> i128 - 192..197 'id(y)': i128 - 195..196 'y': i128 - 210..211 'z': i128 - 214..216 'id': fn id(i128) -> i128 - 214..221 'id(a.x)': i128 - 217..218 'a': A - 217..220 'a.x': i128 - 232..233 'b': A - 236..246 'A { x: z }': A - 243..244 'z': i128 - 253..254 'b': A - 253..258 'b.x()': i128 - "### + check_infer( + r#" + struct A { + x: T, + } + impl A { + fn x(self) -> T2 { + self.x + } + } + fn id(t: T) -> T { t } + + fn test() -> i128 { + let x = 1; + let y = id(x); + let a = A { x: id(y) }; + let z = id(a.x); + let b = A { x: z }; + b.x() + } + "#, + expect![[r#" + 52..56 'self': A + 64..86 '{ ... }': T2 + 74..78 'self': A + 74..80 'self.x': T2 + 98..99 't': T + 109..114 '{ t }': T + 111..112 't': T + 134..254 '{ ....x() }': i128 + 144..145 'x': i128 + 148..149 '1': i128 + 159..160 'y': i128 + 163..165 'id': fn id(i128) -> i128 + 163..168 'id(x)': i128 + 166..167 'x': i128 + 178..179 'a': A + 182..196 'A { x: id(y) }': A + 189..191 'id': fn id(i128) -> i128 + 189..194 'id(y)': i128 + 192..193 'y': i128 + 206..207 'z': i128 + 210..212 'id': fn id(i128) -> i128 + 210..217 'id(a.x)': i128 + 213..214 'a': A + 213..216 'a.x': i128 + 227..228 'b': A + 231..241 'A { x: z }': A + 238..239 'z': i128 + 247..248 'b': A + 247..252 'b.x()': i128 + "#]], ); } #[test] fn infer_associated_const() { - assert_snapshot!( - infer(r#" -struct Struct; + check_infer( + r#" + struct Struct; -impl Struct { - const FOO: u32 = 1; -} + impl Struct { + const FOO: u32 = 1; + } -enum Enum {} + enum Enum {} -impl Enum { - const BAR: u32 = 2; -} + impl Enum { + const BAR: u32 = 2; + } -trait Trait { - const ID: u32; -} + trait Trait { + const ID: u32; + } -struct TraitTest; + struct TraitTest; -impl Trait for TraitTest { - const ID: u32 = 5; -} + impl Trait for TraitTest { + const ID: u32 = 5; + } -fn test() { - let x = Struct::FOO; - let y = Enum::BAR; - let z = TraitTest::ID; -} -"#), - @r###" - 51..52 '1': u32 - 104..105 '2': u32 - 212..213 '5': u32 - 228..306 '{ ...:ID; }': () - 238..239 'x': u32 - 242..253 'Struct::FOO': u32 - 263..264 'y': u32 - 267..276 'Enum::BAR': u32 - 286..287 'z': u32 - 290..303 'TraitTest::ID': u32 - "### + fn test() { + let x = Struct::FOO; + let y = Enum::BAR; + let z = TraitTest::ID; + } + "#, + expect![[r#" + 51..52 '1': u32 + 104..105 '2': u32 + 212..213 '5': u32 + 228..306 '{ ...:ID; }': () + 238..239 'x': u32 + 242..253 'Struct::FOO': u32 + 263..264 'y': u32 + 267..276 'Enum::BAR': u32 + 286..287 'z': u32 + 290..303 'TraitTest::ID': u32 + "#]], ); } #[test] fn infer_type_alias() { - assert_snapshot!( - infer(r#" -struct A { x: X, y: Y } -type Foo = A; -type Bar = A; -type Baz = A; -fn test(x: Foo, y: Bar<&str>, z: Baz) { - x.x; - x.y; - y.x; - y.y; - z.x; - z.y; -} -"#), - @r###" - 115..116 'x': A - 123..124 'y': A<&str, u128> - 137..138 'z': A - 153..210 '{ ...z.y; }': () - 159..160 'x': A - 159..162 'x.x': u32 - 168..169 'x': A - 168..171 'x.y': i128 - 177..178 'y': A<&str, u128> - 177..180 'y.x': &str - 186..187 'y': A<&str, u128> - 186..189 'y.y': u128 - 195..196 'z': A - 195..198 'z.x': u8 - 204..205 'z': A - 204..207 'z.y': i8 - "### + check_infer( + r#" + struct A { x: X, y: Y } + type Foo = A; + type Bar = A; + type Baz = A; + fn test(x: Foo, y: Bar<&str>, z: Baz) { + x.x; + x.y; + y.x; + y.y; + z.x; + z.y; + } + "#, + expect![[r#" + 115..116 'x': A + 123..124 'y': A<&str, u128> + 137..138 'z': A + 153..210 '{ ...z.y; }': () + 159..160 'x': A + 159..162 'x.x': u32 + 168..169 'x': A + 168..171 'x.y': i128 + 177..178 'y': A<&str, u128> + 177..180 'y.x': &str + 186..187 'y': A<&str, u128> + 186..189 'y.y': u128 + 195..196 'z': A + 195..198 'z.x': u8 + 204..205 'z': A + 204..207 'z.y': i8 + "#]], ) } #[test] fn recursive_type_alias() { - assert_snapshot!( - infer(r#" -struct A {} -type Foo = Foo; -type Bar = A; -fn test(x: Foo) {} -"#), - @r###" - 58..59 'x': {unknown} - 66..68 '{}': () - "### + check_infer( + r#" + struct A {} + type Foo = Foo; + type Bar = A; + fn test(x: Foo) {} + "#, + expect![[r#" + 58..59 'x': {unknown} + 66..68 '{}': () + "#]], ) } #[test] fn infer_type_param() { - assert_snapshot!( - infer(r#" -fn id(x: T) -> T { - x -} + check_infer( + r#" + fn id(x: T) -> T { + x + } -fn clone(x: &T) -> T { - *x -} + fn clone(x: &T) -> T { + *x + } -fn test() { - let y = 10u32; - id(y); - let x: bool = clone(z); - id::(1); -} -"#), - @r###" - 9..10 'x': T - 20..29 '{ x }': T - 26..27 'x': T - 43..44 'x': &T - 55..65 '{ *x }': T - 61..63 '*x': T - 62..63 'x': &T - 77..157 '{ ...(1); }': () - 87..88 'y': u32 - 91..96 '10u32': u32 - 102..104 'id': fn id(u32) -> u32 - 102..107 'id(y)': u32 - 105..106 'y': u32 - 117..118 'x': bool - 127..132 'clone': fn clone(&bool) -> bool - 127..135 'clone(z)': bool - 133..134 'z': &bool - 141..151 'id::': fn id(i128) -> i128 - 141..154 'id::(1)': i128 - 152..153 '1': i128 - "### + fn test() { + let y = 10u32; + id(y); + let x: bool = clone(z); + id::(1); + } + "#, + expect![[r#" + 9..10 'x': T + 20..29 '{ x }': T + 26..27 'x': T + 43..44 'x': &T + 55..65 '{ *x }': T + 61..63 '*x': T + 62..63 'x': &T + 77..157 '{ ...(1); }': () + 87..88 'y': u32 + 91..96 '10u32': u32 + 102..104 'id': fn id(u32) -> u32 + 102..107 'id(y)': u32 + 105..106 'y': u32 + 117..118 'x': bool + 127..132 'clone': fn clone(&bool) -> bool + 127..135 'clone(z)': bool + 133..134 'z': &bool + 141..151 'id::': fn id(i128) -> i128 + 141..154 'id::(1)': i128 + 152..153 '1': i128 + "#]], ); } #[test] fn infer_const() { - assert_snapshot!( - infer(r#" -struct Foo; -impl Foo { const ASSOC_CONST: u32 = 0; } -const GLOBAL_CONST: u32 = 101; -fn test() { - const LOCAL_CONST: u32 = 99; - let x = LOCAL_CONST; - let z = GLOBAL_CONST; - let id = Foo::ASSOC_CONST; -} -"#), - @r###" - 48..49 '0': u32 - 79..82 '101': u32 - 94..212 '{ ...NST; }': () - 137..138 'x': u32 - 141..152 'LOCAL_CONST': u32 - 162..163 'z': u32 - 166..178 'GLOBAL_CONST': u32 - 188..190 'id': u32 - 193..209 'Foo::A..._CONST': u32 - 125..127 '99': u32 - "### + check_infer( + r#" + struct Foo; + impl Foo { const ASSOC_CONST: u32 = 0; } + const GLOBAL_CONST: u32 = 101; + fn test() { + const LOCAL_CONST: u32 = 99; + let x = LOCAL_CONST; + let z = GLOBAL_CONST; + let id = Foo::ASSOC_CONST; + } + "#, + expect![[r#" + 48..49 '0': u32 + 79..82 '101': u32 + 94..212 '{ ...NST; }': () + 137..138 'x': u32 + 141..152 'LOCAL_CONST': u32 + 162..163 'z': u32 + 166..178 'GLOBAL_CONST': u32 + 188..190 'id': u32 + 193..209 'Foo::A..._CONST': u32 + 125..127 '99': u32 + "#]], ); } #[test] fn infer_static() { - assert_snapshot!( - infer(r#" -static GLOBAL_STATIC: u32 = 101; -static mut GLOBAL_STATIC_MUT: u32 = 101; -fn test() { - static LOCAL_STATIC: u32 = 99; - static mut LOCAL_STATIC_MUT: u32 = 99; - let x = LOCAL_STATIC; - let y = LOCAL_STATIC_MUT; - let z = GLOBAL_STATIC; - let w = GLOBAL_STATIC_MUT; -} -"#), - @r###" - 28..31 '101': u32 - 69..72 '101': u32 - 84..279 '{ ...MUT; }': () - 172..173 'x': u32 - 176..188 'LOCAL_STATIC': u32 - 198..199 'y': u32 - 202..218 'LOCAL_...IC_MUT': u32 - 228..229 'z': u32 - 232..245 'GLOBAL_STATIC': u32 - 255..256 'w': u32 - 259..276 'GLOBAL...IC_MUT': u32 - 117..119 '99': u32 - 160..162 '99': u32 - "### + check_infer( + r#" + static GLOBAL_STATIC: u32 = 101; + static mut GLOBAL_STATIC_MUT: u32 = 101; + fn test() { + static LOCAL_STATIC: u32 = 99; + static mut LOCAL_STATIC_MUT: u32 = 99; + let x = LOCAL_STATIC; + let y = LOCAL_STATIC_MUT; + let z = GLOBAL_STATIC; + let w = GLOBAL_STATIC_MUT; + } + "#, + expect![[r#" + 28..31 '101': u32 + 69..72 '101': u32 + 84..279 '{ ...MUT; }': () + 172..173 'x': u32 + 176..188 'LOCAL_STATIC': u32 + 198..199 'y': u32 + 202..218 'LOCAL_...IC_MUT': u32 + 228..229 'z': u32 + 232..245 'GLOBAL_STATIC': u32 + 255..256 'w': u32 + 259..276 'GLOBAL...IC_MUT': u32 + 117..119 '99': u32 + 160..162 '99': u32 + "#]], ); } @@ -1777,413 +1778,413 @@ fn main() { #[test] fn closure_return() { - assert_snapshot!( - infer(r#" -fn foo() -> u32 { - let x = || -> usize { return 1; }; -} -"#), - @r###" - 16..58 '{ ...; }; }': () - 26..27 'x': || -> usize - 30..55 '|| -> ...n 1; }': || -> usize - 42..55 '{ return 1; }': usize - 44..52 'return 1': ! - 51..52 '1': usize - "### + check_infer( + r#" + fn foo() -> u32 { + let x = || -> usize { return 1; }; + } + "#, + expect![[r#" + 16..58 '{ ...; }; }': () + 26..27 'x': || -> usize + 30..55 '|| -> ...n 1; }': || -> usize + 42..55 '{ return 1; }': usize + 44..52 'return 1': ! + 51..52 '1': usize + "#]], ); } #[test] fn closure_return_unit() { - assert_snapshot!( - infer(r#" -fn foo() -> u32 { - let x = || { return; }; -} -"#), - @r###" - 16..47 '{ ...; }; }': () - 26..27 'x': || -> () - 30..44 '|| { return; }': || -> () - 33..44 '{ return; }': () - 35..41 'return': ! - "### + check_infer( + r#" + fn foo() -> u32 { + let x = || { return; }; + } + "#, + expect![[r#" + 16..47 '{ ...; }; }': () + 26..27 'x': || -> () + 30..44 '|| { return; }': || -> () + 33..44 '{ return; }': () + 35..41 'return': ! + "#]], ); } #[test] fn closure_return_inferred() { - assert_snapshot!( - infer(r#" -fn foo() -> u32 { - let x = || { "test" }; -} -"#), - @r###" - 16..46 '{ ..." }; }': () - 26..27 'x': || -> &str - 30..43 '|| { "test" }': || -> &str - 33..43 '{ "test" }': &str - 35..41 '"test"': &str - "### + check_infer( + r#" + fn foo() -> u32 { + let x = || { "test" }; + } + "#, + expect![[r#" + 16..46 '{ ..." }; }': () + 26..27 'x': || -> &str + 30..43 '|| { "test" }': || -> &str + 33..43 '{ "test" }': &str + 35..41 '"test"': &str + "#]], ); } #[test] fn fn_pointer_return() { - assert_snapshot!( - infer(r#" -struct Vtable { - method: fn(), -} + check_infer( + r#" + struct Vtable { + method: fn(), + } -fn main() { - let vtable = Vtable { method: || {} }; - let m = vtable.method; -} -"#), - @r###" - 47..120 '{ ...hod; }': () - 57..63 'vtable': Vtable - 66..90 'Vtable...| {} }': Vtable - 83..88 '|| {}': || -> () - 86..88 '{}': () - 100..101 'm': fn() - 104..110 'vtable': Vtable - 104..117 'vtable.method': fn() - "### + fn main() { + let vtable = Vtable { method: || {} }; + let m = vtable.method; + } + "#, + expect![[r#" + 47..120 '{ ...hod; }': () + 57..63 'vtable': Vtable + 66..90 'Vtable...| {} }': Vtable + 83..88 '|| {}': || -> () + 86..88 '{}': () + 100..101 'm': fn() + 104..110 'vtable': Vtable + 104..117 'vtable.method': fn() + "#]], ); } #[test] fn effects_smoke_test() { - assert_snapshot!( - infer(r#" -fn main() { - let x = unsafe { 92 }; - let y = async { async { () }.await }; - let z = try { () }; - let t = 'a: { 92 }; -} -"#), - @r###" - 10..130 '{ ...2 }; }': () - 20..21 'x': i32 - 24..37 'unsafe { 92 }': i32 - 31..37 '{ 92 }': i32 - 33..35 '92': i32 - 47..48 'y': {unknown} - 57..79 '{ asyn...wait }': {unknown} - 59..77 'async ....await': {unknown} - 65..71 '{ () }': () - 67..69 '()': () - 89..90 'z': {unknown} - 93..103 'try { () }': {unknown} - 97..103 '{ () }': () - 99..101 '()': () - 113..114 't': i32 - 121..127 '{ 92 }': i32 - 123..125 '92': i32 - "### + check_infer( + r#" + fn main() { + let x = unsafe { 92 }; + let y = async { async { () }.await }; + let z = try { () }; + let t = 'a: { 92 }; + } + "#, + expect![[r#" + 10..130 '{ ...2 }; }': () + 20..21 'x': i32 + 24..37 'unsafe { 92 }': i32 + 31..37 '{ 92 }': i32 + 33..35 '92': i32 + 47..48 'y': {unknown} + 57..79 '{ asyn...wait }': {unknown} + 59..77 'async ....await': {unknown} + 65..71 '{ () }': () + 67..69 '()': () + 89..90 'z': {unknown} + 93..103 'try { () }': {unknown} + 97..103 '{ () }': () + 99..101 '()': () + 113..114 't': i32 + 121..127 '{ 92 }': i32 + 123..125 '92': i32 + "#]], ) } #[test] fn infer_generic_from_later_assignment() { - assert_snapshot!( - infer(r#" -enum Option { Some(T), None } -use Option::*; + check_infer( + r#" + enum Option { Some(T), None } + use Option::*; -fn test() { - let mut end = None; - loop { - end = Some(true); - } -} -"#), - @r###" - 59..129 '{ ... } }': () - 69..76 'mut end': Option - 79..83 'None': Option - 89..127 'loop {... }': ! - 94..127 '{ ... }': () - 104..107 'end': Option - 104..120 'end = ...(true)': () - 110..114 'Some': Some(bool) -> Option - 110..120 'Some(true)': Option - 115..119 'true': bool - "### + fn test() { + let mut end = None; + loop { + end = Some(true); + } + } + "#, + expect![[r#" + 59..129 '{ ... } }': () + 69..76 'mut end': Option + 79..83 'None': Option + 89..127 'loop {... }': ! + 94..127 '{ ... }': () + 104..107 'end': Option + 104..120 'end = ...(true)': () + 110..114 'Some': Some(bool) -> Option + 110..120 'Some(true)': Option + 115..119 'true': bool + "#]], ); } #[test] fn infer_loop_break_with_val() { - assert_snapshot!( - infer(r#" -enum Option { Some(T), None } -use Option::*; + check_infer( + r#" + enum Option { Some(T), None } + use Option::*; -fn test() { - let x = loop { - if false { - break None; - } - - break Some(true); - }; -} -"#), - @r###" - 59..168 '{ ... }; }': () - 69..70 'x': Option - 73..165 'loop {... }': Option - 78..165 '{ ... }': () - 88..132 'if fal... }': () - 91..96 'false': bool - 97..132 '{ ... }': () - 111..121 'break None': ! - 117..121 'None': Option - 142..158 'break ...(true)': ! - 148..152 'Some': Some(bool) -> Option - 148..158 'Some(true)': Option - 153..157 'true': bool - "### + fn test() { + let x = loop { + if false { + break None; + } + + break Some(true); + }; + } + "#, + expect![[r#" + 59..168 '{ ... }; }': () + 69..70 'x': Option + 73..165 'loop {... }': Option + 78..165 '{ ... }': () + 88..132 'if fal... }': () + 91..96 'false': bool + 97..132 '{ ... }': () + 111..121 'break None': ! + 117..121 'None': Option + 142..158 'break ...(true)': ! + 148..152 'Some': Some(bool) -> Option + 148..158 'Some(true)': Option + 153..157 'true': bool + "#]], ); } #[test] fn infer_loop_break_without_val() { - assert_snapshot!( - infer(r#" -enum Option { Some(T), None } -use Option::*; - -fn test() { - let x = loop { - if false { - break; - } - }; -} -"#), - @r###" - 59..136 '{ ... }; }': () - 69..70 'x': () - 73..133 'loop {... }': () - 78..133 '{ ... }': () - 88..127 'if fal... }': () - 91..96 'false': bool - 97..127 '{ ... }': () - 111..116 'break': ! - "### + check_infer( + r#" + enum Option { Some(T), None } + use Option::*; + + fn test() { + let x = loop { + if false { + break; + } + }; + } + "#, + expect![[r#" + 59..136 '{ ... }; }': () + 69..70 'x': () + 73..133 'loop {... }': () + 78..133 '{ ... }': () + 88..127 'if fal... }': () + 91..96 'false': bool + 97..127 '{ ... }': () + 111..116 'break': ! + "#]], ); } #[test] fn infer_labelled_break_with_val() { - assert_snapshot!( - infer(r#" -fn foo() { - let _x = || 'outer: loop { - let inner = 'inner: loop { - let i = Default::default(); - if (break 'outer i) { - loop { break 'inner 5i8; }; - } else if true { - break 'inner 6; - } - break 7; - }; - break inner < 8; - }; -} -"#), - @r###" - 9..335 '{ ... }; }': () - 19..21 '_x': || -> bool - 24..332 '|| 'ou... }': || -> bool - 27..332 ''outer... }': bool - 40..332 '{ ... }': () - 54..59 'inner': i8 - 62..300 ''inner... }': i8 - 75..300 '{ ... }': () - 93..94 'i': bool - 97..113 'Defaul...efault': {unknown} - 97..115 'Defaul...ault()': bool - 129..269 'if (br... }': () - 133..147 'break 'outer i': ! - 146..147 'i': bool - 149..208 '{ ... }': () - 167..193 'loop {...5i8; }': ! - 172..193 '{ brea...5i8; }': () - 174..190 'break ...er 5i8': ! - 187..190 '5i8': i8 - 214..269 'if tru... }': () - 217..221 'true': bool - 222..269 '{ ... }': () - 240..254 'break 'inner 6': ! - 253..254 '6': i8 - 282..289 'break 7': ! - 288..289 '7': i8 - 310..325 'break inner < 8': ! - 316..321 'inner': i8 - 316..325 'inner < 8': bool - 324..325 '8': i8 - "### + check_infer( + r#" + fn foo() { + let _x = || 'outer: loop { + let inner = 'inner: loop { + let i = Default::default(); + if (break 'outer i) { + loop { break 'inner 5i8; }; + } else if true { + break 'inner 6; + } + break 7; + }; + break inner < 8; + }; + } + "#, + expect![[r#" + 9..335 '{ ... }; }': () + 19..21 '_x': || -> bool + 24..332 '|| 'ou... }': || -> bool + 27..332 ''outer... }': bool + 40..332 '{ ... }': () + 54..59 'inner': i8 + 62..300 ''inner... }': i8 + 75..300 '{ ... }': () + 93..94 'i': bool + 97..113 'Defaul...efault': {unknown} + 97..115 'Defaul...ault()': bool + 129..269 'if (br... }': () + 133..147 'break 'outer i': ! + 146..147 'i': bool + 149..208 '{ ... }': () + 167..193 'loop {...5i8; }': ! + 172..193 '{ brea...5i8; }': () + 174..190 'break ...er 5i8': ! + 187..190 '5i8': i8 + 214..269 'if tru... }': () + 217..221 'true': bool + 222..269 '{ ... }': () + 240..254 'break 'inner 6': ! + 253..254 '6': i8 + 282..289 'break 7': ! + 288..289 '7': i8 + 310..325 'break inner < 8': ! + 316..321 'inner': i8 + 316..325 'inner < 8': bool + 324..325 '8': i8 + "#]], ); } #[test] fn generic_default() { - assert_snapshot!( - infer(r#" -struct Thing { t: T } -enum OtherThing { - One { t: T }, - Two(T), -} - -fn test(t1: Thing, t2: OtherThing, t3: Thing, t4: OtherThing) { - t1.t; - t3.t; - match t2 { - OtherThing::One { t } => { t; }, - OtherThing::Two(t) => { t; }, - } - match t4 { - OtherThing::One { t } => { t; }, - OtherThing::Two(t) => { t; }, - } -} -"#), - @r###" - 97..99 't1': Thing<()> - 108..110 't2': OtherThing<()> - 124..126 't3': Thing - 140..142 't4': OtherThing - 161..384 '{ ... } }': () - 167..169 't1': Thing<()> - 167..171 't1.t': () - 177..179 't3': Thing - 177..181 't3.t': i32 - 187..282 'match ... }': () - 193..195 't2': OtherThing<()> - 206..227 'OtherT... { t }': OtherThing<()> - 224..225 't': () - 231..237 '{ t; }': () - 233..234 't': () - 247..265 'OtherT...Two(t)': OtherThing<()> - 263..264 't': () - 269..275 '{ t; }': () - 271..272 't': () - 287..382 'match ... }': () - 293..295 't4': OtherThing - 306..327 'OtherT... { t }': OtherThing - 324..325 't': i32 - 331..337 '{ t; }': () - 333..334 't': i32 - 347..365 'OtherT...Two(t)': OtherThing - 363..364 't': i32 - 369..375 '{ t; }': () - 371..372 't': i32 - "### + check_infer( + r#" + struct Thing { t: T } + enum OtherThing { + One { t: T }, + Two(T), + } + + fn test(t1: Thing, t2: OtherThing, t3: Thing, t4: OtherThing) { + t1.t; + t3.t; + match t2 { + OtherThing::One { t } => { t; }, + OtherThing::Two(t) => { t; }, + } + match t4 { + OtherThing::One { t } => { t; }, + OtherThing::Two(t) => { t; }, + } + } + "#, + expect![[r#" + 97..99 't1': Thing<()> + 108..110 't2': OtherThing<()> + 124..126 't3': Thing + 140..142 't4': OtherThing + 161..384 '{ ... } }': () + 167..169 't1': Thing<()> + 167..171 't1.t': () + 177..179 't3': Thing + 177..181 't3.t': i32 + 187..282 'match ... }': () + 193..195 't2': OtherThing<()> + 206..227 'OtherT... { t }': OtherThing<()> + 224..225 't': () + 231..237 '{ t; }': () + 233..234 't': () + 247..265 'OtherT...Two(t)': OtherThing<()> + 263..264 't': () + 269..275 '{ t; }': () + 271..272 't': () + 287..382 'match ... }': () + 293..295 't4': OtherThing + 306..327 'OtherT... { t }': OtherThing + 324..325 't': i32 + 331..337 '{ t; }': () + 333..334 't': i32 + 347..365 'OtherT...Two(t)': OtherThing + 363..364 't': i32 + 369..375 '{ t; }': () + 371..372 't': i32 + "#]], ); } #[test] fn generic_default_in_struct_literal() { - assert_snapshot!( - infer(r#" -struct Thing { t: T } -enum OtherThing { - One { t: T }, - Two(T), -} + check_infer( + r#" + struct Thing { t: T } + enum OtherThing { + One { t: T }, + Two(T), + } -fn test() { - let x = Thing { t: loop {} }; - let y = Thing { t: () }; - let z = Thing { t: 1i32 }; - if let Thing { t } = z { - t; - } + fn test() { + let x = Thing { t: loop {} }; + let y = Thing { t: () }; + let z = Thing { t: 1i32 }; + if let Thing { t } = z { + t; + } - let a = OtherThing::One { t: 1i32 }; - let b = OtherThing::Two(1i32); -} -"#), - @r###" - 99..319 '{ ...32); }': () - 109..110 'x': Thing - 113..133 'Thing ...p {} }': Thing - 124..131 'loop {}': ! - 129..131 '{}': () - 143..144 'y': Thing<()> - 147..162 'Thing { t: () }': Thing<()> - 158..160 '()': () - 172..173 'z': Thing - 176..193 'Thing ...1i32 }': Thing - 187..191 '1i32': i32 - 199..240 'if let... }': () - 206..217 'Thing { t }': Thing - 214..215 't': i32 - 220..221 'z': Thing - 222..240 '{ ... }': () - 232..233 't': i32 - 250..251 'a': OtherThing - 254..281 'OtherT...1i32 }': OtherThing - 275..279 '1i32': i32 - 291..292 'b': OtherThing - 295..310 'OtherThing::Two': Two(i32) -> OtherThing - 295..316 'OtherT...(1i32)': OtherThing - 311..315 '1i32': i32 - "### + let a = OtherThing::One { t: 1i32 }; + let b = OtherThing::Two(1i32); + } + "#, + expect![[r#" + 99..319 '{ ...32); }': () + 109..110 'x': Thing + 113..133 'Thing ...p {} }': Thing + 124..131 'loop {}': ! + 129..131 '{}': () + 143..144 'y': Thing<()> + 147..162 'Thing { t: () }': Thing<()> + 158..160 '()': () + 172..173 'z': Thing + 176..193 'Thing ...1i32 }': Thing + 187..191 '1i32': i32 + 199..240 'if let... }': () + 206..217 'Thing { t }': Thing + 214..215 't': i32 + 220..221 'z': Thing + 222..240 '{ ... }': () + 232..233 't': i32 + 250..251 'a': OtherThing + 254..281 'OtherT...1i32 }': OtherThing + 275..279 '1i32': i32 + 291..292 'b': OtherThing + 295..310 'OtherThing::Two': Two(i32) -> OtherThing + 295..316 'OtherT...(1i32)': OtherThing + 311..315 '1i32': i32 + "#]], ); } #[test] fn generic_default_depending_on_other_type_arg() { - assert_snapshot!( - infer(r#" -struct Thing T> { t: T } - -fn test(t1: Thing, t2: Thing) { - t1; - t2; - Thing::<_> { t: 1u32 }; -} -"#), - // FIXME: the {unknown} is a bug - @r###" - 56..58 't1': Thing u32> - 72..74 't2': Thing u128> - 83..130 '{ ...2 }; }': () - 89..91 't1': Thing u32> - 97..99 't2': Thing u128> - 105..127 'Thing:...1u32 }': Thing {unknown}> - 121..125 '1u32': u32 - "### + // FIXME: the {unknown} is a bug + check_infer( + r#" + struct Thing T> { t: T } + + fn test(t1: Thing, t2: Thing) { + t1; + t2; + Thing::<_> { t: 1u32 }; + } + "#, + expect![[r#" + 56..58 't1': Thing u32> + 72..74 't2': Thing u128> + 83..130 '{ ...2 }; }': () + 89..91 't1': Thing u32> + 97..99 't2': Thing u128> + 105..127 'Thing:...1u32 }': Thing {unknown}> + 121..125 '1u32': u32 + "#]], ); } #[test] fn generic_default_depending_on_other_type_arg_forward() { - assert_snapshot!( - infer(r#" -struct Thing T, T = u128> { t: T } - -fn test(t1: Thing) { - t1; -} -"#), - // the {unknown} here is intentional, as defaults are not allowed to - // refer to type parameters coming later - @r###" - 56..58 't1': Thing {unknown}, u128> - 67..78 '{ t1; }': () - 73..75 't1': Thing {unknown}, u128> - "### + // the {unknown} here is intentional, as defaults are not allowed to + // refer to type parameters coming later + check_infer( + r#" + struct Thing T, T = u128> { t: T } + + fn test(t1: Thing) { + t1; + } + "#, + expect![[r#" + 56..58 't1': Thing {unknown}, u128> + 67..78 '{ t1; }': () + 73..75 't1': Thing {unknown}, u128> + "#]], ); } diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 27737fa94..d3c4d3f2a 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -1,7 +1,7 @@ -use insta::assert_snapshot; +use expect::expect; use test_utils::mark; -use super::{check_types, infer, infer_with_mismatches}; +use super::{check_infer, check_infer_with_mismatches, check_types}; #[test] fn infer_await() { @@ -38,7 +38,7 @@ fn infer_async() { r#" //- /main.rs crate:main deps:core async fn foo() -> u64 { - 128 + 128 } fn test() { @@ -65,7 +65,7 @@ fn infer_desugar_async() { r#" //- /main.rs crate:main deps:core async fn foo() -> u64 { - 128 + 128 } fn test() { @@ -222,291 +222,291 @@ mod ops { #[test] fn infer_from_bound_1() { - assert_snapshot!( - infer(r#" -trait Trait {} -struct S(T); -impl Trait for S {} -fn foo>(t: T) {} -fn test() { - let s = S(unknown); - foo(s); -} -"#), - @r###" - 85..86 't': T - 91..93 '{}': () - 104..143 '{ ...(s); }': () - 114..115 's': S - 118..119 'S': S(u32) -> S - 118..128 'S(unknown)': S - 120..127 'unknown': u32 - 134..137 'foo': fn foo>(S) - 134..140 'foo(s)': () - 138..139 's': S - "### + check_infer( + r#" + trait Trait {} + struct S(T); + impl Trait for S {} + fn foo>(t: T) {} + fn test() { + let s = S(unknown); + foo(s); + } + "#, + expect![[r#" + 85..86 't': T + 91..93 '{}': () + 104..143 '{ ...(s); }': () + 114..115 's': S + 118..119 'S': S(u32) -> S + 118..128 'S(unknown)': S + 120..127 'unknown': u32 + 134..137 'foo': fn foo>(S) + 134..140 'foo(s)': () + 138..139 's': S + "#]], ); } #[test] fn infer_from_bound_2() { - assert_snapshot!( - infer(r#" -trait Trait {} -struct S(T); -impl Trait for S {} -fn foo>(t: T) -> U {} -fn test() { - let s = S(unknown); - let x: u32 = foo(s); -} -"#), - @r###" - 86..87 't': T - 97..99 '{}': () - 110..162 '{ ...(s); }': () - 120..121 's': S - 124..125 'S': S(u32) -> S - 124..134 'S(unknown)': S - 126..133 'unknown': u32 - 144..145 'x': u32 - 153..156 'foo': fn foo>(S) -> u32 - 153..159 'foo(s)': u32 - 157..158 's': S - "### + check_infer( + r#" + trait Trait {} + struct S(T); + impl Trait for S {} + fn foo>(t: T) -> U {} + fn test() { + let s = S(unknown); + let x: u32 = foo(s); + } + "#, + expect![[r#" + 86..87 't': T + 97..99 '{}': () + 110..162 '{ ...(s); }': () + 120..121 's': S + 124..125 'S': S(u32) -> S + 124..134 'S(unknown)': S + 126..133 'unknown': u32 + 144..145 'x': u32 + 153..156 'foo': fn foo>(S) -> u32 + 153..159 'foo(s)': u32 + 157..158 's': S + "#]], ); } #[test] fn trait_default_method_self_bound_implements_trait() { mark::check!(trait_self_implements_self); - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> i64; - fn bar(&self) -> { - let x = self.foo(); - } -} -"#), - @r###" - 26..30 'self': &Self - 52..56 'self': &Self - 61..96 '{ ... }': () - 75..76 'x': i64 - 79..83 'self': &Self - 79..89 'self.foo()': i64 - "### + check_infer( + r#" + trait Trait { + fn foo(&self) -> i64; + fn bar(&self) -> { + let x = self.foo(); + } + } + "#, + expect![[r#" + 26..30 'self': &Self + 52..56 'self': &Self + 61..96 '{ ... }': () + 75..76 'x': i64 + 79..83 'self': &Self + 79..89 'self.foo()': i64 + "#]], ); } #[test] fn trait_default_method_self_bound_implements_super_trait() { - assert_snapshot!( - infer(r#" -trait SuperTrait { - fn foo(&self) -> i64; -} -trait Trait: SuperTrait { - fn bar(&self) -> { - let x = self.foo(); - } -} -"#), - @r###" - 31..35 'self': &Self - 85..89 'self': &Self - 94..129 '{ ... }': () - 108..109 'x': i64 - 112..116 'self': &Self - 112..122 'self.foo()': i64 - "### + check_infer( + r#" + trait SuperTrait { + fn foo(&self) -> i64; + } + trait Trait: SuperTrait { + fn bar(&self) -> { + let x = self.foo(); + } + } + "#, + expect![[r#" + 31..35 'self': &Self + 85..89 'self': &Self + 94..129 '{ ... }': () + 108..109 'x': i64 + 112..116 'self': &Self + 112..122 'self.foo()': i64 + "#]], ); } #[test] fn infer_project_associated_type() { - assert_snapshot!( - infer(r#" -trait Iterable { - type Item; -} -struct S; -impl Iterable for S { type Item = u32; } -fn test() { - let x: ::Item = 1; - let y: ::Item = no_matter; - let z: T::Item = no_matter; - let a: ::Item = no_matter; -} -"#), - @r###" - 107..260 '{ ...ter; }': () - 117..118 'x': u32 - 144..145 '1': u32 - 155..156 'y': Iterable::Item - 182..191 'no_matter': Iterable::Item - 201..202 'z': Iterable::Item - 214..223 'no_matter': Iterable::Item - 233..234 'a': Iterable::Item - 248..257 'no_matter': Iterable::Item - "### + check_infer( + r#" + trait Iterable { + type Item; + } + struct S; + impl Iterable for S { type Item = u32; } + fn test() { + let x: ::Item = 1; + let y: ::Item = no_matter; + let z: T::Item = no_matter; + let a: ::Item = no_matter; + } + "#, + expect![[r#" + 108..261 '{ ...ter; }': () + 118..119 'x': u32 + 145..146 '1': u32 + 156..157 'y': Iterable::Item + 183..192 'no_matter': Iterable::Item + 202..203 'z': Iterable::Item + 215..224 'no_matter': Iterable::Item + 234..235 'a': Iterable::Item + 249..258 'no_matter': Iterable::Item + "#]], ); } #[test] fn infer_return_associated_type() { - assert_snapshot!( - infer(r#" -trait Iterable { - type Item; -} -struct S; -impl Iterable for S { type Item = u32; } -fn foo1(t: T) -> T::Item {} -fn foo2(t: T) -> ::Item {} -fn foo3(t: T) -> ::Item {} -fn test() { - let x = foo1(S); - let y = foo2(S); - let z = foo3(S); -} -"#), - @r###" - 105..106 't': T - 122..124 '{}': () - 146..147 't': T - 177..179 '{}': () - 201..202 't': T - 220..222 '{}': () - 233..299 '{ ...(S); }': () - 243..244 'x': u32 - 247..251 'foo1': fn foo1(S) -> ::Item - 247..254 'foo1(S)': u32 - 252..253 'S': S - 264..265 'y': u32 - 268..272 'foo2': fn foo2(S) -> ::Item - 268..275 'foo2(S)': u32 - 273..274 'S': S - 285..286 'z': u32 - 289..293 'foo3': fn foo3(S) -> ::Item - 289..296 'foo3(S)': u32 - 294..295 'S': S - "### + check_infer( + r#" + trait Iterable { + type Item; + } + struct S; + impl Iterable for S { type Item = u32; } + fn foo1(t: T) -> T::Item {} + fn foo2(t: T) -> ::Item {} + fn foo3(t: T) -> ::Item {} + fn test() { + let x = foo1(S); + let y = foo2(S); + let z = foo3(S); + } + "#, + expect![[r#" + 106..107 't': T + 123..125 '{}': () + 147..148 't': T + 178..180 '{}': () + 202..203 't': T + 221..223 '{}': () + 234..300 '{ ...(S); }': () + 244..245 'x': u32 + 248..252 'foo1': fn foo1(S) -> ::Item + 248..255 'foo1(S)': u32 + 253..254 'S': S + 265..266 'y': u32 + 269..273 'foo2': fn foo2(S) -> ::Item + 269..276 'foo2(S)': u32 + 274..275 'S': S + 286..287 'z': u32 + 290..294 'foo3': fn foo3(S) -> ::Item + 290..297 'foo3(S)': u32 + 295..296 'S': S + "#]], ); } #[test] fn infer_associated_type_bound() { - assert_snapshot!( - infer(r#" -trait Iterable { - type Item; -} -fn test>() { - let y: T::Item = unknown; -} -"#), - @r###" - 66..99 '{ ...own; }': () - 76..77 'y': u32 - 89..96 'unknown': u32 - "### + check_infer( + r#" + trait Iterable { + type Item; + } + fn test>() { + let y: T::Item = unknown; + } + "#, + expect![[r#" + 67..100 '{ ...own; }': () + 77..78 'y': u32 + 90..97 'unknown': u32 + "#]], ); } #[test] fn infer_const_body() { - assert_snapshot!( - infer(r#" -const A: u32 = 1 + 1; -static B: u64 = { let x = 1; x }; -"#), - @r###" - 15..16 '1': u32 - 15..20 '1 + 1': u32 - 19..20 '1': u32 - 38..54 '{ let ...1; x }': u64 - 44..45 'x': u64 - 48..49 '1': u64 - 51..52 'x': u64 - "### + check_infer( + r#" + const A: u32 = 1 + 1; + static B: u64 = { let x = 1; x }; + "#, + expect![[r#" + 15..16 '1': u32 + 15..20 '1 + 1': u32 + 19..20 '1': u32 + 38..54 '{ let ...1; x }': u64 + 44..45 'x': u64 + 48..49 '1': u64 + 51..52 'x': u64 + "#]], ); } #[test] fn tuple_struct_fields() { - assert_snapshot!( - infer(r#" -struct S(i32, u64); -fn test() -> u64 { - let a = S(4, 6); - let b = a.0; - a.1 -} -"#), - @r###" - 37..86 '{ ... a.1 }': u64 - 47..48 'a': S - 51..52 'S': S(i32, u64) -> S - 51..58 'S(4, 6)': S - 53..54 '4': i32 - 56..57 '6': u64 - 68..69 'b': i32 - 72..73 'a': S - 72..75 'a.0': i32 - 81..82 'a': S - 81..84 'a.1': u64 - "### + check_infer( + r#" + struct S(i32, u64); + fn test() -> u64 { + let a = S(4, 6); + let b = a.0; + a.1 + } + "#, + expect![[r#" + 37..86 '{ ... a.1 }': u64 + 47..48 'a': S + 51..52 'S': S(i32, u64) -> S + 51..58 'S(4, 6)': S + 53..54 '4': i32 + 56..57 '6': u64 + 68..69 'b': i32 + 72..73 'a': S + 72..75 'a.0': i32 + 81..82 'a': S + 81..84 'a.1': u64 + "#]], ); } #[test] fn tuple_struct_with_fn() { - assert_snapshot!( - infer(r#" -struct S(fn(u32) -> u64); -fn test() -> u64 { - let a = S(|i| 2*i); - let b = a.0(4); - a.0(2) -} -"#), - @r###" - 43..101 '{ ...0(2) }': u64 - 53..54 'a': S - 57..58 'S': S(fn(u32) -> u64) -> S - 57..67 'S(|i| 2*i)': S - 59..66 '|i| 2*i': |u32| -> u64 - 60..61 'i': u32 - 63..64 '2': u32 - 63..66 '2*i': u32 - 65..66 'i': u32 - 77..78 'b': u64 - 81..82 'a': S - 81..84 'a.0': fn(u32) -> u64 - 81..87 'a.0(4)': u64 - 85..86 '4': u32 - 93..94 'a': S - 93..96 'a.0': fn(u32) -> u64 - 93..99 'a.0(2)': u64 - 97..98 '2': u32 - "### + check_infer( + r#" + struct S(fn(u32) -> u64); + fn test() -> u64 { + let a = S(|i| 2*i); + let b = a.0(4); + a.0(2) + } + "#, + expect![[r#" + 43..101 '{ ...0(2) }': u64 + 53..54 'a': S + 57..58 'S': S(fn(u32) -> u64) -> S + 57..67 'S(|i| 2*i)': S + 59..66 '|i| 2*i': |u32| -> u64 + 60..61 'i': u32 + 63..64 '2': u32 + 63..66 '2*i': u32 + 65..66 'i': u32 + 77..78 'b': u64 + 81..82 'a': S + 81..84 'a.0': fn(u32) -> u64 + 81..87 'a.0(4)': u64 + 85..86 '4': u32 + 93..94 'a': S + 93..96 'a.0': fn(u32) -> u64 + 93..99 'a.0(2)': u64 + 97..98 '2': u32 + "#]], ); } #[test] fn indexing_arrays() { - assert_snapshot!( - infer("fn main() { &mut [9][2]; }"), - @r###" - 10..26 '{ &mut...[2]; }': () - 12..23 '&mut [9][2]': &mut {unknown} - 17..20 '[9]': [i32; _] - 17..23 '[9][2]': {unknown} - 18..19 '9': i32 - 21..22 '2': i32 - "### + check_infer( + "fn main() { &mut [9][2]; }", + expect![[r#" + 10..26 '{ &mut...[2]; }': () + 12..23 '&mut [9][2]': &mut {unknown} + 17..20 '[9]': [i32; _] + 17..23 '[9][2]': {unknown} + 18..19 '9': i32 + 21..22 '2': i32 + "#]], ) } @@ -908,476 +908,475 @@ fn test(t: T) { #[test] fn argument_impl_trait() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; -} -fn bar(x: impl Trait) {} -struct S(T); -impl Trait for S {} - -fn test(x: impl Trait, y: &impl Trait) { - x; - y; - let z = S(1); - bar(z); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); -} -"#, true), - @r###" - 29..33 'self': &Self - 54..58 'self': &Self - 77..78 'x': impl Trait - 97..99 '{}': () - 154..155 'x': impl Trait - 174..175 'y': &impl Trait - 195..323 '{ ...2(); }': () - 201..202 'x': impl Trait - 208..209 'y': &impl Trait - 219..220 'z': S - 223..224 'S': S(u16) -> S - 223..227 'S(1)': S - 225..226 '1': u16 - 233..236 'bar': fn bar(S) - 233..239 'bar(z)': () - 237..238 'z': S - 245..246 'x': impl Trait - 245..252 'x.foo()': u64 - 258..259 'y': &impl Trait - 258..265 'y.foo()': u32 - 271..272 'z': S - 271..278 'z.foo()': u16 - 284..285 'x': impl Trait - 284..292 'x.foo2()': i64 - 298..299 'y': &impl Trait - 298..306 'y.foo2()': i64 - 312..313 'z': S - 312..320 'z.foo2()': i64 - "### + check_infer_with_mismatches( + r#" + trait Trait { + fn foo(&self) -> T; + fn foo2(&self) -> i64; + } + fn bar(x: impl Trait) {} + struct S(T); + impl Trait for S {} + + fn test(x: impl Trait, y: &impl Trait) { + x; + y; + let z = S(1); + bar(z); + x.foo(); + y.foo(); + z.foo(); + x.foo2(); + y.foo2(); + z.foo2(); + } + "#, + expect![[r#" + 29..33 'self': &Self + 54..58 'self': &Self + 77..78 'x': impl Trait + 97..99 '{}': () + 154..155 'x': impl Trait + 174..175 'y': &impl Trait + 195..323 '{ ...2(); }': () + 201..202 'x': impl Trait + 208..209 'y': &impl Trait + 219..220 'z': S + 223..224 'S': S(u16) -> S + 223..227 'S(1)': S + 225..226 '1': u16 + 233..236 'bar': fn bar(S) + 233..239 'bar(z)': () + 237..238 'z': S + 245..246 'x': impl Trait + 245..252 'x.foo()': u64 + 258..259 'y': &impl Trait + 258..265 'y.foo()': u32 + 271..272 'z': S + 271..278 'z.foo()': u16 + 284..285 'x': impl Trait + 284..292 'x.foo2()': i64 + 298..299 'y': &impl Trait + 298..306 'y.foo2()': i64 + 312..313 'z': S + 312..320 'z.foo2()': i64 + "#]], ); } #[test] fn argument_impl_trait_type_args_1() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Trait {} -trait Foo { - // this function has an implicit Self param, an explicit type param, - // and an implicit impl Trait param! - fn bar(x: impl Trait) -> T { loop {} } -} -fn foo(x: impl Trait) -> T { loop {} } -struct S; -impl Trait for S {} -struct F; -impl Foo for F {} - -fn test() { - Foo::bar(S); - ::bar(S); - F::bar(S); - Foo::bar::(S); - ::bar::(S); - - foo(S); - foo::(S); - foo::(S); // we should ignore the extraneous i32 -} -"#, true), - @r###" - 155..156 'x': impl Trait - 175..186 '{ loop {} }': T - 177..184 'loop {}': ! - 182..184 '{}': () - 199..200 'x': impl Trait - 219..230 '{ loop {} }': T - 221..228 'loop {}': ! - 226..228 '{}': () - 300..509 '{ ... i32 }': () - 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} - 306..317 'Foo::bar(S)': {unknown} - 315..316 'S': S - 323..338 '::bar': fn bar(S) -> {unknown} - 323..341 '(S) -> {unknown} - 347..356 'F::bar(S)': {unknown} - 354..355 'S': S - 362..377 'Foo::bar::': fn bar<{unknown}, u32>(S) -> u32 - 362..380 'Foo::b...32>(S)': u32 - 378..379 'S': S - 386..408 '': fn bar(S) -> u32 - 386..411 '(S)': u32 - 409..410 'S': S - 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} - 418..424 'foo(S)': {unknown} - 422..423 'S': S - 430..440 'foo::': fn foo(S) -> u32 - 430..443 'foo::(S)': u32 - 441..442 'S': S - 449..464 'foo::': fn foo(S) -> u32 - 449..467 'foo::<...32>(S)': u32 - 465..466 'S': S - "### + check_infer_with_mismatches( + r#" + trait Trait {} + trait Foo { + // this function has an implicit Self param, an explicit type param, + // and an implicit impl Trait param! + fn bar(x: impl Trait) -> T { loop {} } + } + fn foo(x: impl Trait) -> T { loop {} } + struct S; + impl Trait for S {} + struct F; + impl Foo for F {} + + fn test() { + Foo::bar(S); + ::bar(S); + F::bar(S); + Foo::bar::(S); + ::bar::(S); + + foo(S); + foo::(S); + foo::(S); // we should ignore the extraneous i32 + } + "#, + expect![[r#" + 155..156 'x': impl Trait + 175..186 '{ loop {} }': T + 177..184 'loop {}': ! + 182..184 '{}': () + 199..200 'x': impl Trait + 219..230 '{ loop {} }': T + 221..228 'loop {}': ! + 226..228 '{}': () + 300..509 '{ ... i32 }': () + 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} + 306..317 'Foo::bar(S)': {unknown} + 315..316 'S': S + 323..338 '::bar': fn bar(S) -> {unknown} + 323..341 '(S) -> {unknown} + 347..356 'F::bar(S)': {unknown} + 354..355 'S': S + 362..377 'Foo::bar::': fn bar<{unknown}, u32>(S) -> u32 + 362..380 'Foo::b...32>(S)': u32 + 378..379 'S': S + 386..408 '': fn bar(S) -> u32 + 386..411 '(S)': u32 + 409..410 'S': S + 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} + 418..424 'foo(S)': {unknown} + 422..423 'S': S + 430..440 'foo::': fn foo(S) -> u32 + 430..443 'foo::(S)': u32 + 441..442 'S': S + 449..464 'foo::': fn foo(S) -> u32 + 449..467 'foo::<...32>(S)': u32 + 465..466 'S': S + "#]], ); } #[test] fn argument_impl_trait_type_args_2() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Trait {} -struct S; -impl Trait for S {} -struct F; -impl F { - fn foo(self, x: impl Trait) -> (T, U) { loop {} } -} + check_infer_with_mismatches( + r#" + trait Trait {} + struct S; + impl Trait for S {} + struct F; + impl F { + fn foo(self, x: impl Trait) -> (T, U) { loop {} } + } -fn test() { - F.foo(S); - F::.foo(S); - F::.foo::(S); - F::.foo::(S); // extraneous argument should be ignored -} -"#, true), - @r###" - 87..91 'self': F - 93..94 'x': impl Trait - 118..129 '{ loop {} }': (T, U) - 120..127 'loop {}': ! - 125..127 '{}': () - 143..283 '{ ...ored }': () - 149..150 'F': F<{unknown}> - 149..157 'F.foo(S)': ({unknown}, {unknown}) - 155..156 'S': S - 163..171 'F::': F - 163..178 'F::.foo(S)': (u32, {unknown}) - 176..177 'S': S - 184..192 'F::': F - 184..206 'F::(S)': (u32, i32) - 204..205 'S': S - 212..220 'F::': F - 212..239 'F::(S)': (u32, i32) - 237..238 'S': S - "### + fn test() { + F.foo(S); + F::.foo(S); + F::.foo::(S); + F::.foo::(S); // extraneous argument should be ignored + } + "#, + expect![[r#" + 87..91 'self': F + 93..94 'x': impl Trait + 118..129 '{ loop {} }': (T, U) + 120..127 'loop {}': ! + 125..127 '{}': () + 143..283 '{ ...ored }': () + 149..150 'F': F<{unknown}> + 149..157 'F.foo(S)': ({unknown}, {unknown}) + 155..156 'S': S + 163..171 'F::': F + 163..178 'F::.foo(S)': (u32, {unknown}) + 176..177 'S': S + 184..192 'F::': F + 184..206 'F::(S)': (u32, i32) + 204..205 'S': S + 212..220 'F::': F + 212..239 'F::(S)': (u32, i32) + 237..238 'S': S + "#]], ); } #[test] fn argument_impl_trait_to_fn_pointer() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Trait {} -fn foo(x: impl Trait) { loop {} } -struct S; -impl Trait for S {} + check_infer_with_mismatches( + r#" + trait Trait {} + fn foo(x: impl Trait) { loop {} } + struct S; + impl Trait for S {} -fn test() { - let f: fn(S) -> () = foo; -} -"#, true), - @r###" - 22..23 'x': impl Trait - 37..48 '{ loop {} }': () - 39..46 'loop {}': ! - 44..46 '{}': () - 90..123 '{ ...foo; }': () - 100..101 'f': fn(S) - 117..120 'foo': fn foo(S) - "### + fn test() { + let f: fn(S) -> () = foo; + } + "#, + expect![[r#" + 22..23 'x': impl Trait + 37..48 '{ loop {} }': () + 39..46 'loop {}': ! + 44..46 '{}': () + 90..123 '{ ...foo; }': () + 100..101 'f': fn(S) + 117..120 'foo': fn foo(S) + "#]], ); } #[test] fn impl_trait() { - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; -} -fn bar() -> impl Trait {} - -fn test(x: impl Trait, y: &impl Trait) { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); -} -"#), - @r###" - 29..33 'self': &Self - 54..58 'self': &Self - 98..100 '{}': () - 110..111 'x': impl Trait - 130..131 'y': &impl Trait - 151..268 '{ ...2(); }': () - 157..158 'x': impl Trait - 164..165 'y': &impl Trait - 175..176 'z': impl Trait - 179..182 'bar': fn bar() -> impl Trait - 179..184 'bar()': impl Trait - 190..191 'x': impl Trait - 190..197 'x.foo()': u64 - 203..204 'y': &impl Trait - 203..210 'y.foo()': u64 - 216..217 'z': impl Trait - 216..223 'z.foo()': u64 - 229..230 'x': impl Trait - 229..237 'x.foo2()': i64 - 243..244 'y': &impl Trait - 243..251 'y.foo2()': i64 - 257..258 'z': impl Trait - 257..265 'z.foo2()': i64 - "### + check_infer( + r#" + trait Trait { + fn foo(&self) -> T; + fn foo2(&self) -> i64; + } + fn bar() -> impl Trait {} + + fn test(x: impl Trait, y: &impl Trait) { + x; + y; + let z = bar(); + x.foo(); + y.foo(); + z.foo(); + x.foo2(); + y.foo2(); + z.foo2(); + } + "#, + expect![[r#" + 29..33 'self': &Self + 54..58 'self': &Self + 98..100 '{}': () + 110..111 'x': impl Trait + 130..131 'y': &impl Trait + 151..268 '{ ...2(); }': () + 157..158 'x': impl Trait + 164..165 'y': &impl Trait + 175..176 'z': impl Trait + 179..182 'bar': fn bar() -> impl Trait + 179..184 'bar()': impl Trait + 190..191 'x': impl Trait + 190..197 'x.foo()': u64 + 203..204 'y': &impl Trait + 203..210 'y.foo()': u64 + 216..217 'z': impl Trait + 216..223 'z.foo()': u64 + 229..230 'x': impl Trait + 229..237 'x.foo2()': i64 + 243..244 'y': &impl Trait + 243..251 'y.foo2()': i64 + 257..258 'z': impl Trait + 257..265 'z.foo2()': i64 + "#]], ); } #[test] fn simple_return_pos_impl_trait() { mark::check!(lower_rpit); - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> T; -} -fn bar() -> impl Trait { loop {} } + check_infer( + r#" + trait Trait { + fn foo(&self) -> T; + } + fn bar() -> impl Trait { loop {} } -fn test() { - let a = bar(); - a.foo(); -} -"#), - @r###" - 29..33 'self': &Self - 71..82 '{ loop {} }': ! - 73..80 'loop {}': ! - 78..80 '{}': () - 94..129 '{ ...o(); }': () - 104..105 'a': impl Trait - 108..111 'bar': fn bar() -> impl Trait - 108..113 'bar()': impl Trait - 119..120 'a': impl Trait - 119..126 'a.foo()': u64 - "### + fn test() { + let a = bar(); + a.foo(); + } + "#, + expect![[r#" + 29..33 'self': &Self + 71..82 '{ loop {} }': ! + 73..80 'loop {}': ! + 78..80 '{}': () + 94..129 '{ ...o(); }': () + 104..105 'a': impl Trait + 108..111 'bar': fn bar() -> impl Trait + 108..113 'bar()': impl Trait + 119..120 'a': impl Trait + 119..126 'a.foo()': u64 + "#]], ); } #[test] fn more_return_pos_impl_trait() { - assert_snapshot!( - infer(r#" -trait Iterator { - type Item; - fn next(&mut self) -> Self::Item; -} -trait Trait { - fn foo(&self) -> T; -} -fn bar() -> (impl Iterator>, impl Trait) { loop {} } -fn baz(t: T) -> (impl Iterator>, impl Trait) { loop {} } - -fn test() { - let (a, b) = bar(); - a.next().foo(); - b.foo(); - let (c, d) = baz(1u128); - c.next().foo(); - d.foo(); -} -"#), - @r###" - 49..53 'self': &mut Self - 101..105 'self': &Self - 184..195 '{ loop {} }': ({unknown}, {unknown}) - 186..193 'loop {}': ! - 191..193 '{}': () - 206..207 't': T - 268..279 '{ loop {} }': ({unknown}, {unknown}) - 270..277 'loop {}': ! - 275..277 '{}': () - 291..413 '{ ...o(); }': () - 301..307 '(a, b)': (impl Iterator>, impl Trait) - 302..303 'a': impl Iterator> - 305..306 'b': impl Trait - 310..313 'bar': fn bar() -> (impl Iterator>, impl Trait) - 310..315 'bar()': (impl Iterator>, impl Trait) - 321..322 'a': impl Iterator> - 321..329 'a.next()': impl Trait - 321..335 'a.next().foo()': u32 - 341..342 'b': impl Trait - 341..348 'b.foo()': u64 - 358..364 '(c, d)': (impl Iterator>, impl Trait) - 359..360 'c': impl Iterator> - 362..363 'd': impl Trait - 367..370 'baz': fn baz(u128) -> (impl Iterator>, impl Trait) - 367..377 'baz(1u128)': (impl Iterator>, impl Trait) - 371..376 '1u128': u128 - 383..384 'c': impl Iterator> - 383..391 'c.next()': impl Trait - 383..397 'c.next().foo()': u128 - 403..404 'd': impl Trait - 403..410 'd.foo()': u128 - "### + check_infer( + r#" + trait Iterator { + type Item; + fn next(&mut self) -> Self::Item; + } + trait Trait { + fn foo(&self) -> T; + } + fn bar() -> (impl Iterator>, impl Trait) { loop {} } + fn baz(t: T) -> (impl Iterator>, impl Trait) { loop {} } + + fn test() { + let (a, b) = bar(); + a.next().foo(); + b.foo(); + let (c, d) = baz(1u128); + c.next().foo(); + d.foo(); + } + "#, + expect![[r#" + 49..53 'self': &mut Self + 101..105 'self': &Self + 184..195 '{ loop {} }': ({unknown}, {unknown}) + 186..193 'loop {}': ! + 191..193 '{}': () + 206..207 't': T + 268..279 '{ loop {} }': ({unknown}, {unknown}) + 270..277 'loop {}': ! + 275..277 '{}': () + 291..413 '{ ...o(); }': () + 301..307 '(a, b)': (impl Iterator>, impl Trait) + 302..303 'a': impl Iterator> + 305..306 'b': impl Trait + 310..313 'bar': fn bar() -> (impl Iterator>, impl Trait) + 310..315 'bar()': (impl Iterator>, impl Trait) + 321..322 'a': impl Iterator> + 321..329 'a.next()': impl Trait + 321..335 'a.next().foo()': u32 + 341..342 'b': impl Trait + 341..348 'b.foo()': u64 + 358..364 '(c, d)': (impl Iterator>, impl Trait) + 359..360 'c': impl Iterator> + 362..363 'd': impl Trait + 367..370 'baz': fn baz(u128) -> (impl Iterator>, impl Trait) + 367..377 'baz(1u128)': (impl Iterator>, impl Trait) + 371..376 '1u128': u128 + 383..384 'c': impl Iterator> + 383..391 'c.next()': impl Trait + 383..397 'c.next().foo()': u128 + 403..404 'd': impl Trait + 403..410 'd.foo()': u128 + "#]], ); } #[test] fn dyn_trait() { - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> T; - fn foo2(&self) -> i64; -} -fn bar() -> dyn Trait {} - -fn test(x: dyn Trait, y: &dyn Trait) { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); - x.foo2(); - y.foo2(); - z.foo2(); -} -"#), - @r###" - 29..33 'self': &Self - 54..58 'self': &Self - 97..99 '{}': () - 109..110 'x': dyn Trait - 128..129 'y': &dyn Trait - 148..265 '{ ...2(); }': () - 154..155 'x': dyn Trait - 161..162 'y': &dyn Trait - 172..173 'z': dyn Trait - 176..179 'bar': fn bar() -> dyn Trait - 176..181 'bar()': dyn Trait - 187..188 'x': dyn Trait - 187..194 'x.foo()': u64 - 200..201 'y': &dyn Trait - 200..207 'y.foo()': u64 - 213..214 'z': dyn Trait - 213..220 'z.foo()': u64 - 226..227 'x': dyn Trait - 226..234 'x.foo2()': i64 - 240..241 'y': &dyn Trait - 240..248 'y.foo2()': i64 - 254..255 'z': dyn Trait - 254..262 'z.foo2()': i64 - "### + check_infer( + r#" + trait Trait { + fn foo(&self) -> T; + fn foo2(&self) -> i64; + } + fn bar() -> dyn Trait {} + + fn test(x: dyn Trait, y: &dyn Trait) { + x; + y; + let z = bar(); + x.foo(); + y.foo(); + z.foo(); + x.foo2(); + y.foo2(); + z.foo2(); + } + "#, + expect![[r#" + 29..33 'self': &Self + 54..58 'self': &Self + 97..99 '{}': () + 109..110 'x': dyn Trait + 128..129 'y': &dyn Trait + 148..265 '{ ...2(); }': () + 154..155 'x': dyn Trait + 161..162 'y': &dyn Trait + 172..173 'z': dyn Trait + 176..179 'bar': fn bar() -> dyn Trait + 176..181 'bar()': dyn Trait + 187..188 'x': dyn Trait + 187..194 'x.foo()': u64 + 200..201 'y': &dyn Trait + 200..207 'y.foo()': u64 + 213..214 'z': dyn Trait + 213..220 'z.foo()': u64 + 226..227 'x': dyn Trait + 226..234 'x.foo2()': i64 + 240..241 'y': &dyn Trait + 240..248 'y.foo2()': i64 + 254..255 'z': dyn Trait + 254..262 'z.foo2()': i64 + "#]], ); } #[test] fn dyn_trait_in_impl() { - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> (T, U); -} -struct S {} -impl S { - fn bar(&self) -> &dyn Trait { loop {} } -} -trait Trait2 { - fn baz(&self) -> (T, U); -} -impl Trait2 for dyn Trait { } + check_infer( + r#" + trait Trait { + fn foo(&self) -> (T, U); + } + struct S {} + impl S { + fn bar(&self) -> &dyn Trait { loop {} } + } + trait Trait2 { + fn baz(&self) -> (T, U); + } + impl Trait2 for dyn Trait { } -fn test(s: S) { - s.bar().baz(); -} -"#), - @r###" - 32..36 'self': &Self - 102..106 'self': &S - 128..139 '{ loop {} }': &dyn Trait - 130..137 'loop {}': ! - 135..137 '{}': () - 175..179 'self': &Self - 251..252 's': S - 267..289 '{ ...z(); }': () - 273..274 's': S - 273..280 's.bar()': &dyn Trait - 273..286 's.bar().baz()': (u32, i32) - "### + fn test(s: S) { + s.bar().baz(); + } + "#, + expect![[r#" + 32..36 'self': &Self + 102..106 'self': &S + 128..139 '{ loop {} }': &dyn Trait + 130..137 'loop {}': ! + 135..137 '{}': () + 175..179 'self': &Self + 251..252 's': S + 267..289 '{ ...z(); }': () + 273..274 's': S + 273..280 's.bar()': &dyn Trait + 273..286 's.bar().baz()': (u32, i32) + "#]], ); } #[test] fn dyn_trait_bare() { - assert_snapshot!( - infer(r#" -trait Trait { - fn foo(&self) -> u64; -} -fn bar() -> Trait {} - -fn test(x: Trait, y: &Trait) -> u64 { - x; - y; - let z = bar(); - x.foo(); - y.foo(); - z.foo(); -} -"#), - @r###" - 26..30 'self': &Self - 60..62 '{}': () - 72..73 'x': dyn Trait - 82..83 'y': &dyn Trait - 100..175 '{ ...o(); }': () - 106..107 'x': dyn Trait - 113..114 'y': &dyn Trait - 124..125 'z': dyn Trait - 128..131 'bar': fn bar() -> dyn Trait - 128..133 'bar()': dyn Trait - 139..140 'x': dyn Trait - 139..146 'x.foo()': u64 - 152..153 'y': &dyn Trait - 152..159 'y.foo()': u64 - 165..166 'z': dyn Trait - 165..172 'z.foo()': u64 - "### + check_infer( + r#" + trait Trait { + fn foo(&self) -> u64; + } + fn bar() -> Trait {} + + fn test(x: Trait, y: &Trait) -> u64 { + x; + y; + let z = bar(); + x.foo(); + y.foo(); + z.foo(); + } + "#, + expect![[r#" + 26..30 'self': &Self + 60..62 '{}': () + 72..73 'x': dyn Trait + 82..83 'y': &dyn Trait + 100..175 '{ ...o(); }': () + 106..107 'x': dyn Trait + 113..114 'y': &dyn Trait + 124..125 'z': dyn Trait + 128..131 'bar': fn bar() -> dyn Trait + 128..133 'bar()': dyn Trait + 139..140 'x': dyn Trait + 139..146 'x.foo()': u64 + 152..153 'y': &dyn Trait + 152..159 'y.foo()': u64 + 165..166 'z': dyn Trait + 165..172 'z.foo()': u64 + "#]], ); } #[test] fn weird_bounds() { - assert_snapshot!( - infer(r#" -trait Trait {} -fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { -} -"#), - @r###" - 23..24 'a': impl Trait + {error} - 50..51 'b': impl {error} - 69..70 'c': impl Trait - 86..87 'd': impl {error} - 107..108 'e': impl {error} - 123..124 'f': impl Trait + {error} - 147..150 '{ }': () - "### + check_infer( + r#" + trait Trait {} + fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} + "#, + expect![[r#" + 23..24 'a': impl Trait + {error} + 50..51 'b': impl {error} + 69..70 'c': impl Trait + 86..87 'd': impl {error} + 107..108 'e': impl {error} + 123..124 'f': impl Trait + {error} + 147..149 '{}': () + "#]], ); } @@ -1399,66 +1398,66 @@ fn test(x: (impl Trait + UnknownTrait)) { #[test] fn assoc_type_bindings() { - assert_snapshot!( - infer(r#" -trait Trait { - type Type; -} - -fn get(t: T) -> ::Type {} -fn get2>(t: T) -> U {} -fn set>(t: T) -> T {t} + check_infer( + r#" + trait Trait { + type Type; + } -struct S; -impl Trait for S { type Type = T; } - -fn test>(x: T, y: impl Trait) { - get(x); - get2(x); - get(y); - get2(y); - get(set(S)); - get2(set(S)); - get2(S::); -} -"#), - @r###" - 49..50 't': T - 77..79 '{}': () - 111..112 't': T - 122..124 '{}': () - 154..155 't': T - 165..168 '{t}': T - 166..167 't': T - 256..257 'x': T - 262..263 'y': impl Trait - 289..397 '{ ...r>); }': () - 295..298 'get': fn get(T) -> ::Type - 295..301 'get(x)': u32 - 299..300 'x': T - 307..311 'get2': fn get2(T) -> u32 - 307..314 'get2(x)': u32 - 312..313 'x': T - 320..323 'get': fn get>(impl Trait) -> as Trait>::Type - 320..326 'get(y)': i64 - 324..325 'y': impl Trait - 332..336 'get2': fn get2>(impl Trait) -> i64 - 332..339 'get2(y)': i64 - 337..338 'y': impl Trait - 345..348 'get': fn get>(S) -> as Trait>::Type - 345..356 'get(set(S))': u64 - 349..352 'set': fn set>(S) -> S - 349..355 'set(S)': S - 353..354 'S': S - 362..366 'get2': fn get2>(S) -> u64 - 362..374 'get2(set(S))': u64 - 367..370 'set': fn set>(S) -> S - 367..373 'set(S)': S - 371..372 'S': S - 380..384 'get2': fn get2>(S) -> str - 380..394 'get2(S::)': str - 385..393 'S::': S - "### + fn get(t: T) -> ::Type {} + fn get2>(t: T) -> U {} + fn set>(t: T) -> T {t} + + struct S; + impl Trait for S { type Type = T; } + + fn test>(x: T, y: impl Trait) { + get(x); + get2(x); + get(y); + get2(y); + get(set(S)); + get2(set(S)); + get2(S::); + } + "#, + expect![[r#" + 49..50 't': T + 77..79 '{}': () + 111..112 't': T + 122..124 '{}': () + 154..155 't': T + 165..168 '{t}': T + 166..167 't': T + 256..257 'x': T + 262..263 'y': impl Trait + 289..397 '{ ...r>); }': () + 295..298 'get': fn get(T) -> ::Type + 295..301 'get(x)': u32 + 299..300 'x': T + 307..311 'get2': fn get2(T) -> u32 + 307..314 'get2(x)': u32 + 312..313 'x': T + 320..323 'get': fn get>(impl Trait) -> as Trait>::Type + 320..326 'get(y)': i64 + 324..325 'y': impl Trait + 332..336 'get2': fn get2>(impl Trait) -> i64 + 332..339 'get2(y)': i64 + 337..338 'y': impl Trait + 345..348 'get': fn get>(S) -> as Trait>::Type + 345..356 'get(set(S))': u64 + 349..352 'set': fn set>(S) -> S + 349..355 'set(S)': S + 353..354 'S': S + 362..366 'get2': fn get2>(S) -> u64 + 362..374 'get2(set(S))': u64 + 367..370 'set': fn set>(S) -> S + 367..373 'set(S)': S + 371..372 'S': S + 380..384 'get2': fn get2>(S) -> str + 380..394 'get2(S::)': str + 385..393 'S::': S + "#]], ); } @@ -1506,27 +1505,27 @@ mod iter { #[test] fn projection_eq_within_chalk() { - assert_snapshot!( - infer(r#" -trait Trait1 { - type Type; -} -trait Trait2 { - fn foo(self) -> T; -} -impl Trait2 for U where U: Trait1 {} + check_infer( + r#" + trait Trait1 { + type Type; + } + trait Trait2 { + fn foo(self) -> T; + } + impl Trait2 for U where U: Trait1 {} -fn test>(x: T) { - x.foo(); -} -"#), - @r###" - 61..65 'self': Self - 163..164 'x': T - 169..185 '{ ...o(); }': () - 175..176 'x': T - 175..182 'x.foo()': u32 - "### + fn test>(x: T) { + x.foo(); + } + "#, + expect![[r#" + 61..65 'self': Self + 163..164 'x': T + 169..185 '{ ...o(); }': () + 175..176 'x': T + 175..182 'x.foo()': u32 + "#]], ); } @@ -1549,445 +1548,445 @@ fn test(x: T) { #[test] fn super_trait_method_resolution() { - assert_snapshot!( - infer(r#" -mod foo { - trait SuperTrait { - fn foo(&self) -> u32 {} - } -} -trait Trait1: foo::SuperTrait {} -trait Trait2 where Self: foo::SuperTrait {} + check_infer( + r#" + mod foo { + trait SuperTrait { + fn foo(&self) -> u32 {} + } + } + trait Trait1: foo::SuperTrait {} + trait Trait2 where Self: foo::SuperTrait {} -fn test(x: T, y: U) { - x.foo(); - y.foo(); -} -"#), - @r###" - 49..53 'self': &Self - 62..64 '{}': () - 181..182 'x': T - 187..188 'y': U - 193..222 '{ ...o(); }': () - 199..200 'x': T - 199..206 'x.foo()': u32 - 212..213 'y': U - 212..219 'y.foo()': u32 - "### + fn test(x: T, y: U) { + x.foo(); + y.foo(); + } + "#, + expect![[r#" + 49..53 'self': &Self + 62..64 '{}': () + 181..182 'x': T + 187..188 'y': U + 193..222 '{ ...o(); }': () + 199..200 'x': T + 199..206 'x.foo()': u32 + 212..213 'y': U + 212..219 'y.foo()': u32 + "#]], ); } #[test] fn super_trait_impl_trait_method_resolution() { - assert_snapshot!( - infer(r#" -mod foo { - trait SuperTrait { - fn foo(&self) -> u32 {} - } -} -trait Trait1: foo::SuperTrait {} + check_infer( + r#" + mod foo { + trait SuperTrait { + fn foo(&self) -> u32 {} + } + } + trait Trait1: foo::SuperTrait {} -fn test(x: &impl Trait1) { - x.foo(); -} -"#), - @r###" - 49..53 'self': &Self - 62..64 '{}': () - 115..116 'x': &impl Trait1 - 132..148 '{ ...o(); }': () - 138..139 'x': &impl Trait1 - 138..145 'x.foo()': u32 - "### + fn test(x: &impl Trait1) { + x.foo(); + } + "#, + expect![[r#" + 49..53 'self': &Self + 62..64 '{}': () + 115..116 'x': &impl Trait1 + 132..148 '{ ...o(); }': () + 138..139 'x': &impl Trait1 + 138..145 'x.foo()': u32 + "#]], ); } #[test] fn super_trait_cycle() { // This just needs to not crash - assert_snapshot!( - infer(r#" -trait A: B {} -trait B: A {} + check_infer( + r#" + trait A: B {} + trait B: A {} -fn test(x: T) { - x.foo(); -} -"#), - @r###" - 43..44 'x': T - 49..65 '{ ...o(); }': () - 55..56 'x': T - 55..62 'x.foo()': {unknown} - "### + fn test(x: T) { + x.foo(); + } + "#, + expect![[r#" + 43..44 'x': T + 49..65 '{ ...o(); }': () + 55..56 'x': T + 55..62 'x.foo()': {unknown} + "#]], ); } #[test] fn super_trait_assoc_type_bounds() { - assert_snapshot!( - infer(r#" -trait SuperTrait { type Type; } -trait Trait where Self: SuperTrait {} + check_infer( + r#" + trait SuperTrait { type Type; } + trait Trait where Self: SuperTrait {} -fn get2>(t: T) -> U {} -fn set>(t: T) -> T {t} + fn get2>(t: T) -> U {} + fn set>(t: T) -> T {t} -struct S; -impl SuperTrait for S { type Type = T; } -impl Trait for S {} + struct S; + impl SuperTrait for S { type Type = T; } + impl Trait for S {} -fn test() { - get2(set(S)); -} -"#), - @r###" - 102..103 't': T - 113..115 '{}': () - 145..146 't': T - 156..159 '{t}': T - 157..158 't': T - 258..279 '{ ...S)); }': () - 264..268 'get2': fn get2>(S) -> u64 - 264..276 'get2(set(S))': u64 - 269..272 'set': fn set>(S) -> S - 269..275 'set(S)': S - 273..274 'S': S - "### + fn test() { + get2(set(S)); + } + "#, + expect![[r#" + 102..103 't': T + 113..115 '{}': () + 145..146 't': T + 156..159 '{t}': T + 157..158 't': T + 258..279 '{ ...S)); }': () + 264..268 'get2': fn get2>(S) -> u64 + 264..276 'get2(set(S))': u64 + 269..272 'set': fn set>(S) -> S + 269..275 'set(S)': S + 273..274 'S': S + "#]], ); } #[test] fn fn_trait() { - assert_snapshot!( - infer(r#" -trait FnOnce { - type Output; + check_infer( + r#" + trait FnOnce { + type Output; - fn call_once(self, args: Args) -> >::Output; -} + fn call_once(self, args: Args) -> >::Output; + } -fn test u128>(f: F) { - f.call_once((1, 2)); -} -"#), - @r###" - 56..60 'self': Self - 62..66 'args': Args - 149..150 'f': F - 155..183 '{ ...2)); }': () - 161..162 'f': F - 161..180 'f.call...1, 2))': u128 - 173..179 '(1, 2)': (u32, u64) - 174..175 '1': u32 - 177..178 '2': u64 - "### + fn test u128>(f: F) { + f.call_once((1, 2)); + } + "#, + expect![[r#" + 56..60 'self': Self + 62..66 'args': Args + 149..150 'f': F + 155..183 '{ ...2)); }': () + 161..162 'f': F + 161..180 'f.call...1, 2))': u128 + 173..179 '(1, 2)': (u32, u64) + 174..175 '1': u32 + 177..178 '2': u64 + "#]], ); } #[test] fn fn_ptr_and_item() { - assert_snapshot!( - infer(r#" -#[lang="fn_once"] -trait FnOnce { - type Output; + check_infer( + r#" + #[lang="fn_once"] + trait FnOnce { + type Output; - fn call_once(self, args: Args) -> Self::Output; -} + fn call_once(self, args: Args) -> Self::Output; + } -trait Foo { - fn foo(&self) -> T; -} + trait Foo { + fn foo(&self) -> T; + } -struct Bar(T); + struct Bar(T); -impl R> Foo<(A1, R)> for Bar { - fn foo(&self) -> (A1, R) {} -} + impl R> Foo<(A1, R)> for Bar { + fn foo(&self) -> (A1, R) {} + } -enum Opt { None, Some(T) } -impl Opt { - fn map U>(self, f: F) -> Opt {} -} + enum Opt { None, Some(T) } + impl Opt { + fn map U>(self, f: F) -> Opt {} + } -fn test() { - let bar: Bar u32>; - bar.foo(); - - let opt: Opt; - let f: fn(u8) -> u32; - opt.map(f); -} -"#), - @r###" - 74..78 'self': Self - 80..84 'args': Args - 139..143 'self': &Self - 243..247 'self': &Bar - 260..262 '{}': () - 346..350 'self': Opt - 352..353 'f': F - 368..370 '{}': () - 384..500 '{ ...(f); }': () - 394..397 'bar': Bar u32> - 423..426 'bar': Bar u32> - 423..432 'bar.foo()': (u8, u32) - 443..446 'opt': Opt - 465..466 'f': fn(u8) -> u32 - 487..490 'opt': Opt - 487..497 'opt.map(f)': Opt - 495..496 'f': fn(u8) -> u32 - "### + fn test() { + let bar: Bar u32>; + bar.foo(); + + let opt: Opt; + let f: fn(u8) -> u32; + opt.map(f); + } + "#, + expect![[r#" + 74..78 'self': Self + 80..84 'args': Args + 139..143 'self': &Self + 243..247 'self': &Bar + 260..262 '{}': () + 346..350 'self': Opt + 352..353 'f': F + 368..370 '{}': () + 384..500 '{ ...(f); }': () + 394..397 'bar': Bar u32> + 423..426 'bar': Bar u32> + 423..432 'bar.foo()': (u8, u32) + 443..446 'opt': Opt + 465..466 'f': fn(u8) -> u32 + 487..490 'opt': Opt + 487..497 'opt.map(f)': Opt + 495..496 'f': fn(u8) -> u32 + "#]], ); } #[test] fn fn_trait_deref_with_ty_default() { - assert_snapshot!( - infer(r#" -#[lang = "deref"] -trait Deref { - type Target; + check_infer( + r#" + #[lang = "deref"] + trait Deref { + type Target; - fn deref(&self) -> &Self::Target; -} + fn deref(&self) -> &Self::Target; + } -#[lang="fn_once"] -trait FnOnce { - type Output; + #[lang="fn_once"] + trait FnOnce { + type Output; - fn call_once(self, args: Args) -> Self::Output; -} + fn call_once(self, args: Args) -> Self::Output; + } -struct Foo; + struct Foo; -impl Foo { - fn foo(&self) -> usize {} -} + impl Foo { + fn foo(&self) -> usize {} + } -struct Lazy T>(F); + struct Lazy T>(F); -impl Lazy { - pub fn new(f: F) -> Lazy {} -} + impl Lazy { + pub fn new(f: F) -> Lazy {} + } -impl T> Deref for Lazy { - type Target = T; -} + impl T> Deref for Lazy { + type Target = T; + } -fn test() { - let lazy1: Lazy = Lazy::new(|| Foo); - let r1 = lazy1.foo(); - - fn make_foo_fn() -> Foo {} - let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; - let lazy2: Lazy = Lazy::new(make_foo_fn_ptr); - let r2 = lazy2.foo(); -} -"#), - @r###" - 64..68 'self': &Self - 165..169 'self': Self - 171..175 'args': Args - 239..243 'self': &Foo - 254..256 '{}': () - 334..335 'f': F - 354..356 '{}': () - 443..689 '{ ...o(); }': () - 453..458 'lazy1': Lazy Foo> - 475..484 'Lazy::new': fn new Foo>(|| -> Foo) -> Lazy Foo> - 475..492 'Lazy::...| Foo)': Lazy Foo> - 485..491 '|| Foo': || -> Foo - 488..491 'Foo': Foo - 502..504 'r1': usize - 507..512 'lazy1': Lazy Foo> - 507..518 'lazy1.foo()': usize - 560..575 'make_foo_fn_ptr': fn() -> Foo - 591..602 'make_foo_fn': fn make_foo_fn() -> Foo - 612..617 'lazy2': Lazy Foo> - 634..643 'Lazy::new': fn new Foo>(fn() -> Foo) -> Lazy Foo> - 634..660 'Lazy::...n_ptr)': Lazy Foo> - 644..659 'make_foo_fn_ptr': fn() -> Foo - 670..672 'r2': usize - 675..680 'lazy2': Lazy Foo> - 675..686 'lazy2.foo()': usize - 549..551 '{}': () - "### + fn test() { + let lazy1: Lazy = Lazy::new(|| Foo); + let r1 = lazy1.foo(); + + fn make_foo_fn() -> Foo {} + let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; + let lazy2: Lazy = Lazy::new(make_foo_fn_ptr); + let r2 = lazy2.foo(); + } + "#, + expect![[r#" + 64..68 'self': &Self + 165..169 'self': Self + 171..175 'args': Args + 239..243 'self': &Foo + 254..256 '{}': () + 334..335 'f': F + 354..356 '{}': () + 443..689 '{ ...o(); }': () + 453..458 'lazy1': Lazy Foo> + 475..484 'Lazy::new': fn new Foo>(|| -> Foo) -> Lazy Foo> + 475..492 'Lazy::...| Foo)': Lazy Foo> + 485..491 '|| Foo': || -> Foo + 488..491 'Foo': Foo + 502..504 'r1': usize + 507..512 'lazy1': Lazy Foo> + 507..518 'lazy1.foo()': usize + 560..575 'make_foo_fn_ptr': fn() -> Foo + 591..602 'make_foo_fn': fn make_foo_fn() -> Foo + 612..617 'lazy2': Lazy Foo> + 634..643 'Lazy::new': fn new Foo>(fn() -> Foo) -> Lazy Foo> + 634..660 'Lazy::...n_ptr)': Lazy Foo> + 644..659 'make_foo_fn_ptr': fn() -> Foo + 670..672 'r2': usize + 675..680 'lazy2': Lazy Foo> + 675..686 'lazy2.foo()': usize + 549..551 '{}': () + "#]], ); } #[test] fn closure_1() { - assert_snapshot!( - infer(r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} + check_infer( + r#" + #[lang = "fn_once"] + trait FnOnce { + type Output; + } -enum Option { Some(T), None } -impl Option { - fn map U>(self, f: F) -> Option {} -} + enum Option { Some(T), None } + impl Option { + fn map U>(self, f: F) -> Option {} + } -fn test() { - let x = Option::Some(1u32); - x.map(|v| v + 1); - x.map(|_v| 1u64); - let y: Option = x.map(|_v| 1); -} -"#), - @r###" - 147..151 'self': Option - 153..154 'f': F - 172..174 '{}': () - 188..307 '{ ... 1); }': () - 198..199 'x': Option - 202..214 'Option::Some': Some(u32) -> Option - 202..220 'Option...(1u32)': Option - 215..219 '1u32': u32 - 226..227 'x': Option - 226..242 'x.map(...v + 1)': Option - 232..241 '|v| v + 1': |u32| -> u32 - 233..234 'v': u32 - 236..237 'v': u32 - 236..241 'v + 1': u32 - 240..241 '1': u32 - 248..249 'x': Option - 248..264 'x.map(... 1u64)': Option - 254..263 '|_v| 1u64': |u32| -> u64 - 255..257 '_v': u32 - 259..263 '1u64': u64 - 274..275 'y': Option - 291..292 'x': Option - 291..304 'x.map(|_v| 1)': Option - 297..303 '|_v| 1': |u32| -> i64 - 298..300 '_v': u32 - 302..303 '1': i64 - "### + fn test() { + let x = Option::Some(1u32); + x.map(|v| v + 1); + x.map(|_v| 1u64); + let y: Option = x.map(|_v| 1); + } + "#, + expect![[r#" + 147..151 'self': Option + 153..154 'f': F + 172..174 '{}': () + 188..307 '{ ... 1); }': () + 198..199 'x': Option + 202..214 'Option::Some': Some(u32) -> Option + 202..220 'Option...(1u32)': Option + 215..219 '1u32': u32 + 226..227 'x': Option + 226..242 'x.map(...v + 1)': Option + 232..241 '|v| v + 1': |u32| -> u32 + 233..234 'v': u32 + 236..237 'v': u32 + 236..241 'v + 1': u32 + 240..241 '1': u32 + 248..249 'x': Option + 248..264 'x.map(... 1u64)': Option + 254..263 '|_v| 1u64': |u32| -> u64 + 255..257 '_v': u32 + 259..263 '1u64': u64 + 274..275 'y': Option + 291..292 'x': Option + 291..304 'x.map(|_v| 1)': Option + 297..303 '|_v| 1': |u32| -> i64 + 298..300 '_v': u32 + 302..303 '1': i64 + "#]], ); } #[test] fn closure_2() { - assert_snapshot!( - infer(r#" -trait FnOnce { - type Output; -} + check_infer( + r#" + trait FnOnce { + type Output; + } -fn test u64>(f: F) { - f(1); - let g = |v| v + 1; - g(1u64); - let h = |v| 1u128 + v; -} -"#), - @r###" - 72..73 'f': F - 78..154 '{ ...+ v; }': () - 84..85 'f': F - 84..88 'f(1)': {unknown} - 86..87 '1': i32 - 98..99 'g': |u64| -> i32 - 102..111 '|v| v + 1': |u64| -> i32 - 103..104 'v': u64 - 106..107 'v': u64 - 106..111 'v + 1': i32 - 110..111 '1': i32 - 117..118 'g': |u64| -> i32 - 117..124 'g(1u64)': i32 - 119..123 '1u64': u64 - 134..135 'h': |u128| -> u128 - 138..151 '|v| 1u128 + v': |u128| -> u128 - 139..140 'v': u128 - 142..147 '1u128': u128 - 142..151 '1u128 + v': u128 - 150..151 'v': u128 - "### + fn test u64>(f: F) { + f(1); + let g = |v| v + 1; + g(1u64); + let h = |v| 1u128 + v; + } + "#, + expect![[r#" + 72..73 'f': F + 78..154 '{ ...+ v; }': () + 84..85 'f': F + 84..88 'f(1)': {unknown} + 86..87 '1': i32 + 98..99 'g': |u64| -> i32 + 102..111 '|v| v + 1': |u64| -> i32 + 103..104 'v': u64 + 106..107 'v': u64 + 106..111 'v + 1': i32 + 110..111 '1': i32 + 117..118 'g': |u64| -> i32 + 117..124 'g(1u64)': i32 + 119..123 '1u64': u64 + 134..135 'h': |u128| -> u128 + 138..151 '|v| 1u128 + v': |u128| -> u128 + 139..140 'v': u128 + 142..147 '1u128': u128 + 142..151 '1u128 + v': u128 + 150..151 'v': u128 + "#]], ); } #[test] fn closure_as_argument_inference_order() { - assert_snapshot!( - infer(r#" -#[lang = "fn_once"] -trait FnOnce { - type Output; -} + check_infer( + r#" + #[lang = "fn_once"] + trait FnOnce { + type Output; + } -fn foo1 U>(x: T, f: F) -> U {} -fn foo2 U>(f: F, x: T) -> U {} + fn foo1 U>(x: T, f: F) -> U {} + fn foo2 U>(f: F, x: T) -> U {} -struct S; -impl S { - fn method(self) -> u64; + struct S; + impl S { + fn method(self) -> u64; - fn foo1 U>(self, x: T, f: F) -> U {} - fn foo2 U>(self, f: F, x: T) -> U {} -} + fn foo1 U>(self, x: T, f: F) -> U {} + fn foo2 U>(self, f: F, x: T) -> U {} + } -fn test() { - let x1 = foo1(S, |s| s.method()); - let x2 = foo2(|s| s.method(), S); - let x3 = S.foo1(S, |s| s.method()); - let x4 = S.foo2(|s| s.method(), S); -} -"#), - @r###" - 94..95 'x': T - 100..101 'f': F - 111..113 '{}': () - 147..148 'f': F - 153..154 'x': T - 164..166 '{}': () - 201..205 'self': S - 253..257 'self': S - 259..260 'x': T - 265..266 'f': F - 276..278 '{}': () - 316..320 'self': S - 322..323 'f': F - 328..329 'x': T - 339..341 '{}': () - 355..514 '{ ... S); }': () - 365..367 'x1': u64 - 370..374 'foo1': fn foo1 u64>(S, |S| -> u64) -> u64 - 370..393 'foo1(S...hod())': u64 - 375..376 'S': S - 378..392 '|s| s.method()': |S| -> u64 - 379..380 's': S - 382..383 's': S - 382..392 's.method()': u64 - 403..405 'x2': u64 - 408..412 'foo2': fn foo2 u64>(|S| -> u64, S) -> u64 - 408..431 'foo2(|...(), S)': u64 - 413..427 '|s| s.method()': |S| -> u64 - 414..415 's': S - 417..418 's': S - 417..427 's.method()': u64 - 429..430 'S': S - 441..443 'x3': u64 - 446..447 'S': S - 446..471 'S.foo1...hod())': u64 - 453..454 'S': S - 456..470 '|s| s.method()': |S| -> u64 - 457..458 's': S - 460..461 's': S - 460..470 's.method()': u64 - 481..483 'x4': u64 - 486..487 'S': S - 486..511 'S.foo2...(), S)': u64 - 493..507 '|s| s.method()': |S| -> u64 - 494..495 's': S - 497..498 's': S - 497..507 's.method()': u64 - 509..510 'S': S - "### + fn test() { + let x1 = foo1(S, |s| s.method()); + let x2 = foo2(|s| s.method(), S); + let x3 = S.foo1(S, |s| s.method()); + let x4 = S.foo2(|s| s.method(), S); + } + "#, + expect![[r#" + 94..95 'x': T + 100..101 'f': F + 111..113 '{}': () + 147..148 'f': F + 153..154 'x': T + 164..166 '{}': () + 201..205 'self': S + 253..257 'self': S + 259..260 'x': T + 265..266 'f': F + 276..278 '{}': () + 316..320 'self': S + 322..323 'f': F + 328..329 'x': T + 339..341 '{}': () + 355..514 '{ ... S); }': () + 365..367 'x1': u64 + 370..374 'foo1': fn foo1 u64>(S, |S| -> u64) -> u64 + 370..393 'foo1(S...hod())': u64 + 375..376 'S': S + 378..392 '|s| s.method()': |S| -> u64 + 379..380 's': S + 382..383 's': S + 382..392 's.method()': u64 + 403..405 'x2': u64 + 408..412 'foo2': fn foo2 u64>(|S| -> u64, S) -> u64 + 408..431 'foo2(|...(), S)': u64 + 413..427 '|s| s.method()': |S| -> u64 + 414..415 's': S + 417..418 's': S + 417..427 's.method()': u64 + 429..430 'S': S + 441..443 'x3': u64 + 446..447 'S': S + 446..471 'S.foo1...hod())': u64 + 453..454 'S': S + 456..470 '|s| s.method()': |S| -> u64 + 457..458 's': S + 460..461 's': S + 460..470 's.method()': u64 + 481..483 'x4': u64 + 486..487 'S': S + 486..511 'S.foo2...(), S)': u64 + 493..507 '|s| s.method()': |S| -> u64 + 494..495 's': S + 497..498 's': S + 497..507 's.method()': u64 + 509..510 'S': S + "#]], ); } @@ -2056,43 +2055,44 @@ fn test() where T::Item: Trait2, T: Trait, U: Trait<()> { #[test] fn unselected_projection_on_impl_self() { - assert_snapshot!(infer( + check_infer( r#" -//- /main.rs -trait Trait { - type Item; + //- /main.rs + trait Trait { + type Item; - fn f(&self, x: Self::Item); -} + fn f(&self, x: Self::Item); + } -struct S; + struct S; -impl Trait for S { - type Item = u32; - fn f(&self, x: Self::Item) { let y = x; } -} + impl Trait for S { + type Item = u32; + fn f(&self, x: Self::Item) { let y = x; } + } -struct S2; + struct S2; -impl Trait for S2 { - type Item = i32; - fn f(&self, x: ::Item) { let y = x; } -} -"#, - ), @r###" - 40..44 'self': &Self - 46..47 'x': Trait::Item - 126..130 'self': &S - 132..133 'x': u32 - 147..161 '{ let y = x; }': () - 153..154 'y': u32 - 157..158 'x': u32 - 228..232 'self': &S2 - 234..235 'x': i32 - 251..265 '{ let y = x; }': () - 257..258 'y': i32 - 261..262 'x': i32 - "###); + impl Trait for S2 { + type Item = i32; + fn f(&self, x: ::Item) { let y = x; } + } + "#, + expect![[r#" + 40..44 'self': &Self + 46..47 'x': Trait::Item + 126..130 'self': &S + 132..133 'x': u32 + 147..161 '{ let y = x; }': () + 153..154 'y': u32 + 157..158 'x': u32 + 228..232 'self': &S2 + 234..235 'x': i32 + 251..265 '{ let y = x; }': () + 257..258 'y': i32 + 261..262 'x': i32 + "#]], + ); } #[test] @@ -2261,170 +2261,170 @@ fn test>>() { #[test] fn proc_macro_server_types() { - assert_snapshot!( - infer(r#" -macro_rules! with_api { - ($S:ident, $self:ident, $m:ident) => { - $m! { - TokenStream { - fn new() -> $S::TokenStream; - }, - Group { - }, - } - }; -} -macro_rules! associated_item { - (type TokenStream) => - (type TokenStream: 'static;); - (type Group) => - (type Group: 'static;); - ($($item:tt)*) => ($($item)*;) -} -macro_rules! declare_server_traits { - ($($name:ident { - $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* - }),* $(,)?) => { - pub trait Types { - $(associated_item!(type $name);)* - } - - $(pub trait $name: Types { - $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* - })* - - pub trait Server: Types $(+ $name)* {} - impl Server for S {} - } -} + check_infer( + r#" + macro_rules! with_api { + ($S:ident, $self:ident, $m:ident) => { + $m! { + TokenStream { + fn new() -> $S::TokenStream; + }, + Group { + }, + } + }; + } + macro_rules! associated_item { + (type TokenStream) => + (type TokenStream: 'static;); + (type Group) => + (type Group: 'static;); + ($($item:tt)*) => ($($item)*;) + } + macro_rules! declare_server_traits { + ($($name:ident { + $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* + }),* $(,)?) => { + pub trait Types { + $(associated_item!(type $name);)* + } -with_api!(Self, self_, declare_server_traits); -struct G {} -struct T {} -struct Rustc; -impl Types for Rustc { - type TokenStream = T; - type Group = G; -} + $(pub trait $name: Types { + $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* + })* -fn make() -> T { loop {} } -impl TokenStream for Rustc { - fn new() -> Self::TokenStream { - let group: Self::Group = make(); - make() - } -} -"#), - @r###" - 1061..1072 '{ loop {} }': T - 1063..1070 'loop {}': ! - 1068..1070 '{}': () - 1136..1199 '{ ... }': T - 1150..1155 'group': G - 1171..1175 'make': fn make() -> G - 1171..1177 'make()': G - 1187..1191 'make': fn make() -> T - 1187..1193 'make()': T - "### + pub trait Server: Types $(+ $name)* {} + impl Server for S {} + } + } + + with_api!(Self, self_, declare_server_traits); + struct G {} + struct T {} + struct Rustc; + impl Types for Rustc { + type TokenStream = T; + type Group = G; + } + + fn make() -> T { loop {} } + impl TokenStream for Rustc { + fn new() -> Self::TokenStream { + let group: Self::Group = make(); + make() + } + } + "#, + expect![[r#" + 1061..1072 '{ loop {} }': T + 1063..1070 'loop {}': ! + 1068..1070 '{}': () + 1136..1199 '{ ... }': T + 1150..1155 'group': G + 1171..1175 'make': fn make() -> G + 1171..1177 'make()': G + 1187..1191 'make': fn make() -> T + 1187..1193 'make()': T + "#]], ); } #[test] fn unify_impl_trait() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Trait {} + check_infer_with_mismatches( + r#" + trait Trait {} + + fn foo(x: impl Trait) { loop {} } + fn bar(x: impl Trait) -> T { loop {} } + + struct S(T); + impl Trait for S {} + + fn default() -> T { loop {} } -fn foo(x: impl Trait) { loop {} } -fn bar(x: impl Trait) -> T { loop {} } - -struct S(T); -impl Trait for S {} - -fn default() -> T { loop {} } - -fn test() -> impl Trait { - let s1 = S(default()); - foo(s1); - let x: i32 = bar(S(default())); - S(default()) -} -"#, true), - @r###" - 26..27 'x': impl Trait - 46..57 '{ loop {} }': () - 48..55 'loop {}': ! - 53..55 '{}': () - 68..69 'x': impl Trait - 91..102 '{ loop {} }': T - 93..100 'loop {}': ! - 98..100 '{}': () - 171..182 '{ loop {} }': T - 173..180 'loop {}': ! - 178..180 '{}': () - 213..309 '{ ...t()) }': S<{unknown}> - 223..225 's1': S - 228..229 'S': S(u32) -> S - 228..240 'S(default())': S - 230..237 'default': fn default() -> u32 - 230..239 'default()': u32 - 246..249 'foo': fn foo(S) - 246..253 'foo(s1)': () - 250..252 's1': S - 263..264 'x': i32 - 272..275 'bar': fn bar(S) -> i32 - 272..289 'bar(S(...lt()))': i32 - 276..277 'S': S(i32) -> S - 276..288 'S(default())': S - 278..285 'default': fn default() -> i32 - 278..287 'default()': i32 - 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> - 295..307 'S(default())': S<{unknown}> - 297..304 'default': fn default<{unknown}>() -> {unknown} - 297..306 'default()': {unknown} - "### + fn test() -> impl Trait { + let s1 = S(default()); + foo(s1); + let x: i32 = bar(S(default())); + S(default()) + } + "#, + expect![[r#" + 26..27 'x': impl Trait + 46..57 '{ loop {} }': () + 48..55 'loop {}': ! + 53..55 '{}': () + 68..69 'x': impl Trait + 91..102 '{ loop {} }': T + 93..100 'loop {}': ! + 98..100 '{}': () + 171..182 '{ loop {} }': T + 173..180 'loop {}': ! + 178..180 '{}': () + 213..309 '{ ...t()) }': S<{unknown}> + 223..225 's1': S + 228..229 'S': S(u32) -> S + 228..240 'S(default())': S + 230..237 'default': fn default() -> u32 + 230..239 'default()': u32 + 246..249 'foo': fn foo(S) + 246..253 'foo(s1)': () + 250..252 's1': S + 263..264 'x': i32 + 272..275 'bar': fn bar(S) -> i32 + 272..289 'bar(S(...lt()))': i32 + 276..277 'S': S(i32) -> S + 276..288 'S(default())': S + 278..285 'default': fn default() -> i32 + 278..287 'default()': i32 + 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> + 295..307 'S(default())': S<{unknown}> + 297..304 'default': fn default<{unknown}>() -> {unknown} + 297..306 'default()': {unknown} + "#]], ); } #[test] fn assoc_types_from_bounds() { - assert_snapshot!( - infer(r#" -//- /main.rs -#[lang = "fn_once"] -trait FnOnce { - type Output; -} + check_infer( + r#" + //- /main.rs + #[lang = "fn_once"] + trait FnOnce { + type Output; + } -trait T { - type O; -} + trait T { + type O; + } -impl T for () { - type O = (); -} + impl T for () { + type O = (); + } -fn f(_v: F) -where - X: T, - F: FnOnce(&X::O), -{ } + fn f(_v: F) + where + X: T, + F: FnOnce(&X::O), + { } -fn main() { - f::<(), _>(|z| { z; }); -} -"#), - @r###" - 133..135 '_v': F - 178..181 '{ }': () - 193..224 '{ ... }); }': () - 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) - 199..221 'f::<()... z; })': () - 210..220 '|z| { z; }': |&()| -> () - 211..212 'z': &() - 214..220 '{ z; }': () - 216..217 'z': &() - "### + fn main() { + f::<(), _>(|z| { z; }); + } + "#, + expect![[r#" + 133..135 '_v': F + 178..181 '{ }': () + 193..224 '{ ... }); }': () + 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) + 199..221 'f::<()... z; })': () + 210..220 '|z| { z; }': |&()| -> () + 211..212 'z': &() + 214..220 '{ z; }': () + 216..217 'z': &() + "#]], ); } @@ -2497,120 +2497,120 @@ fn test() { #[test] fn iterator_chain() { - assert_snapshot!( - infer(r#" -//- /main.rs -#[lang = "fn_once"] -trait FnOnce { - type Output; -} -#[lang = "fn_mut"] -trait FnMut: FnOnce { } + check_infer( + r#" + //- /main.rs + #[lang = "fn_once"] + trait FnOnce { + type Output; + } + #[lang = "fn_mut"] + trait FnMut: FnOnce { } -enum Option { Some(T), None } -use Option::*; + enum Option { Some(T), None } + use Option::*; -pub trait Iterator { - type Item; + pub trait Iterator { + type Item; - fn filter_map(self, f: F) -> FilterMap - where - F: FnMut(Self::Item) -> Option, - { loop {} } + fn filter_map(self, f: F) -> FilterMap + where + F: FnMut(Self::Item) -> Option, + { loop {} } - fn for_each(self, f: F) - where - F: FnMut(Self::Item), - { loop {} } -} + fn for_each(self, f: F) + where + F: FnMut(Self::Item), + { loop {} } + } -pub trait IntoIterator { - type Item; - type IntoIter: Iterator; - fn into_iter(self) -> Self::IntoIter; -} + pub trait IntoIterator { + type Item; + type IntoIter: Iterator; + fn into_iter(self) -> Self::IntoIter; + } -pub struct FilterMap { } -impl Iterator for FilterMap -where - F: FnMut(I::Item) -> Option, -{ - type Item = B; -} + pub struct FilterMap { } + impl Iterator for FilterMap + where + F: FnMut(I::Item) -> Option, + { + type Item = B; + } -#[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for I { - type Item = I::Item; - type IntoIter = I; + #[stable(feature = "rust1", since = "1.0.0")] + impl IntoIterator for I { + type Item = I::Item; + type IntoIter = I; - fn into_iter(self) -> I { - self - } -} + fn into_iter(self) -> I { + self + } + } -struct Vec {} -impl Vec { - fn new() -> Self { loop {} } -} + struct Vec {} + impl Vec { + fn new() -> Self { loop {} } + } -impl IntoIterator for Vec { - type Item = T; - type IntoIter = IntoIter; -} + impl IntoIterator for Vec { + type Item = T; + type IntoIter = IntoIter; + } -pub struct IntoIter { } -impl Iterator for IntoIter { - type Item = T; -} + pub struct IntoIter { } + impl Iterator for IntoIter { + type Item = T; + } -fn main() { - Vec::::new().into_iter() - .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) - .for_each(|y| { y; }); -} -"#), - @r###" - 226..230 'self': Self - 232..233 'f': F - 317..328 '{ loop {} }': FilterMap - 319..326 'loop {}': ! - 324..326 '{}': () - 349..353 'self': Self - 355..356 'f': F - 405..416 '{ loop {} }': () - 407..414 'loop {}': ! - 412..414 '{}': () - 525..529 'self': Self - 854..858 'self': I - 865..885 '{ ... }': I - 875..879 'self': I - 944..955 '{ loop {} }': Vec - 946..953 'loop {}': ! - 951..953 '{}': () - 1142..1273 '{ ... }); }': () - 1148..1163 'Vec::::new': fn new() -> Vec - 1148..1165 'Vec::<...:new()': Vec - 1148..1177 'Vec::<...iter()': IntoIter - 1148..1242 'Vec::<...one })': FilterMap, |i32| -> Option> - 1148..1270 'Vec::<... y; })': () - 1196..1241 '|x| if...None }': |i32| -> Option - 1197..1198 'x': i32 - 1200..1241 'if x >...None }': Option - 1203..1204 'x': i32 - 1203..1208 'x > 0': bool - 1207..1208 '0': i32 - 1209..1227 '{ Some...u32) }': Option - 1211..1215 'Some': Some(u32) -> Option - 1211..1225 'Some(x as u32)': Option - 1216..1217 'x': i32 - 1216..1224 'x as u32': u32 - 1233..1241 '{ None }': Option - 1235..1239 'None': Option - 1259..1269 '|y| { y; }': |u32| -> () - 1260..1261 'y': u32 - 1263..1269 '{ y; }': () - 1265..1266 'y': u32 - "### + fn main() { + Vec::::new().into_iter() + .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) + .for_each(|y| { y; }); + } + "#, + expect![[r#" + 226..230 'self': Self + 232..233 'f': F + 317..328 '{ loop {} }': FilterMap + 319..326 'loop {}': ! + 324..326 '{}': () + 349..353 'self': Self + 355..356 'f': F + 405..416 '{ loop {} }': () + 407..414 'loop {}': ! + 412..414 '{}': () + 525..529 'self': Self + 854..858 'self': I + 865..885 '{ ... }': I + 875..879 'self': I + 944..955 '{ loop {} }': Vec + 946..953 'loop {}': ! + 951..953 '{}': () + 1142..1269 '{ ... }); }': () + 1148..1163 'Vec::::new': fn new() -> Vec + 1148..1165 'Vec::<...:new()': Vec + 1148..1177 'Vec::<...iter()': IntoIter + 1148..1240 'Vec::<...one })': FilterMap, |i32| -> Option> + 1148..1266 'Vec::<... y; })': () + 1194..1239 '|x| if...None }': |i32| -> Option + 1195..1196 'x': i32 + 1198..1239 'if x >...None }': Option + 1201..1202 'x': i32 + 1201..1206 'x > 0': bool + 1205..1206 '0': i32 + 1207..1225 '{ Some...u32) }': Option + 1209..1213 'Some': Some(u32) -> Option + 1209..1223 'Some(x as u32)': Option + 1214..1215 'x': i32 + 1214..1222 'x as u32': u32 + 1231..1239 '{ None }': Option + 1233..1237 'None': Option + 1255..1265 '|y| { y; }': |u32| -> () + 1256..1257 'y': u32 + 1259..1265 '{ y; }': () + 1261..1262 'y': u32 + "#]], ); } @@ -2648,176 +2648,176 @@ fn main() { #[test] fn trait_object_no_coercion() { - assert_snapshot!( - infer_with_mismatches(r#" -trait Foo {} + check_infer_with_mismatches( + r#" + trait Foo {} -fn foo(x: &dyn Foo) {} + fn foo(x: &dyn Foo) {} -fn test(x: &dyn Foo) { - foo(x); -} -"#, true), - @r###" - 21..22 'x': &dyn Foo - 34..36 '{}': () - 46..47 'x': &dyn Foo - 59..74 '{ foo(x); }': () - 65..68 'foo': fn foo(&dyn Foo) - 65..71 'foo(x)': () - 69..70 'x': &dyn Foo - "### + fn test(x: &dyn Foo) { + foo(x); + } + "#, + expect![[r#" + 21..22 'x': &dyn Foo + 34..36 '{}': () + 46..47 'x': &dyn Foo + 59..74 '{ foo(x); }': () + 65..68 'foo': fn foo(&dyn Foo) + 65..71 'foo(x)': () + 69..70 'x': &dyn Foo + "#]], ); } #[test] fn builtin_copy() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "copy"] -trait Copy {} + check_infer_with_mismatches( + r#" + #[lang = "copy"] + trait Copy {} -struct IsCopy; -impl Copy for IsCopy {} -struct NotCopy; + struct IsCopy; + impl Copy for IsCopy {} + struct NotCopy; -trait Test { fn test(&self) -> bool; } -impl Test for T {} + trait Test { fn test(&self) -> bool; } + impl Test for T {} -fn test() { - IsCopy.test(); - NotCopy.test(); - (IsCopy, IsCopy).test(); - (IsCopy, NotCopy).test(); -} -"#, true), - @r###" - 110..114 'self': &Self - 166..267 '{ ...t(); }': () - 172..178 'IsCopy': IsCopy - 172..185 'IsCopy.test()': bool - 191..198 'NotCopy': NotCopy - 191..205 'NotCopy.test()': {unknown} - 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) - 211..234 '(IsCop...test()': bool - 212..218 'IsCopy': IsCopy - 220..226 'IsCopy': IsCopy - 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) - 240..264 '(IsCop...test()': {unknown} - 241..247 'IsCopy': IsCopy - 249..256 'NotCopy': NotCopy - "### + fn test() { + IsCopy.test(); + NotCopy.test(); + (IsCopy, IsCopy).test(); + (IsCopy, NotCopy).test(); + } + "#, + expect![[r#" + 110..114 'self': &Self + 166..267 '{ ...t(); }': () + 172..178 'IsCopy': IsCopy + 172..185 'IsCopy.test()': bool + 191..198 'NotCopy': NotCopy + 191..205 'NotCopy.test()': {unknown} + 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) + 211..234 '(IsCop...test()': bool + 212..218 'IsCopy': IsCopy + 220..226 'IsCopy': IsCopy + 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) + 240..264 '(IsCop...test()': {unknown} + 241..247 'IsCopy': IsCopy + 249..256 'NotCopy': NotCopy + "#]], ); } #[test] fn builtin_fn_def_copy() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "copy"] -trait Copy {} - -fn foo() {} -fn bar(T) -> T {} -struct Struct(usize); -enum Enum { Variant(usize) } - -trait Test { fn test(&self) -> bool; } -impl Test for T {} - -fn test() { - foo.test(); - bar.test(); - Struct.test(); - Enum::Variant.test(); -} -"#, true), - @r###" - 41..43 '{}': () - 60..61 'T': {unknown} - 68..70 '{}': () - 68..70: expected T, got () - 145..149 'self': &Self - 201..281 '{ ...t(); }': () - 207..210 'foo': fn foo() - 207..217 'foo.test()': bool - 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} - 223..233 'bar.test()': bool - 239..245 'Struct': Struct(usize) -> Struct - 239..252 'Struct.test()': bool - 258..271 'Enum::Variant': Variant(usize) -> Enum - 258..278 'Enum::...test()': bool - "### + check_infer_with_mismatches( + r#" + #[lang = "copy"] + trait Copy {} + + fn foo() {} + fn bar(T) -> T {} + struct Struct(usize); + enum Enum { Variant(usize) } + + trait Test { fn test(&self) -> bool; } + impl Test for T {} + + fn test() { + foo.test(); + bar.test(); + Struct.test(); + Enum::Variant.test(); + } + "#, + expect![[r#" + 41..43 '{}': () + 60..61 'T': {unknown} + 68..70 '{}': () + 68..70: expected T, got () + 145..149 'self': &Self + 201..281 '{ ...t(); }': () + 207..210 'foo': fn foo() + 207..217 'foo.test()': bool + 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} + 223..233 'bar.test()': bool + 239..245 'Struct': Struct(usize) -> Struct + 239..252 'Struct.test()': bool + 258..271 'Enum::Variant': Variant(usize) -> Enum + 258..278 'Enum::...test()': bool + "#]], ); } #[test] fn builtin_fn_ptr_copy() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "copy"] -trait Copy {} + check_infer_with_mismatches( + r#" + #[lang = "copy"] + trait Copy {} -trait Test { fn test(&self) -> bool; } -impl Test for T {} + trait Test { fn test(&self) -> bool; } + impl Test for T {} -fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { - f1.test(); - f2.test(); - f3.test(); -} -"#, true), - @r###" - 54..58 'self': &Self - 108..110 'f1': fn() - 118..120 'f2': fn(usize) -> u8 - 139..141 'f3': fn(u8, u8) -> &u8 - 162..210 '{ ...t(); }': () - 168..170 'f1': fn() - 168..177 'f1.test()': bool - 183..185 'f2': fn(usize) -> u8 - 183..192 'f2.test()': bool - 198..200 'f3': fn(u8, u8) -> &u8 - 198..207 'f3.test()': bool - "### + fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { + f1.test(); + f2.test(); + f3.test(); + } + "#, + expect![[r#" + 54..58 'self': &Self + 108..110 'f1': fn() + 118..120 'f2': fn(usize) -> u8 + 139..141 'f3': fn(u8, u8) -> &u8 + 162..210 '{ ...t(); }': () + 168..170 'f1': fn() + 168..177 'f1.test()': bool + 183..185 'f2': fn(usize) -> u8 + 183..192 'f2.test()': bool + 198..200 'f3': fn(u8, u8) -> &u8 + 198..207 'f3.test()': bool + "#]], ); } #[test] fn builtin_sized() { - assert_snapshot!( - infer_with_mismatches(r#" -#[lang = "sized"] -trait Sized {} + check_infer_with_mismatches( + r#" + #[lang = "sized"] + trait Sized {} -trait Test { fn test(&self) -> bool; } -impl Test for T {} + trait Test { fn test(&self) -> bool; } + impl Test for T {} -fn test() { - 1u8.test(); - (*"foo").test(); // not Sized - (1u8, 1u8).test(); - (1u8, *"foo").test(); // not Sized -} -"#, true), - @r###" - 56..60 'self': &Self - 113..228 '{ ...ized }': () - 119..122 '1u8': u8 - 119..129 '1u8.test()': bool - 135..150 '(*"foo").test()': {unknown} - 136..142 '*"foo"': str - 137..142 '"foo"': &str - 169..179 '(1u8, 1u8)': (u8, u8) - 169..186 '(1u8, ...test()': bool - 170..173 '1u8': u8 - 175..178 '1u8': u8 - 192..205 '(1u8, *"foo")': (u8, str) - 192..212 '(1u8, ...test()': {unknown} - 193..196 '1u8': u8 - 198..204 '*"foo"': str - 199..204 '"foo"': &str - "### + fn test() { + 1u8.test(); + (*"foo").test(); // not Sized + (1u8, 1u8).test(); + (1u8, *"foo").test(); // not Sized + } + "#, + expect![[r#" + 56..60 'self': &Self + 113..228 '{ ...ized }': () + 119..122 '1u8': u8 + 119..129 '1u8.test()': bool + 135..150 '(*"foo").test()': {unknown} + 136..142 '*"foo"': str + 137..142 '"foo"': &str + 169..179 '(1u8, 1u8)': (u8, u8) + 169..186 '(1u8, ...test()': bool + 170..173 '1u8': u8 + 175..178 '1u8': u8 + 192..205 '(1u8, *"foo")': (u8, str) + 192..212 '(1u8, ...test()': {unknown} + 193..196 '1u8': u8 + 198..204 '*"foo"': str + 199..204 '"foo"': &str + "#]], ); } @@ -2867,156 +2867,150 @@ impl iter::Iterator for ops::Range { #[test] fn infer_closure_arg() { - assert_snapshot!( - infer( - r#" - //- /lib.rs - - enum Option { - None, - Some(T) - } + check_infer( + r#" + //- /lib.rs - fn foo() { - let s = Option::None; - let f = |x: Option| {}; - (&f)(s) - } - "# - ), - @r###" - 52..126 '{ ...)(s) }': () - 62..63 's': Option - 66..78 'Option::None': Option - 88..89 'f': |Option| -> () - 92..111 '|x: Op...2>| {}': |Option| -> () - 93..94 'x': Option - 109..111 '{}': () - 117..124 '(&f)(s)': () - 118..120 '&f': &|Option| -> () - 119..120 'f': |Option| -> () - 122..123 's': Option - "### + enum Option { + None, + Some(T) + } + + fn foo() { + let s = Option::None; + let f = |x: Option| {}; + (&f)(s) + } + "#, + expect![[r#" + 52..126 '{ ...)(s) }': () + 62..63 's': Option + 66..78 'Option::None': Option + 88..89 'f': |Option| -> () + 92..111 '|x: Op...2>| {}': |Option| -> () + 93..94 'x': Option + 109..111 '{}': () + 117..124 '(&f)(s)': () + 118..120 '&f': &|Option| -> () + 119..120 'f': |Option| -> () + 122..123 's': Option + "#]], ); } #[test] fn infer_fn_trait_arg() { - assert_snapshot!( - infer( - r#" - //- /lib.rs deps:std + check_infer( + r#" + //- /lib.rs deps:std - #[lang = "fn_once"] - pub trait FnOnce { - type Output; + #[lang = "fn_once"] + pub trait FnOnce { + type Output; - extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; - } + extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; + } - #[lang = "fn"] - pub trait Fn:FnOnce { - extern "rust-call" fn call(&self, args: Args) -> Self::Output; - } + #[lang = "fn"] + pub trait Fn:FnOnce { + extern "rust-call" fn call(&self, args: Args) -> Self::Output; + } - enum Option { - None, - Some(T) - } + enum Option { + None, + Some(T) + } - fn foo(f: F) -> T - where - F: Fn(Option) -> T, - { - let s = None; - f(s) - } - "# - ), - @r###" - 101..105 'self': &Self - 107..111 'args': Args - 220..224 'self': &Self - 226..230 'args': Args - 313..314 'f': F - 359..389 '{ ...f(s) }': T - 369..370 's': Option - 373..377 'None': Option - 383..384 'f': F - 383..387 'f(s)': T - 385..386 's': Option - "### + fn foo(f: F) -> T + where + F: Fn(Option) -> T, + { + let s = None; + f(s) + } + "#, + expect![[r#" + 101..105 'self': &Self + 107..111 'args': Args + 220..224 'self': &Self + 226..230 'args': Args + 313..314 'f': F + 359..389 '{ ...f(s) }': T + 369..370 's': Option + 373..377 'None': Option + 383..384 'f': F + 383..387 'f(s)': T + 385..386 's': Option + "#]], ); } #[test] fn infer_box_fn_arg() { - assert_snapshot!( - infer( - r#" - //- /lib.rs deps:std + check_infer( + r#" + //- /lib.rs deps:std - #[lang = "fn_once"] - pub trait FnOnce { - type Output; + #[lang = "fn_once"] + pub trait FnOnce { + type Output; - extern "rust-call" fn call_once(self, args: Args) -> Self::Output; - } + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + } - #[lang = "deref"] - pub trait Deref { - type Target: ?Sized; + #[lang = "deref"] + pub trait Deref { + type Target: ?Sized; - fn deref(&self) -> &Self::Target; - } + fn deref(&self) -> &Self::Target; + } - #[lang = "owned_box"] - pub struct Box { - inner: *mut T, - } + #[lang = "owned_box"] + pub struct Box { + inner: *mut T, + } - impl Deref for Box { - type Target = T; + impl Deref for Box { + type Target = T; - fn deref(&self) -> &T { - &self.inner - } + fn deref(&self) -> &T { + &self.inner } + } - enum Option { - None, - Some(T) - } + enum Option { + None, + Some(T) + } - fn foo() { - let s = Option::None; - let f: Box)> = box (|ps| {}); - f(&s) - } - "# - ), - @r###" - 100..104 'self': Self - 106..110 'args': Args - 214..218 'self': &Self - 384..388 'self': &Box - 396..423 '{ ... }': &T - 406..417 '&self.inner': &*mut T - 407..411 'self': &Box - 407..417 'self.inner': *mut T - 478..575 '{ ...(&s) }': FnOnce::Output,)>, (&Option,)> - 488..489 's': Option - 492..504 'Option::None': Option - 514..515 'f': Box,)>> - 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> - 554..561 '|ps| {}': |{unknown}| -> () - 555..557 'ps': {unknown} - 559..561 '{}': () - 568..569 'f': Box,)>> - 568..573 'f(&s)': FnOnce::Output,)>, (&Option,)> - 570..572 '&s': &Option - 571..572 's': Option - "### + fn foo() { + let s = Option::None; + let f: Box)> = box (|ps| {}); + f(&s) + } + "#, + expect![[r#" + 100..104 'self': Self + 106..110 'args': Args + 214..218 'self': &Self + 384..388 'self': &Box + 396..423 '{ ... }': &T + 406..417 '&self.inner': &*mut T + 407..411 'self': &Box + 407..417 'self.inner': *mut T + 478..575 '{ ...(&s) }': FnOnce::Output,)>, (&Option,)> + 488..489 's': Option + 492..504 'Option::None': Option + 514..515 'f': Box,)>> + 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> + 554..561 '|ps| {}': |{unknown}| -> () + 555..557 'ps': {unknown} + 559..561 '{}': () + 568..569 'f': Box,)>> + 568..573 'f(&s)': FnOnce::Output,)>, (&Option,)> + 570..572 '&s': &Option + 571..572 's': Option + "#]], ); } -- cgit v1.2.3