aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock87
-rw-r--r--crates/ra_hir_ty/Cargo.toml1
-rw-r--r--crates/ra_hir_ty/src/tests.rs4
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs620
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs1150
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs1102
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs1172
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs3413
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs3274
-rw-r--r--docs/dev/architecture.md3
10 files changed, 5369 insertions, 5457 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 90a9f3822..cf4de8bbe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -206,20 +206,6 @@ dependencies = [
206] 206]
207 207
208[[package]] 208[[package]]
209name = "console"
210version = "0.11.3"
211source = "registry+https://github.com/rust-lang/crates.io-index"
212checksum = "8c0994e656bba7b922d8dd1245db90672ffb701e684e45be58f20719d69abc5a"
213dependencies = [
214 "encode_unicode",
215 "lazy_static",
216 "libc",
217 "terminal_size",
218 "termios",
219 "winapi 0.3.9",
220]
221
222[[package]]
223name = "crc32fast" 209name = "crc32fast"
224version = "1.2.0" 210version = "1.2.0"
225source = "registry+https://github.com/rust-lang/crates.io-index" 211source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -299,12 +285,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
299checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f" 285checksum = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
300 286
301[[package]] 287[[package]]
302name = "dtoa"
303version = "0.4.6"
304source = "registry+https://github.com/rust-lang/crates.io-index"
305checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
306
307[[package]]
308name = "either" 288name = "either"
309version = "1.5.3" 289version = "1.5.3"
310source = "registry+https://github.com/rust-lang/crates.io-index" 290source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -320,12 +300,6 @@ dependencies = [
320] 300]
321 301
322[[package]] 302[[package]]
323name = "encode_unicode"
324version = "0.3.6"
325source = "registry+https://github.com/rust-lang/crates.io-index"
326checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
327
328[[package]]
329name = "env_logger" 303name = "env_logger"
330version = "0.7.1" 304version = "0.7.1"
331source = "registry+https://github.com/rust-lang/crates.io-index" 305source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -538,20 +512,6 @@ dependencies = [
538] 512]
539 513
540[[package]] 514[[package]]
541name = "insta"
542version = "0.16.1"
543source = "registry+https://github.com/rust-lang/crates.io-index"
544checksum = "617e921abc813f96a3b00958c079e7bf1e2db998f8a04f1546dd967373a418ee"
545dependencies = [
546 "console",
547 "difference",
548 "lazy_static",
549 "serde",
550 "serde_json",
551 "serde_yaml",
552]
553
554[[package]]
555name = "instant" 515name = "instant"
556version = "0.1.6" 516version = "0.1.6"
557source = "registry+https://github.com/rust-lang/crates.io-index" 517source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -666,12 +626,6 @@ dependencies = [
666] 626]
667 627
668[[package]] 628[[package]]
669name = "linked-hash-map"
670version = "0.5.3"
671source = "registry+https://github.com/rust-lang/crates.io-index"
672checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
673
674[[package]]
675name = "lock_api" 629name = "lock_api"
676version = "0.4.1" 630version = "0.4.1"
677source = "registry+https://github.com/rust-lang/crates.io-index" 631source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1128,7 +1082,6 @@ dependencies = [
1128 "chalk-solve", 1082 "chalk-solve",
1129 "ena", 1083 "ena",
1130 "expect", 1084 "expect",
1131 "insta",
1132 "itertools", 1085 "itertools",
1133 "log", 1086 "log",
1134 "ra_arena", 1087 "ra_arena",
@@ -1660,18 +1613,6 @@ dependencies = [
1660] 1613]
1661 1614
1662[[package]] 1615[[package]]
1663name = "serde_yaml"
1664version = "0.8.13"
1665source = "registry+https://github.com/rust-lang/crates.io-index"
1666checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
1667dependencies = [
1668 "dtoa",
1669 "linked-hash-map",
1670 "serde",
1671 "yaml-rust",
1672]
1673
1674[[package]]
1675name = "sharded-slab" 1616name = "sharded-slab"
1676version = "0.0.9" 1617version = "0.0.9"
1677source = "registry+https://github.com/rust-lang/crates.io-index" 1618source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1758,25 +1699,6 @@ dependencies = [
1758] 1699]
1759 1700
1760[[package]] 1701[[package]]
1761name = "terminal_size"
1762version = "0.1.13"
1763source = "registry+https://github.com/rust-lang/crates.io-index"
1764checksum = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13"
1765dependencies = [
1766 "libc",
1767 "winapi 0.3.9",
1768]
1769
1770[[package]]
1771name = "termios"
1772version = "0.3.2"
1773source = "registry+https://github.com/rust-lang/crates.io-index"
1774checksum = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2"
1775dependencies = [
1776 "libc",
1777]
1778
1779[[package]]
1780name = "test_utils" 1702name = "test_utils"
1781version = "0.1.0" 1703version = "0.1.0"
1782dependencies = [ 1704dependencies = [
@@ -2065,12 +1987,3 @@ dependencies = [
2065 "quote", 1987 "quote",
2066 "walkdir", 1988 "walkdir",
2067] 1989]
2068
2069[[package]]
2070name = "yaml-rust"
2071version = "0.4.4"
2072source = "registry+https://github.com/rust-lang/crates.io-index"
2073checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
2074dependencies = [
2075 "linked-hash-map",
2076]
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 548a3fc1f..cdabb359f 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -33,7 +33,6 @@ chalk-ir = { version = "0.18.0" }
33chalk-recursive = { version = "0.18.0" } 33chalk-recursive = { version = "0.18.0" }
34 34
35[dev-dependencies] 35[dev-dependencies]
36insta = "0.16.0"
37expect = { path = "../expect" } 36expect = { path = "../expect" }
38 37
39tracing = "0.1" 38tracing = "0.1"
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 59a21092e..45bc14c37 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -34,8 +34,8 @@ use crate::{
34}; 34};
35 35
36// These tests compare the inference results for all expressions in a file 36// These tests compare the inference results for all expressions in a file
37// against snapshots of the expected results using insta. Use cargo-insta to 37// against snapshots of the expected results using expect. Use
38// update the snapshots. 38// `env UPDATE_EXPECT=1 cargo test -p ra_hir_ty` to update the snapshots.
39 39
40fn setup_tracing() -> tracing::subscriber::DefaultGuard { 40fn setup_tracing() -> tracing::subscriber::DefaultGuard {
41 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; 41 use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
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 @@
1use std::fs; 1use std::fs;
2 2
3use insta::assert_snapshot; 3use expect::expect;
4use test_utils::project_dir; 4use test_utils::project_dir;
5 5
6use super::{check_types, infer}; 6use super::{check_infer, check_types};
7 7
8#[test] 8#[test]
9fn cfg_impl_def() { 9fn cfg_impl_def() {
@@ -46,204 +46,204 @@ impl S {
46 46
47#[test] 47#[test]
48fn infer_macros_expanded() { 48fn infer_macros_expanded() {
49 assert_snapshot!( 49 check_infer(
50 infer(r#" 50 r#"
51struct Foo(Vec<i32>); 51 struct Foo(Vec<i32>);
52 52
53macro_rules! foo { 53 macro_rules! foo {
54 ($($item:expr),*) => { 54 ($($item:expr),*) => {
55 { 55 {
56 Foo(vec![$($item,)*]) 56 Foo(vec![$($item,)*])
57 } 57 }
58 }; 58 };
59} 59 }
60 60
61fn main() { 61 fn main() {
62 let x = foo!(1,2); 62 let x = foo!(1,2);
63} 63 }
64"#), 64 "#,
65 @r###" 65 expect![[r#"
66 !0..17 '{Foo(v...,2,])}': Foo 66 !0..17 '{Foo(v...,2,])}': Foo
67 !1..4 'Foo': Foo({unknown}) -> Foo 67 !1..4 'Foo': Foo({unknown}) -> Foo
68 !1..16 'Foo(vec![1,2,])': Foo 68 !1..16 'Foo(vec![1,2,])': Foo
69 !5..15 'vec![1,2,]': {unknown} 69 !5..15 'vec![1,2,]': {unknown}
70 155..181 '{ ...,2); }': () 70 155..181 '{ ...,2); }': ()
71 165..166 'x': Foo 71 165..166 'x': Foo
72 "### 72 "#]],
73 ); 73 );
74} 74}
75 75
76#[test] 76#[test]
77fn infer_legacy_textual_scoped_macros_expanded() { 77fn infer_legacy_textual_scoped_macros_expanded() {
78 assert_snapshot!( 78 check_infer(
79 infer(r#" 79 r#"
80struct Foo(Vec<i32>); 80 struct Foo(Vec<i32>);
81 81
82#[macro_use] 82 #[macro_use]
83mod m { 83 mod m {
84 macro_rules! foo { 84 macro_rules! foo {
85 ($($item:expr),*) => { 85 ($($item:expr),*) => {
86 { 86 {
87 Foo(vec![$($item,)*]) 87 Foo(vec![$($item,)*])
88 }
89 };
88 } 90 }
89 }; 91 }
90 }
91}
92 92
93fn main() { 93 fn main() {
94 let x = foo!(1,2); 94 let x = foo!(1,2);
95 let y = crate::foo!(1,2); 95 let y = crate::foo!(1,2);
96} 96 }
97"#), 97 "#,
98 @r###" 98 expect![[r#"
99 !0..17 '{Foo(v...,2,])}': Foo 99 !0..17 '{Foo(v...,2,])}': Foo
100 !1..4 'Foo': Foo({unknown}) -> Foo 100 !1..4 'Foo': Foo({unknown}) -> Foo
101 !1..16 'Foo(vec![1,2,])': Foo 101 !1..16 'Foo(vec![1,2,])': Foo
102 !5..15 'vec![1,2,]': {unknown} 102 !5..15 'vec![1,2,]': {unknown}
103 194..250 '{ ...,2); }': () 103 194..250 '{ ...,2); }': ()
104 204..205 'x': Foo 104 204..205 'x': Foo
105 227..228 'y': {unknown} 105 227..228 'y': {unknown}
106 231..247 'crate:...!(1,2)': {unknown} 106 231..247 'crate:...!(1,2)': {unknown}
107 "### 107 "#]],
108 ); 108 );
109} 109}
110 110
111#[test] 111#[test]
112fn infer_path_qualified_macros_expanded() { 112fn infer_path_qualified_macros_expanded() {
113 assert_snapshot!( 113 check_infer(
114 infer(r#" 114 r#"
115#[macro_export] 115 #[macro_export]
116macro_rules! foo { 116 macro_rules! foo {
117 () => { 42i32 } 117 () => { 42i32 }
118} 118 }
119 119
120mod m { 120 mod m {
121 pub use super::foo as bar; 121 pub use super::foo as bar;
122} 122 }
123 123
124fn main() { 124 fn main() {
125 let x = crate::foo!(); 125 let x = crate::foo!();
126 let y = m::bar!(); 126 let y = m::bar!();
127} 127 }
128"#), 128 "#,
129 @r###" 129 expect![[r#"
130 !0..5 '42i32': i32 130 !0..5 '42i32': i32
131 !0..5 '42i32': i32 131 !0..5 '42i32': i32
132 110..163 '{ ...!(); }': () 132 110..163 '{ ...!(); }': ()
133 120..121 'x': i32 133 120..121 'x': i32
134 147..148 'y': i32 134 147..148 'y': i32
135 "### 135 "#]],
136 ); 136 );
137} 137}
138 138
139#[test] 139#[test]
140fn expr_macro_expanded_in_various_places() { 140fn expr_macro_expanded_in_various_places() {
141 assert_snapshot!( 141 check_infer(
142 infer(r#" 142 r#"
143macro_rules! spam { 143 macro_rules! spam {
144 () => (1isize); 144 () => (1isize);
145} 145 }
146 146
147fn spam() { 147 fn spam() {
148 spam!(); 148 spam!();
149 (spam!()); 149 (spam!());
150 spam!().spam(spam!()); 150 spam!().spam(spam!());
151 for _ in spam!() {} 151 for _ in spam!() {}
152 || spam!(); 152 || spam!();
153 while spam!() {} 153 while spam!() {}
154 break spam!(); 154 break spam!();
155 return spam!(); 155 return spam!();
156 match spam!() { 156 match spam!() {
157 _ if spam!() => spam!(), 157 _ if spam!() => spam!(),
158 } 158 }
159 spam!()(spam!()); 159 spam!()(spam!());
160 Spam { spam: spam!() }; 160 Spam { spam: spam!() };
161 spam!()[spam!()]; 161 spam!()[spam!()];
162 await spam!(); 162 await spam!();
163 spam!() as usize; 163 spam!() as usize;
164 &spam!(); 164 &spam!();
165 -spam!(); 165 -spam!();
166 spam!()..spam!(); 166 spam!()..spam!();
167 spam!() + spam!(); 167 spam!() + spam!();
168} 168 }
169"#), 169 "#,
170 @r###" 170 expect![[r#"
171 !0..6 '1isize': isize 171 !0..6 '1isize': isize
172 !0..6 '1isize': isize 172 !0..6 '1isize': isize
173 !0..6 '1isize': isize 173 !0..6 '1isize': isize
174 !0..6 '1isize': isize 174 !0..6 '1isize': isize
175 !0..6 '1isize': isize 175 !0..6 '1isize': isize
176 !0..6 '1isize': isize 176 !0..6 '1isize': isize
177 !0..6 '1isize': isize 177 !0..6 '1isize': isize
178 !0..6 '1isize': isize 178 !0..6 '1isize': isize
179 !0..6 '1isize': isize 179 !0..6 '1isize': isize
180 !0..6 '1isize': isize 180 !0..6 '1isize': isize
181 !0..6 '1isize': isize 181 !0..6 '1isize': isize
182 !0..6 '1isize': isize 182 !0..6 '1isize': isize
183 !0..6 '1isize': isize 183 !0..6 '1isize': isize
184 !0..6 '1isize': isize 184 !0..6 '1isize': isize
185 !0..6 '1isize': isize 185 !0..6 '1isize': isize
186 !0..6 '1isize': isize 186 !0..6 '1isize': isize
187 !0..6 '1isize': isize 187 !0..6 '1isize': isize
188 !0..6 '1isize': isize 188 !0..6 '1isize': isize
189 !0..6 '1isize': isize 189 !0..6 '1isize': isize
190 !0..6 '1isize': isize 190 !0..6 '1isize': isize
191 !0..6 '1isize': isize 191 !0..6 '1isize': isize
192 !0..6 '1isize': isize 192 !0..6 '1isize': isize
193 !0..6 '1isize': isize 193 !0..6 '1isize': isize
194 !0..6 '1isize': isize 194 !0..6 '1isize': isize
195 !0..6 '1isize': isize 195 !0..6 '1isize': isize
196 53..456 '{ ...!(); }': () 196 53..456 '{ ...!(); }': ()
197 87..108 'spam!(...am!())': {unknown} 197 87..108 'spam!(...am!())': {unknown}
198 114..133 'for _ ...!() {}': () 198 114..133 'for _ ...!() {}': ()
199 118..119 '_': {unknown} 199 118..119 '_': {unknown}
200 131..133 '{}': () 200 131..133 '{}': ()
201 138..148 '|| spam!()': || -> isize 201 138..148 '|| spam!()': || -> isize
202 154..170 'while ...!() {}': () 202 154..170 'while ...!() {}': ()
203 168..170 '{}': () 203 168..170 '{}': ()
204 175..188 'break spam!()': ! 204 175..188 'break spam!()': !
205 194..208 'return spam!()': ! 205 194..208 'return spam!()': !
206 214..268 'match ... }': isize 206 214..268 'match ... }': isize
207 238..239 '_': isize 207 238..239 '_': isize
208 273..289 'spam!(...am!())': {unknown} 208 273..289 'spam!(...am!())': {unknown}
209 295..317 'Spam {...m!() }': {unknown} 209 295..317 'Spam {...m!() }': {unknown}
210 323..339 'spam!(...am!()]': {unknown} 210 323..339 'spam!(...am!()]': {unknown}
211 364..380 'spam!(... usize': usize 211 364..380 'spam!(... usize': usize
212 386..394 '&spam!()': &isize 212 386..394 '&spam!()': &isize
213 400..408 '-spam!()': isize 213 400..408 '-spam!()': isize
214 414..430 'spam!(...pam!()': {unknown} 214 414..430 'spam!(...pam!()': {unknown}
215 436..453 'spam!(...pam!()': isize 215 436..453 'spam!(...pam!()': isize
216 "### 216 "#]],
217 ); 217 );
218} 218}
219 219
220#[test] 220#[test]
221fn infer_type_value_macro_having_same_name() { 221fn infer_type_value_macro_having_same_name() {
222 assert_snapshot!( 222 check_infer(
223 infer(r#" 223 r#"
224#[macro_export] 224 #[macro_export]
225macro_rules! foo { 225 macro_rules! foo {
226 () => { 226 () => {
227 mod foo { 227 mod foo {
228 pub use super::foo; 228 pub use super::foo;
229 }
230 };
231 ($x:tt) => {
232 $x
233 };
229 } 234 }
230 };
231 ($x:tt) => {
232 $x
233 };
234}
235 235
236foo!(); 236 foo!();
237 237
238fn foo() { 238 fn foo() {
239 let foo = foo::foo!(42i32); 239 let foo = foo::foo!(42i32);
240} 240 }
241"#), 241 "#,
242 @r###" 242 expect![[r#"
243 !0..5 '42i32': i32 243 !0..5 '42i32': i32
244 170..205 '{ ...32); }': () 244 170..205 '{ ...32); }': ()
245 180..183 'foo': i32 245 180..183 'foo': i32
246 "### 246 "#]],
247 ); 247 );
248} 248}
249 249
@@ -372,50 +372,50 @@ expand!();
372 372
373#[test] 373#[test]
374fn infer_type_value_non_legacy_macro_use_as() { 374fn infer_type_value_non_legacy_macro_use_as() {
375 assert_snapshot!( 375 check_infer(
376 infer(r#" 376 r#"
377mod m { 377 mod m {
378 macro_rules! _foo { 378 macro_rules! _foo {
379 ($x:ident) => { type $x = u64; } 379 ($x:ident) => { type $x = u64; }
380 } 380 }
381 pub(crate) use _foo as foo; 381 pub(crate) use _foo as foo;
382} 382 }
383 383
384m::foo!(foo); 384 m::foo!(foo);
385use foo as bar; 385 use foo as bar;
386fn f() -> bar { 0 } 386 fn f() -> bar { 0 }
387fn main() { 387 fn main() {
388 let _a = f(); 388 let _a = f();
389} 389 }
390"#), 390 "#,
391 @r###" 391 expect![[r#"
392 158..163 '{ 0 }': u64 392 158..163 '{ 0 }': u64
393 160..161 '0': u64 393 160..161 '0': u64
394 174..196 '{ ...f(); }': () 394 174..196 '{ ...f(); }': ()
395 184..186 '_a': u64 395 184..186 '_a': u64
396 190..191 'f': fn f() -> u64 396 190..191 'f': fn f() -> u64
397 190..193 'f()': u64 397 190..193 'f()': u64
398 "### 398 "#]],
399 ); 399 );
400} 400}
401 401
402#[test] 402#[test]
403fn infer_local_macro() { 403fn infer_local_macro() {
404 assert_snapshot!( 404 check_infer(
405 infer(r#" 405 r#"
406fn main() { 406 fn main() {
407 macro_rules! foo { 407 macro_rules! foo {
408 () => { 1usize } 408 () => { 1usize }
409 } 409 }
410 let _a = foo!(); 410 let _a = foo!();
411} 411 }
412"#), 412 "#,
413 @r###" 413 expect![[r#"
414 !0..6 '1usize': usize 414 !0..6 '1usize': usize
415 10..89 '{ ...!(); }': () 415 10..89 '{ ...!(); }': ()
416 16..65 'macro_... }': {unknown} 416 16..65 'macro_... }': {unknown}
417 74..76 '_a': usize 417 74..76 '_a': usize
418 "### 418 "#]],
419 ); 419 );
420} 420}
421 421
@@ -446,77 +446,77 @@ macro_rules! bar {
446 446
447#[test] 447#[test]
448fn infer_builtin_macros_line() { 448fn infer_builtin_macros_line() {
449 assert_snapshot!( 449 check_infer(
450 infer(r#" 450 r#"
451#[rustc_builtin_macro] 451 #[rustc_builtin_macro]
452macro_rules! line {() => {}} 452 macro_rules! line {() => {}}
453 453
454fn main() { 454 fn main() {
455 let x = line!(); 455 let x = line!();
456} 456 }
457"#), 457 "#,
458 @r###" 458 expect![[r#"
459 !0..1 '0': i32 459 !0..1 '0': i32
460 63..87 '{ ...!(); }': () 460 63..87 '{ ...!(); }': ()
461 73..74 'x': i32 461 73..74 'x': i32
462 "### 462 "#]],
463 ); 463 );
464} 464}
465 465
466#[test] 466#[test]
467fn infer_builtin_macros_file() { 467fn infer_builtin_macros_file() {
468 assert_snapshot!( 468 check_infer(
469 infer(r#" 469 r#"
470#[rustc_builtin_macro] 470 #[rustc_builtin_macro]
471macro_rules! file {() => {}} 471 macro_rules! file {() => {}}
472 472
473fn main() { 473 fn main() {
474 let x = file!(); 474 let x = file!();
475} 475 }
476"#), 476 "#,
477 @r###" 477 expect![[r#"
478 !0..2 '""': &str 478 !0..2 '""': &str
479 63..87 '{ ...!(); }': () 479 63..87 '{ ...!(); }': ()
480 73..74 'x': &str 480 73..74 'x': &str
481 "### 481 "#]],
482 ); 482 );
483} 483}
484 484
485#[test] 485#[test]
486fn infer_builtin_macros_column() { 486fn infer_builtin_macros_column() {
487 assert_snapshot!( 487 check_infer(
488 infer(r#" 488 r#"
489#[rustc_builtin_macro] 489 #[rustc_builtin_macro]
490macro_rules! column {() => {}} 490 macro_rules! column {() => {}}
491 491
492fn main() { 492 fn main() {
493 let x = column!(); 493 let x = column!();
494} 494 }
495"#), 495 "#,
496 @r###" 496 expect![[r#"
497 !0..1 '0': i32 497 !0..1 '0': i32
498 65..91 '{ ...!(); }': () 498 65..91 '{ ...!(); }': ()
499 75..76 'x': i32 499 75..76 'x': i32
500 "### 500 "#]],
501 ); 501 );
502} 502}
503 503
504#[test] 504#[test]
505fn infer_builtin_macros_concat() { 505fn infer_builtin_macros_concat() {
506 assert_snapshot!( 506 check_infer(
507 infer(r#" 507 r#"
508#[rustc_builtin_macro] 508 #[rustc_builtin_macro]
509macro_rules! concat {() => {}} 509 macro_rules! concat {() => {}}
510 510
511fn main() { 511 fn main() {
512 let x = concat!("hello", concat!("world", "!")); 512 let x = concat!("hello", concat!("world", "!"));
513} 513 }
514"#), 514 "#,
515 @r###" 515 expect![[r#"
516 !0..13 '"helloworld!"': &str 516 !0..13 '"helloworld!"': &str
517 65..121 '{ ...")); }': () 517 65..121 '{ ...")); }': ()
518 75..76 'x': &str 518 75..76 'x': &str
519 "### 519 "#]],
520 ); 520 );
521} 521}
522 522
@@ -622,7 +622,7 @@ macro_rules! include {() => {}}
622include!("main.rs"); 622include!("main.rs");
623 623
624fn main() { 624fn main() {
625 0 625 0
626} //^ i32 626} //^ i32
627"#, 627"#,
628 ); 628 );
@@ -630,42 +630,42 @@ fn main() {
630 630
631#[test] 631#[test]
632fn infer_builtin_macros_concat_with_lazy() { 632fn infer_builtin_macros_concat_with_lazy() {
633 assert_snapshot!( 633 check_infer(
634 infer(r#" 634 r#"
635macro_rules! hello {() => {"hello"}} 635 macro_rules! hello {() => {"hello"}}
636 636
637#[rustc_builtin_macro] 637 #[rustc_builtin_macro]
638macro_rules! concat {() => {}} 638 macro_rules! concat {() => {}}
639 639
640fn main() { 640 fn main() {
641 let x = concat!(hello!(), concat!("world", "!")); 641 let x = concat!(hello!(), concat!("world", "!"));
642} 642 }
643"#), 643 "#,
644 @r###" 644 expect![[r#"
645 !0..13 '"helloworld!"': &str 645 !0..13 '"helloworld!"': &str
646 103..160 '{ ...")); }': () 646 103..160 '{ ...")); }': ()
647 113..114 'x': &str 647 113..114 'x': &str
648 "### 648 "#]],
649 ); 649 );
650} 650}
651 651
652#[test] 652#[test]
653fn infer_builtin_macros_env() { 653fn infer_builtin_macros_env() {
654 assert_snapshot!( 654 check_infer(
655 infer(r#" 655 r#"
656//- /main.rs env:foo=bar 656 //- /main.rs env:foo=bar
657#[rustc_builtin_macro] 657 #[rustc_builtin_macro]
658macro_rules! env {() => {}} 658 macro_rules! env {() => {}}
659 659
660fn main() { 660 fn main() {
661 let x = env!("foo"); 661 let x = env!("foo");
662} 662 }
663"#), 663 "#,
664 @r###" 664 expect![[r#"
665 !0..22 '"__RA_...TED__"': &str 665 !0..22 '"__RA_...TED__"': &str
666 62..90 '{ ...o"); }': () 666 62..90 '{ ...o"); }': ()
667 72..73 'x': &str 667 72..73 'x': &str
668 "### 668 "#]],
669 ); 669 );
670} 670}
671 671
@@ -763,25 +763,25 @@ fn test() {
763 763
764#[test] 764#[test]
765fn macro_in_arm() { 765fn macro_in_arm() {
766 assert_snapshot!( 766 check_infer(
767 infer(r#" 767 r#"
768macro_rules! unit { 768 macro_rules! unit {
769 () => { () }; 769 () => { () };
770} 770 }
771 771
772fn main() { 772 fn main() {
773 let x = match () { 773 let x = match () {
774 unit!() => 92u32, 774 unit!() => 92u32,
775 }; 775 };
776} 776 }
777"#), 777 "#,
778 @r###" 778 expect![[r#"
779 51..110 '{ ... }; }': () 779 51..110 '{ ... }; }': ()
780 61..62 'x': u32 780 61..62 'x': u32
781 65..107 'match ... }': u32 781 65..107 'match ... }': u32
782 71..73 '()': () 782 71..73 '()': ()
783 84..91 'unit!()': () 783 84..91 'unit!()': ()
784 95..100 '92u32': u32 784 95..100 '92u32': u32
785 "### 785 "#]],
786 ); 786 );
787} 787}
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 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer}; 3use super::{check_infer, check_types};
4 4
5#[test] 5#[test]
6fn infer_slice_method() { 6fn infer_slice_method() {
7 assert_snapshot!( 7 check_infer(
8 infer(r#" 8 r#"
9#[lang = "slice"] 9 #[lang = "slice"]
10impl<T> [T] { 10 impl<T> [T] {
11 fn foo(&self) -> T { 11 fn foo(&self) -> T {
12 loop {} 12 loop {}
13 } 13 }
14} 14 }
15 15
16#[lang = "slice_alloc"] 16 #[lang = "slice_alloc"]
17impl<T> [T] {} 17 impl<T> [T] {}
18 18
19fn test(x: &[u8]) { 19 fn test(x: &[u8]) {
20 <[_]>::foo(x); 20 <[_]>::foo(x);
21} 21 }
22"#), 22 "#,
23 @r###" 23 expect![[r#"
24 44..48 'self': &[T] 24 44..48 'self': &[T]
25 55..78 '{ ... }': T 25 55..78 '{ ... }': T
26 65..72 'loop {}': ! 26 65..72 'loop {}': !
27 70..72 '{}': () 27 70..72 '{}': ()
28 130..131 'x': &[u8] 28 130..131 'x': &[u8]
29 140..162 '{ ...(x); }': () 29 140..162 '{ ...(x); }': ()
30 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8 30 146..156 '<[_]>::foo': fn foo<u8>(&[u8]) -> u8
31 146..159 '<[_]>::foo(x)': u8 31 146..159 '<[_]>::foo(x)': u8
32 157..158 'x': &[u8] 32 157..158 'x': &[u8]
33 "### 33 "#]],
34 ); 34 );
35} 35}
36 36
37#[test] 37#[test]
38fn infer_associated_method_struct() { 38fn infer_associated_method_struct() {
39 assert_snapshot!( 39 check_infer(
40 infer(r#" 40 r#"
41struct A { x: u32 } 41 struct A { x: u32 }
42 42
43impl A { 43 impl A {
44 fn new() -> A { 44 fn new() -> A {
45 A { x: 0 } 45 A { x: 0 }
46 } 46 }
47} 47 }
48fn test() { 48 fn test() {
49 let a = A::new(); 49 let a = A::new();
50 a.x; 50 a.x;
51} 51 }
52"#), 52 "#,
53 @r###" 53 expect![[r#"
54 48..74 '{ ... }': A 54 48..74 '{ ... }': A
55 58..68 'A { x: 0 }': A 55 58..68 'A { x: 0 }': A
56 65..66 '0': u32 56 65..66 '0': u32
57 87..121 '{ ...a.x; }': () 57 87..121 '{ ...a.x; }': ()
58 97..98 'a': A 58 97..98 'a': A
59 101..107 'A::new': fn new() -> A 59 101..107 'A::new': fn new() -> A
60 101..109 'A::new()': A 60 101..109 'A::new()': A
61 115..116 'a': A 61 115..116 'a': A
62 115..118 'a.x': u32 62 115..118 'a.x': u32
63 "### 63 "#]],
64 ); 64 );
65} 65}
66 66
67#[test] 67#[test]
68fn infer_associated_method_enum() { 68fn infer_associated_method_enum() {
69 assert_snapshot!( 69 check_infer(
70 infer(r#" 70 r#"
71enum A { B, C } 71 enum A { B, C }
72 72
73impl A { 73 impl A {
74 pub fn b() -> A { 74 pub fn b() -> A {
75 A::B 75 A::B
76 } 76 }
77 pub fn c() -> A { 77 pub fn c() -> A {
78 A::C 78 A::C
79 } 79 }
80} 80 }
81fn test() { 81 fn test() {
82 let a = A::b(); 82 let a = A::b();
83 a; 83 a;
84 let c = A::c(); 84 let c = A::c();
85 c; 85 c;
86} 86 }
87"#), 87 "#,
88 @r###" 88 expect![[r#"
89 46..66 '{ ... }': A 89 46..66 '{ ... }': A
90 56..60 'A::B': A 90 56..60 'A::B': A
91 87..107 '{ ... }': A 91 87..107 '{ ... }': A
92 97..101 'A::C': A 92 97..101 'A::C': A
93 120..177 '{ ... c; }': () 93 120..177 '{ ... c; }': ()
94 130..131 'a': A 94 130..131 'a': A
95 134..138 'A::b': fn b() -> A 95 134..138 'A::b': fn b() -> A
96 134..140 'A::b()': A 96 134..140 'A::b()': A
97 146..147 'a': A 97 146..147 'a': A
98 157..158 'c': A 98 157..158 'c': A
99 161..165 'A::c': fn c() -> A 99 161..165 'A::c': fn c() -> A
100 161..167 'A::c()': A 100 161..167 'A::c()': A
101 173..174 'c': A 101 173..174 'c': A
102 "### 102 "#]],
103 ); 103 );
104} 104}
105 105
106#[test] 106#[test]
107fn infer_associated_method_with_modules() { 107fn infer_associated_method_with_modules() {
108 assert_snapshot!( 108 check_infer(
109 infer(r#" 109 r#"
110mod a { 110 mod a {
111 struct A; 111 struct A;
112 impl A { pub fn thing() -> A { A {} }} 112 impl A { pub fn thing() -> A { A {} }}
113} 113 }
114 114
115mod b { 115 mod b {
116 struct B; 116 struct B;
117 impl B { pub fn thing() -> u32 { 99 }} 117 impl B { pub fn thing() -> u32 { 99 }}
118 118
119 mod c { 119 mod c {
120 struct C; 120 struct C;
121 impl C { pub fn thing() -> C { C {} }} 121 impl C { pub fn thing() -> C { C {} }}
122 } 122 }
123} 123 }
124use b::c; 124 use b::c;
125 125
126fn test() { 126 fn test() {
127 let x = a::A::thing(); 127 let x = a::A::thing();
128 let y = b::B::thing(); 128 let y = b::B::thing();
129 let z = c::C::thing(); 129 let z = c::C::thing();
130} 130 }
131"#), 131 "#,
132 @r###" 132 expect![[r#"
133 55..63 '{ A {} }': A 133 55..63 '{ A {} }': A
134 57..61 'A {}': A 134 57..61 'A {}': A
135 125..131 '{ 99 }': u32 135 125..131 '{ 99 }': u32
136 127..129 '99': u32 136 127..129 '99': u32
137 201..209 '{ C {} }': C 137 201..209 '{ C {} }': C
138 203..207 'C {}': C 138 203..207 'C {}': C
139 240..324 '{ ...g(); }': () 139 240..324 '{ ...g(); }': ()
140 250..251 'x': A 140 250..251 'x': A
141 254..265 'a::A::thing': fn thing() -> A 141 254..265 'a::A::thing': fn thing() -> A
142 254..267 'a::A::thing()': A 142 254..267 'a::A::thing()': A
143 277..278 'y': u32 143 277..278 'y': u32
144 281..292 'b::B::thing': fn thing() -> u32 144 281..292 'b::B::thing': fn thing() -> u32
145 281..294 'b::B::thing()': u32 145 281..294 'b::B::thing()': u32
146 304..305 'z': C 146 304..305 'z': C
147 308..319 'c::C::thing': fn thing() -> C 147 308..319 'c::C::thing': fn thing() -> C
148 308..321 'c::C::thing()': C 148 308..321 'c::C::thing()': C
149 "### 149 "#]],
150 ); 150 );
151} 151}
152 152
153#[test] 153#[test]
154fn infer_associated_method_generics() { 154fn infer_associated_method_generics() {
155 assert_snapshot!( 155 check_infer(
156 infer(r#" 156 r#"
157struct Gen<T> { 157 struct Gen<T> {
158 val: T 158 val: T
159} 159 }
160 160
161impl<T> Gen<T> { 161 impl<T> Gen<T> {
162 pub fn make(val: T) -> Gen<T> { 162 pub fn make(val: T) -> Gen<T> {
163 Gen { val } 163 Gen { val }
164 } 164 }
165} 165 }
166 166
167fn test() { 167 fn test() {
168 let a = Gen::make(0u32); 168 let a = Gen::make(0u32);
169} 169 }
170"#), 170 "#,
171 @r###" 171 expect![[r#"
172 63..66 'val': T 172 63..66 'val': T
173 81..108 '{ ... }': Gen<T> 173 81..108 '{ ... }': Gen<T>
174 91..102 'Gen { val }': Gen<T> 174 91..102 'Gen { val }': Gen<T>
175 97..100 'val': T 175 97..100 'val': T
176 122..154 '{ ...32); }': () 176 122..154 '{ ...32); }': ()
177 132..133 'a': Gen<u32> 177 132..133 'a': Gen<u32>
178 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32> 178 136..145 'Gen::make': fn make<u32>(u32) -> Gen<u32>
179 136..151 'Gen::make(0u32)': Gen<u32> 179 136..151 'Gen::make(0u32)': Gen<u32>
180 146..150 '0u32': u32 180 146..150 '0u32': u32
181 "### 181 "#]],
182 ); 182 );
183} 183}
184 184
185#[test] 185#[test]
186fn infer_associated_method_generics_without_args() { 186fn infer_associated_method_generics_without_args() {
187 assert_snapshot!( 187 check_infer(
188 infer(r#" 188 r#"
189struct Gen<T> { 189 struct Gen<T> {
190 val: T 190 val: T
191} 191 }
192 192
193impl<T> Gen<T> { 193 impl<T> Gen<T> {
194 pub fn make() -> Gen<T> { 194 pub fn make() -> Gen<T> {
195 loop { } 195 loop { }
196 } 196 }
197} 197 }
198 198
199fn test() { 199 fn test() {
200 let a = Gen::<u32>::make(); 200 let a = Gen::<u32>::make();
201} 201 }
202"#), 202 "#,
203 @r###" 203 expect![[r#"
204 75..99 '{ ... }': Gen<T> 204 75..99 '{ ... }': Gen<T>
205 85..93 'loop { }': ! 205 85..93 'loop { }': !
206 90..93 '{ }': () 206 90..93 '{ }': ()
207 113..148 '{ ...e(); }': () 207 113..148 '{ ...e(); }': ()
208 123..124 'a': Gen<u32> 208 123..124 'a': Gen<u32>
209 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32> 209 127..143 'Gen::<...::make': fn make<u32>() -> Gen<u32>
210 127..145 'Gen::<...make()': Gen<u32> 210 127..145 'Gen::<...make()': Gen<u32>
211 "### 211 "#]],
212 ); 212 );
213} 213}
214 214
215#[test] 215#[test]
216fn infer_associated_method_generics_2_type_params_without_args() { 216fn infer_associated_method_generics_2_type_params_without_args() {
217 assert_snapshot!( 217 check_infer(
218 infer(r#" 218 r#"
219struct Gen<T, U> { 219 struct Gen<T, U> {
220 val: T, 220 val: T,
221 val2: U, 221 val2: U,
222} 222 }
223 223
224impl<T> Gen<u32, T> { 224 impl<T> Gen<u32, T> {
225 pub fn make() -> Gen<u32,T> { 225 pub fn make() -> Gen<u32,T> {
226 loop { } 226 loop { }
227 } 227 }
228} 228 }
229 229
230fn test() { 230 fn test() {
231 let a = Gen::<u32, u64>::make(); 231 let a = Gen::<u32, u64>::make();
232} 232 }
233"#), 233 "#,
234 @r###" 234 expect![[r#"
235 101..125 '{ ... }': Gen<u32, T> 235 101..125 '{ ... }': Gen<u32, T>
236 111..119 'loop { }': ! 236 111..119 'loop { }': !
237 116..119 '{ }': () 237 116..119 '{ }': ()
238 139..179 '{ ...e(); }': () 238 139..179 '{ ...e(); }': ()
239 149..150 'a': Gen<u32, u64> 239 149..150 'a': Gen<u32, u64>
240 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64> 240 153..174 'Gen::<...::make': fn make<u64>() -> Gen<u32, u64>
241 153..176 'Gen::<...make()': Gen<u32, u64> 241 153..176 'Gen::<...make()': Gen<u32, u64>
242 "### 242 "#]],
243 ); 243 );
244} 244}
245 245
@@ -267,416 +267,416 @@ mod foo {
267#[test] 267#[test]
268fn infer_trait_method_simple() { 268fn infer_trait_method_simple() {
269 // the trait implementation is intentionally incomplete -- it shouldn't matter 269 // the trait implementation is intentionally incomplete -- it shouldn't matter
270 assert_snapshot!( 270 check_infer(
271 infer(r#" 271 r#"
272trait Trait1 { 272 trait Trait1 {
273 fn method(&self) -> u32; 273 fn method(&self) -> u32;
274} 274 }
275struct S1; 275 struct S1;
276impl Trait1 for S1 {} 276 impl Trait1 for S1 {}
277trait Trait2 { 277 trait Trait2 {
278 fn method(&self) -> i128; 278 fn method(&self) -> i128;
279} 279 }
280struct S2; 280 struct S2;
281impl Trait2 for S2 {} 281 impl Trait2 for S2 {}
282fn test() { 282 fn test() {
283 S1.method(); // -> u32 283 S1.method(); // -> u32
284 S2.method(); // -> i128 284 S2.method(); // -> i128
285} 285 }
286"#), 286 "#,
287 @r###" 287 expect![[r#"
288 30..34 'self': &Self 288 30..34 'self': &Self
289 109..113 'self': &Self 289 109..113 'self': &Self
290 169..227 '{ ...i128 }': () 290 169..227 '{ ...i128 }': ()
291 175..177 'S1': S1 291 175..177 'S1': S1
292 175..186 'S1.method()': u32 292 175..186 'S1.method()': u32
293 202..204 'S2': S2 293 202..204 'S2': S2
294 202..213 'S2.method()': i128 294 202..213 'S2.method()': i128
295 "### 295 "#]],
296 ); 296 );
297} 297}
298 298
299#[test] 299#[test]
300fn infer_trait_method_scoped() { 300fn infer_trait_method_scoped() {
301 // the trait implementation is intentionally incomplete -- it shouldn't matter 301 // the trait implementation is intentionally incomplete -- it shouldn't matter
302 assert_snapshot!( 302 check_infer(
303 infer(r#" 303 r#"
304struct S; 304 struct S;
305mod foo { 305 mod foo {
306 pub trait Trait1 { 306 pub trait Trait1 {
307 fn method(&self) -> u32; 307 fn method(&self) -> u32;
308 } 308 }
309 impl Trait1 for super::S {} 309 impl Trait1 for super::S {}
310} 310 }
311mod bar { 311 mod bar {
312 pub trait Trait2 { 312 pub trait Trait2 {
313 fn method(&self) -> i128; 313 fn method(&self) -> i128;
314 } 314 }
315 impl Trait2 for super::S {} 315 impl Trait2 for super::S {}
316} 316 }
317 317
318mod foo_test { 318 mod foo_test {
319 use super::S; 319 use super::S;
320 use super::foo::Trait1; 320 use super::foo::Trait1;
321 fn test() { 321 fn test() {
322 S.method(); // -> u32 322 S.method(); // -> u32
323 } 323 }
324} 324 }
325 325
326mod bar_test { 326 mod bar_test {
327 use super::S; 327 use super::S;
328 use super::bar::Trait2; 328 use super::bar::Trait2;
329 fn test() { 329 fn test() {
330 S.method(); // -> i128 330 S.method(); // -> i128
331 } 331 }
332} 332 }
333"#), 333 "#,
334 @r###" 334 expect![[r#"
335 62..66 'self': &Self 335 62..66 'self': &Self
336 168..172 'self': &Self 336 168..172 'self': &Self
337 299..336 '{ ... }': () 337 299..336 '{ ... }': ()
338 309..310 'S': S 338 309..310 'S': S
339 309..319 'S.method()': u32 339 309..319 'S.method()': u32
340 415..453 '{ ... }': () 340 415..453 '{ ... }': ()
341 425..426 'S': S 341 425..426 'S': S
342 425..435 'S.method()': i128 342 425..435 'S.method()': i128
343 "### 343 "#]],
344 ); 344 );
345} 345}
346 346
347#[test] 347#[test]
348fn infer_trait_method_generic_1() { 348fn infer_trait_method_generic_1() {
349 // the trait implementation is intentionally incomplete -- it shouldn't matter 349 // the trait implementation is intentionally incomplete -- it shouldn't matter
350 assert_snapshot!( 350 check_infer(
351 infer(r#" 351 r#"
352trait Trait<T> { 352 trait Trait<T> {
353 fn method(&self) -> T; 353 fn method(&self) -> T;
354} 354 }
355struct S; 355 struct S;
356impl Trait<u32> for S {} 356 impl Trait<u32> for S {}
357fn test() { 357 fn test() {
358 S.method(); 358 S.method();
359} 359 }
360"#), 360 "#,
361 @r###" 361 expect![[r#"
362 32..36 'self': &Self 362 32..36 'self': &Self
363 91..110 '{ ...d(); }': () 363 91..110 '{ ...d(); }': ()
364 97..98 'S': S 364 97..98 'S': S
365 97..107 'S.method()': u32 365 97..107 'S.method()': u32
366 "### 366 "#]],
367 ); 367 );
368} 368}
369 369
370#[test] 370#[test]
371fn infer_trait_method_generic_more_params() { 371fn infer_trait_method_generic_more_params() {
372 // the trait implementation is intentionally incomplete -- it shouldn't matter 372 // the trait implementation is intentionally incomplete -- it shouldn't matter
373 assert_snapshot!( 373 check_infer(
374 infer(r#" 374 r#"
375trait Trait<T1, T2, T3> { 375 trait Trait<T1, T2, T3> {
376 fn method1(&self) -> (T1, T2, T3); 376 fn method1(&self) -> (T1, T2, T3);
377 fn method2(&self) -> (T3, T2, T1); 377 fn method2(&self) -> (T3, T2, T1);
378} 378 }
379struct S1; 379 struct S1;
380impl Trait<u8, u16, u32> for S1 {} 380 impl Trait<u8, u16, u32> for S1 {}
381struct S2; 381 struct S2;
382impl<T> Trait<i8, i16, T> for S2 {} 382 impl<T> Trait<i8, i16, T> for S2 {}
383fn test() { 383 fn test() {
384 S1.method1(); // u8, u16, u32 384 S1.method1(); // u8, u16, u32
385 S1.method2(); // u32, u16, u8 385 S1.method2(); // u32, u16, u8
386 S2.method1(); // i8, i16, {unknown} 386 S2.method1(); // i8, i16, {unknown}
387 S2.method2(); // {unknown}, i16, i8 387 S2.method2(); // {unknown}, i16, i8
388} 388 }
389"#), 389 "#,
390 @r###" 390 expect![[r#"
391 42..46 'self': &Self 391 42..46 'self': &Self
392 81..85 'self': &Self 392 81..85 'self': &Self
393 209..360 '{ ..., i8 }': () 393 209..360 '{ ..., i8 }': ()
394 215..217 'S1': S1 394 215..217 'S1': S1
395 215..227 'S1.method1()': (u8, u16, u32) 395 215..227 'S1.method1()': (u8, u16, u32)
396 249..251 'S1': S1 396 249..251 'S1': S1
397 249..261 'S1.method2()': (u32, u16, u8) 397 249..261 'S1.method2()': (u32, u16, u8)
398 283..285 'S2': S2 398 283..285 'S2': S2
399 283..295 'S2.method1()': (i8, i16, {unknown}) 399 283..295 'S2.method1()': (i8, i16, {unknown})
400 323..325 'S2': S2 400 323..325 'S2': S2
401 323..335 'S2.method2()': ({unknown}, i16, i8) 401 323..335 'S2.method2()': ({unknown}, i16, i8)
402 "### 402 "#]],
403 ); 403 );
404} 404}
405 405
406#[test] 406#[test]
407fn infer_trait_method_generic_2() { 407fn infer_trait_method_generic_2() {
408 // the trait implementation is intentionally incomplete -- it shouldn't matter 408 // the trait implementation is intentionally incomplete -- it shouldn't matter
409 assert_snapshot!( 409 check_infer(
410 infer(r#" 410 r#"
411trait Trait<T> { 411 trait Trait<T> {
412 fn method(&self) -> T; 412 fn method(&self) -> T;
413} 413 }
414struct S<T>(T); 414 struct S<T>(T);
415impl<U> Trait<U> for S<U> {} 415 impl<U> Trait<U> for S<U> {}
416fn test() { 416 fn test() {
417 S(1u32).method(); 417 S(1u32).method();
418} 418 }
419"#), 419 "#,
420 @r###" 420 expect![[r#"
421 32..36 'self': &Self 421 32..36 'self': &Self
422 101..126 '{ ...d(); }': () 422 101..126 '{ ...d(); }': ()
423 107..108 'S': S<u32>(u32) -> S<u32> 423 107..108 'S': S<u32>(u32) -> S<u32>
424 107..114 'S(1u32)': S<u32> 424 107..114 'S(1u32)': S<u32>
425 107..123 'S(1u32...thod()': u32 425 107..123 'S(1u32...thod()': u32
426 109..113 '1u32': u32 426 109..113 '1u32': u32
427 "### 427 "#]],
428 ); 428 );
429} 429}
430 430
431#[test] 431#[test]
432fn infer_trait_assoc_method() { 432fn infer_trait_assoc_method() {
433 assert_snapshot!( 433 check_infer(
434 infer(r#" 434 r#"
435trait Default { 435 trait Default {
436 fn default() -> Self; 436 fn default() -> Self;
437} 437 }
438struct S; 438 struct S;
439impl Default for S {} 439 impl Default for S {}
440fn test() { 440 fn test() {
441 let s1: S = Default::default(); 441 let s1: S = Default::default();
442 let s2 = S::default(); 442 let s2 = S::default();
443 let s3 = <S as Default>::default(); 443 let s3 = <S as Default>::default();
444} 444 }
445"#), 445 "#,
446 @r###" 446 expect![[r#"
447 86..192 '{ ...t(); }': () 447 86..192 '{ ...t(); }': ()
448 96..98 's1': S 448 96..98 's1': S
449 104..120 'Defaul...efault': fn default<S>() -> S 449 104..120 'Defaul...efault': fn default<S>() -> S
450 104..122 'Defaul...ault()': S 450 104..122 'Defaul...ault()': S
451 132..134 's2': S 451 132..134 's2': S
452 137..147 'S::default': fn default<S>() -> S 452 137..147 'S::default': fn default<S>() -> S
453 137..149 'S::default()': S 453 137..149 'S::default()': S
454 159..161 's3': S 454 159..161 's3': S
455 164..187 '<S as ...efault': fn default<S>() -> S 455 164..187 '<S as ...efault': fn default<S>() -> S
456 164..189 '<S as ...ault()': S 456 164..189 '<S as ...ault()': S
457 "### 457 "#]],
458 ); 458 );
459} 459}
460 460
461#[test] 461#[test]
462fn infer_trait_assoc_method_generics_1() { 462fn infer_trait_assoc_method_generics_1() {
463 assert_snapshot!( 463 check_infer(
464 infer(r#" 464 r#"
465trait Trait<T> { 465 trait Trait<T> {
466 fn make() -> T; 466 fn make() -> T;
467} 467 }
468struct S; 468 struct S;
469impl Trait<u32> for S {} 469 impl Trait<u32> for S {}
470struct G<T>; 470 struct G<T>;
471impl<T> Trait<T> for G<T> {} 471 impl<T> Trait<T> for G<T> {}
472fn test() { 472 fn test() {
473 let a = S::make(); 473 let a = S::make();
474 let b = G::<u64>::make(); 474 let b = G::<u64>::make();
475 let c: f64 = G::make(); 475 let c: f64 = G::make();
476} 476 }
477"#), 477 "#,
478 @r###" 478 expect![[r#"
479 126..210 '{ ...e(); }': () 479 126..210 '{ ...e(); }': ()
480 136..137 'a': u32 480 136..137 'a': u32
481 140..147 'S::make': fn make<S, u32>() -> u32 481 140..147 'S::make': fn make<S, u32>() -> u32
482 140..149 'S::make()': u32 482 140..149 'S::make()': u32
483 159..160 'b': u64 483 159..160 'b': u64
484 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64 484 163..177 'G::<u64>::make': fn make<G<u64>, u64>() -> u64
485 163..179 'G::<u6...make()': u64 485 163..179 'G::<u6...make()': u64
486 189..190 'c': f64 486 189..190 'c': f64
487 198..205 'G::make': fn make<G<f64>, f64>() -> f64 487 198..205 'G::make': fn make<G<f64>, f64>() -> f64
488 198..207 'G::make()': f64 488 198..207 'G::make()': f64
489 "### 489 "#]],
490 ); 490 );
491} 491}
492 492
493#[test] 493#[test]
494fn infer_trait_assoc_method_generics_2() { 494fn infer_trait_assoc_method_generics_2() {
495 assert_snapshot!( 495 check_infer(
496 infer(r#" 496 r#"
497trait Trait<T> { 497 trait Trait<T> {
498 fn make<U>() -> (T, U); 498 fn make<U>() -> (T, U);
499} 499 }
500struct S; 500 struct S;
501impl Trait<u32> for S {} 501 impl Trait<u32> for S {}
502struct G<T>; 502 struct G<T>;
503impl<T> Trait<T> for G<T> {} 503 impl<T> Trait<T> for G<T> {}
504fn test() { 504 fn test() {
505 let a = S::make::<i64>(); 505 let a = S::make::<i64>();
506 let b: (_, i64) = S::make(); 506 let b: (_, i64) = S::make();
507 let c = G::<u32>::make::<i64>(); 507 let c = G::<u32>::make::<i64>();
508 let d: (u32, _) = G::make::<i64>(); 508 let d: (u32, _) = G::make::<i64>();
509 let e: (u32, i64) = G::make(); 509 let e: (u32, i64) = G::make();
510} 510 }
511"#), 511 "#,
512 @r###" 512 expect![[r#"
513 134..312 '{ ...e(); }': () 513 134..312 '{ ...e(); }': ()
514 144..145 'a': (u32, i64) 514 144..145 'a': (u32, i64)
515 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64) 515 148..162 'S::make::<i64>': fn make<S, u32, i64>() -> (u32, i64)
516 148..164 'S::mak...i64>()': (u32, i64) 516 148..164 'S::mak...i64>()': (u32, i64)
517 174..175 'b': (u32, i64) 517 174..175 'b': (u32, i64)
518 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64) 518 188..195 'S::make': fn make<S, u32, i64>() -> (u32, i64)
519 188..197 'S::make()': (u32, i64) 519 188..197 'S::make()': (u32, i64)
520 207..208 'c': (u32, i64) 520 207..208 'c': (u32, i64)
521 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) 521 211..232 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
522 211..234 'G::<u3...i64>()': (u32, i64) 522 211..234 'G::<u3...i64>()': (u32, i64)
523 244..245 'd': (u32, i64) 523 244..245 'd': (u32, i64)
524 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64) 524 258..272 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (u32, i64)
525 258..274 'G::mak...i64>()': (u32, i64) 525 258..274 'G::mak...i64>()': (u32, i64)
526 284..285 'e': (u32, i64) 526 284..285 'e': (u32, i64)
527 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64) 527 300..307 'G::make': fn make<G<u32>, u32, i64>() -> (u32, i64)
528 300..309 'G::make()': (u32, i64) 528 300..309 'G::make()': (u32, i64)
529 "### 529 "#]],
530 ); 530 );
531} 531}
532 532
533#[test] 533#[test]
534fn infer_trait_assoc_method_generics_3() { 534fn infer_trait_assoc_method_generics_3() {
535 assert_snapshot!( 535 check_infer(
536 infer(r#" 536 r#"
537trait Trait<T> { 537 trait Trait<T> {
538 fn make() -> (Self, T); 538 fn make() -> (Self, T);
539} 539 }
540struct S<T>; 540 struct S<T>;
541impl Trait<i64> for S<i32> {} 541 impl Trait<i64> for S<i32> {}
542fn test() { 542 fn test() {
543 let a = S::make(); 543 let a = S::make();
544} 544 }
545"#), 545 "#,
546 @r###" 546 expect![[r#"
547 100..126 '{ ...e(); }': () 547 100..126 '{ ...e(); }': ()
548 110..111 'a': (S<i32>, i64) 548 110..111 'a': (S<i32>, i64)
549 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64) 549 114..121 'S::make': fn make<S<i32>, i64>() -> (S<i32>, i64)
550 114..123 'S::make()': (S<i32>, i64) 550 114..123 'S::make()': (S<i32>, i64)
551 "### 551 "#]],
552 ); 552 );
553} 553}
554 554
555#[test] 555#[test]
556fn infer_trait_assoc_method_generics_4() { 556fn infer_trait_assoc_method_generics_4() {
557 assert_snapshot!( 557 check_infer(
558 infer(r#" 558 r#"
559trait Trait<T> { 559 trait Trait<T> {
560 fn make() -> (Self, T); 560 fn make() -> (Self, T);
561} 561 }
562struct S<T>; 562 struct S<T>;
563impl Trait<i64> for S<u64> {} 563 impl Trait<i64> for S<u64> {}
564impl Trait<i32> for S<u32> {} 564 impl Trait<i32> for S<u32> {}
565fn test() { 565 fn test() {
566 let a: (S<u64>, _) = S::make(); 566 let a: (S<u64>, _) = S::make();
567 let b: (_, i32) = S::make(); 567 let b: (_, i32) = S::make();
568} 568 }
569"#), 569 "#,
570 @r###" 570 expect![[r#"
571 130..202 '{ ...e(); }': () 571 130..202 '{ ...e(); }': ()
572 140..141 'a': (S<u64>, i64) 572 140..141 'a': (S<u64>, i64)
573 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64) 573 157..164 'S::make': fn make<S<u64>, i64>() -> (S<u64>, i64)
574 157..166 'S::make()': (S<u64>, i64) 574 157..166 'S::make()': (S<u64>, i64)
575 176..177 'b': (S<u32>, i32) 575 176..177 'b': (S<u32>, i32)
576 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32) 576 190..197 'S::make': fn make<S<u32>, i32>() -> (S<u32>, i32)
577 190..199 'S::make()': (S<u32>, i32) 577 190..199 'S::make()': (S<u32>, i32)
578 "### 578 "#]],
579 ); 579 );
580} 580}
581 581
582#[test] 582#[test]
583fn infer_trait_assoc_method_generics_5() { 583fn infer_trait_assoc_method_generics_5() {
584 assert_snapshot!( 584 check_infer(
585 infer(r#" 585 r#"
586trait Trait<T> { 586 trait Trait<T> {
587 fn make<U>() -> (Self, T, U); 587 fn make<U>() -> (Self, T, U);
588} 588 }
589struct S<T>; 589 struct S<T>;
590impl Trait<i64> for S<u64> {} 590 impl Trait<i64> for S<u64> {}
591fn test() { 591 fn test() {
592 let a = <S as Trait<i64>>::make::<u8>(); 592 let a = <S as Trait<i64>>::make::<u8>();
593 let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>(); 593 let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>();
594} 594 }
595"#), 595 "#,
596 @r###" 596 expect![[r#"
597 106..210 '{ ...>(); }': () 597 106..210 '{ ...>(); }': ()
598 116..117 'a': (S<u64>, i64, u8) 598 116..117 'a': (S<u64>, i64, u8)
599 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) 599 120..149 '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
600 120..151 '<S as ...<u8>()': (S<u64>, i64, u8) 600 120..151 '<S as ...<u8>()': (S<u64>, i64, u8)
601 161..162 'b': (S<u64>, i64, u8) 601 161..162 'b': (S<u64>, i64, u8)
602 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8) 602 181..205 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (S<u64>, i64, u8)
603 181..207 'Trait:...<u8>()': (S<u64>, i64, u8) 603 181..207 'Trait:...<u8>()': (S<u64>, i64, u8)
604 "### 604 "#]],
605 ); 605 );
606} 606}
607 607
608#[test] 608#[test]
609fn infer_call_trait_method_on_generic_param_1() { 609fn infer_call_trait_method_on_generic_param_1() {
610 assert_snapshot!( 610 check_infer(
611 infer(r#" 611 r#"
612trait Trait { 612 trait Trait {
613 fn method(&self) -> u32; 613 fn method(&self) -> u32;
614} 614 }
615fn test<T: Trait>(t: T) { 615 fn test<T: Trait>(t: T) {
616 t.method(); 616 t.method();
617} 617 }
618"#), 618 "#,
619 @r###" 619 expect![[r#"
620 29..33 'self': &Self 620 29..33 'self': &Self
621 63..64 't': T 621 63..64 't': T
622 69..88 '{ ...d(); }': () 622 69..88 '{ ...d(); }': ()
623 75..76 't': T 623 75..76 't': T
624 75..85 't.method()': u32 624 75..85 't.method()': u32
625 "### 625 "#]],
626 ); 626 );
627} 627}
628 628
629#[test] 629#[test]
630fn infer_call_trait_method_on_generic_param_2() { 630fn infer_call_trait_method_on_generic_param_2() {
631 assert_snapshot!( 631 check_infer(
632 infer(r#" 632 r#"
633trait Trait<T> { 633 trait Trait<T> {
634 fn method(&self) -> T; 634 fn method(&self) -> T;
635} 635 }
636fn test<U, T: Trait<U>>(t: T) { 636 fn test<U, T: Trait<U>>(t: T) {
637 t.method(); 637 t.method();
638} 638 }
639"#), 639 "#,
640 @r###" 640 expect![[r#"
641 32..36 'self': &Self 641 32..36 'self': &Self
642 70..71 't': T 642 70..71 't': T
643 76..95 '{ ...d(); }': () 643 76..95 '{ ...d(); }': ()
644 82..83 't': T 644 82..83 't': T
645 82..92 't.method()': U 645 82..92 't.method()': U
646 "### 646 "#]],
647 ); 647 );
648} 648}
649 649
650#[test] 650#[test]
651fn infer_with_multiple_trait_impls() { 651fn infer_with_multiple_trait_impls() {
652 assert_snapshot!( 652 check_infer(
653 infer(r#" 653 r#"
654trait Into<T> { 654 trait Into<T> {
655 fn into(self) -> T; 655 fn into(self) -> T;
656} 656 }
657struct S; 657 struct S;
658impl Into<u32> for S {} 658 impl Into<u32> for S {}
659impl Into<u64> for S {} 659 impl Into<u64> for S {}
660fn test() { 660 fn test() {
661 let x: u32 = S.into(); 661 let x: u32 = S.into();
662 let y: u64 = S.into(); 662 let y: u64 = S.into();
663 let z = Into::<u64>::into(S); 663 let z = Into::<u64>::into(S);
664} 664 }
665"#), 665 "#,
666 @r###" 666 expect![[r#"
667 28..32 'self': Self 667 28..32 'self': Self
668 110..201 '{ ...(S); }': () 668 110..201 '{ ...(S); }': ()
669 120..121 'x': u32 669 120..121 'x': u32
670 129..130 'S': S 670 129..130 'S': S
671 129..137 'S.into()': u32 671 129..137 'S.into()': u32
672 147..148 'y': u64 672 147..148 'y': u64
673 156..157 'S': S 673 156..157 'S': S
674 156..164 'S.into()': u64 674 156..164 'S.into()': u64
675 174..175 'z': u64 675 174..175 'z': u64
676 178..195 'Into::...::into': fn into<S, u64>(S) -> u64 676 178..195 'Into::...::into': fn into<S, u64>(S) -> u64
677 178..198 'Into::...nto(S)': u64 677 178..198 'Into::...nto(S)': u64
678 196..197 'S': S 678 196..197 'S': S
679 "### 679 "#]],
680 ); 680 );
681} 681}
682 682
@@ -1023,31 +1023,31 @@ fn test() { (S {}).method(); }
1023 1023
1024#[test] 1024#[test]
1025fn dyn_trait_super_trait_not_in_scope() { 1025fn dyn_trait_super_trait_not_in_scope() {
1026 assert_snapshot!( 1026 check_infer(
1027 infer(r#" 1027 r#"
1028mod m { 1028 mod m {
1029 pub trait SuperTrait { 1029 pub trait SuperTrait {
1030 fn foo(&self) -> u32 { 0 } 1030 fn foo(&self) -> u32 { 0 }
1031 } 1031 }
1032} 1032 }
1033trait Trait: m::SuperTrait {} 1033 trait Trait: m::SuperTrait {}
1034 1034
1035struct S; 1035 struct S;
1036impl m::SuperTrait for S {} 1036 impl m::SuperTrait for S {}
1037impl Trait for S {} 1037 impl Trait for S {}
1038 1038
1039fn test(d: &dyn Trait) { 1039 fn test(d: &dyn Trait) {
1040 d.foo(); 1040 d.foo();
1041} 1041 }
1042"#), 1042 "#,
1043 @r###" 1043 expect![[r#"
1044 51..55 'self': &Self 1044 51..55 'self': &Self
1045 64..69 '{ 0 }': u32 1045 64..69 '{ 0 }': u32
1046 66..67 '0': u32 1046 66..67 '0': u32
1047 176..177 'd': &dyn Trait 1047 176..177 'd': &dyn Trait
1048 191..207 '{ ...o(); }': () 1048 191..207 '{ ...o(); }': ()
1049 197..198 'd': &dyn Trait 1049 197..198 'd': &dyn Trait
1050 197..204 'd.foo()': u32 1050 197..204 'd.foo()': u32
1051 "### 1051 "#]],
1052 ); 1052 );
1053} 1053}
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 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::{infer, infer_with_mismatches}; 4use super::{check_infer, check_infer_with_mismatches};
5 5
6#[test] 6#[test]
7fn infer_pattern() { 7fn infer_pattern() {
8 assert_snapshot!( 8 check_infer(
9 infer(r#" 9 r#"
10fn test(x: &i32) { 10 fn test(x: &i32) {
11 let y = x; 11 let y = x;
12 let &z = x; 12 let &z = x;
13 let a = z; 13 let a = z;
14 let (c, d) = (1, "hello"); 14 let (c, d) = (1, "hello");
15 15
16 for (e, f) in some_iter { 16 for (e, f) in some_iter {
17 let g = e; 17 let g = e;
18 } 18 }
19 19
20 if let [val] = opt { 20 if let [val] = opt {
21 let h = val; 21 let h = val;
22 } 22 }
23 23
24 let lambda = |a: u64, b, c: i32| { a + b; c }; 24 let lambda = |a: u64, b, c: i32| { a + b; c };
25 25
26 let ref ref_to_x = x; 26 let ref ref_to_x = x;
27 let mut mut_x = x; 27 let mut mut_x = x;
28 let ref mut mut_ref_to_x = x; 28 let ref mut mut_ref_to_x = x;
29 let k = mut_ref_to_x; 29 let k = mut_ref_to_x;
30} 30 }
31"#), 31 "#,
32 @r###" 32 expect![[r#"
33 8..9 'x': &i32 33 8..9 'x': &i32
34 17..368 '{ ...o_x; }': () 34 17..368 '{ ...o_x; }': ()
35 27..28 'y': &i32 35 27..28 'y': &i32
36 31..32 'x': &i32 36 31..32 'x': &i32
37 42..44 '&z': &i32 37 42..44 '&z': &i32
38 43..44 'z': i32 38 43..44 'z': i32
39 47..48 'x': &i32 39 47..48 'x': &i32
40 58..59 'a': i32 40 58..59 'a': i32
41 62..63 'z': i32 41 62..63 'z': i32
42 73..79 '(c, d)': (i32, &str) 42 73..79 '(c, d)': (i32, &str)
43 74..75 'c': i32 43 74..75 'c': i32
44 77..78 'd': &str 44 77..78 'd': &str
45 82..94 '(1, "hello")': (i32, &str) 45 82..94 '(1, "hello")': (i32, &str)
46 83..84 '1': i32 46 83..84 '1': i32
47 86..93 '"hello"': &str 47 86..93 '"hello"': &str
48 101..151 'for (e... }': () 48 101..151 'for (e... }': ()
49 105..111 '(e, f)': ({unknown}, {unknown}) 49 105..111 '(e, f)': ({unknown}, {unknown})
50 106..107 'e': {unknown} 50 106..107 'e': {unknown}
51 109..110 'f': {unknown} 51 109..110 'f': {unknown}
52 115..124 'some_iter': {unknown} 52 115..124 'some_iter': {unknown}
53 125..151 '{ ... }': () 53 125..151 '{ ... }': ()
54 139..140 'g': {unknown} 54 139..140 'g': {unknown}
55 143..144 'e': {unknown} 55 143..144 'e': {unknown}
56 157..204 'if let... }': () 56 157..204 'if let... }': ()
57 164..169 '[val]': [{unknown}] 57 164..169 '[val]': [{unknown}]
58 165..168 'val': {unknown} 58 165..168 'val': {unknown}
59 172..175 'opt': [{unknown}] 59 172..175 'opt': [{unknown}]
60 176..204 '{ ... }': () 60 176..204 '{ ... }': ()
61 190..191 'h': {unknown} 61 190..191 'h': {unknown}
62 194..197 'val': {unknown} 62 194..197 'val': {unknown}
63 214..220 'lambda': |u64, u64, i32| -> i32 63 214..220 'lambda': |u64, u64, i32| -> i32
64 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32 64 223..255 '|a: u6...b; c }': |u64, u64, i32| -> i32
65 224..225 'a': u64 65 224..225 'a': u64
66 232..233 'b': u64 66 232..233 'b': u64
67 235..236 'c': i32 67 235..236 'c': i32
68 243..255 '{ a + b; c }': i32 68 243..255 '{ a + b; c }': i32
69 245..246 'a': u64 69 245..246 'a': u64
70 245..250 'a + b': u64 70 245..250 'a + b': u64
71 249..250 'b': u64 71 249..250 'b': u64
72 252..253 'c': i32 72 252..253 'c': i32
73 266..278 'ref ref_to_x': &&i32 73 266..278 'ref ref_to_x': &&i32
74 281..282 'x': &i32 74 281..282 'x': &i32
75 292..301 'mut mut_x': &i32 75 292..301 'mut mut_x': &i32
76 304..305 'x': &i32 76 304..305 'x': &i32
77 315..335 'ref mu...f_to_x': &mut &i32 77 315..335 'ref mu...f_to_x': &mut &i32
78 338..339 'x': &i32 78 338..339 'x': &i32
79 349..350 'k': &mut &i32 79 349..350 'k': &mut &i32
80 353..365 'mut_ref_to_x': &mut &i32 80 353..365 'mut_ref_to_x': &mut &i32
81 "### 81 "#]],
82 ); 82 );
83} 83}
84 84
85#[test] 85#[test]
86fn infer_literal_pattern() { 86fn infer_literal_pattern() {
87 assert_snapshot!( 87 check_infer_with_mismatches(
88 infer_with_mismatches(r#" 88 r#"
89fn any<T>() -> T { loop {} } 89 fn any<T>() -> T { loop {} }
90fn test(x: &i32) { 90 fn test(x: &i32) {
91 if let "foo" = any() {} 91 if let "foo" = any() {}
92 if let 1 = any() {} 92 if let 1 = any() {}
93 if let 1u32 = any() {} 93 if let 1u32 = any() {}
94 if let 1f32 = any() {} 94 if let 1f32 = any() {}
95 if let 1.0 = any() {} 95 if let 1.0 = any() {}
96 if let true = any() {} 96 if let true = any() {}
97} 97 }
98"#, true), 98 "#,
99 @r###" 99 expect![[r#"
100 17..28 '{ loop {} }': T 100 17..28 '{ loop {} }': T
101 19..26 'loop {}': ! 101 19..26 'loop {}': !
102 24..26 '{}': () 102 24..26 '{}': ()
103 37..38 'x': &i32 103 37..38 'x': &i32
104 46..208 '{ ...) {} }': () 104 46..208 '{ ...) {} }': ()
105 52..75 'if let...y() {}': () 105 52..75 'if let...y() {}': ()
106 59..64 '"foo"': &str 106 59..64 '"foo"': &str
107 59..64 '"foo"': &str 107 59..64 '"foo"': &str
108 67..70 'any': fn any<&str>() -> &str 108 67..70 'any': fn any<&str>() -> &str
109 67..72 'any()': &str 109 67..72 'any()': &str
110 73..75 '{}': () 110 73..75 '{}': ()
111 80..99 'if let...y() {}': () 111 80..99 'if let...y() {}': ()
112 87..88 '1': i32 112 87..88 '1': i32
113 87..88 '1': i32 113 87..88 '1': i32
114 91..94 'any': fn any<i32>() -> i32 114 91..94 'any': fn any<i32>() -> i32
115 91..96 'any()': i32 115 91..96 'any()': i32
116 97..99 '{}': () 116 97..99 '{}': ()
117 104..126 'if let...y() {}': () 117 104..126 'if let...y() {}': ()
118 111..115 '1u32': u32 118 111..115 '1u32': u32
119 111..115 '1u32': u32 119 111..115 '1u32': u32
120 118..121 'any': fn any<u32>() -> u32 120 118..121 'any': fn any<u32>() -> u32
121 118..123 'any()': u32 121 118..123 'any()': u32
122 124..126 '{}': () 122 124..126 '{}': ()
123 131..153 'if let...y() {}': () 123 131..153 'if let...y() {}': ()
124 138..142 '1f32': f32 124 138..142 '1f32': f32
125 138..142 '1f32': f32 125 138..142 '1f32': f32
126 145..148 'any': fn any<f32>() -> f32 126 145..148 'any': fn any<f32>() -> f32
127 145..150 'any()': f32 127 145..150 'any()': f32
128 151..153 '{}': () 128 151..153 '{}': ()
129 158..179 'if let...y() {}': () 129 158..179 'if let...y() {}': ()
130 165..168 '1.0': f64 130 165..168 '1.0': f64
131 165..168 '1.0': f64 131 165..168 '1.0': f64
132 171..174 'any': fn any<f64>() -> f64 132 171..174 'any': fn any<f64>() -> f64
133 171..176 'any()': f64 133 171..176 'any()': f64
134 177..179 '{}': () 134 177..179 '{}': ()
135 184..206 'if let...y() {}': () 135 184..206 'if let...y() {}': ()
136 191..195 'true': bool 136 191..195 'true': bool
137 191..195 'true': bool 137 191..195 'true': bool
138 198..201 'any': fn any<bool>() -> bool 138 198..201 'any': fn any<bool>() -> bool
139 198..203 'any()': bool 139 198..203 'any()': bool
140 204..206 '{}': () 140 204..206 '{}': ()
141 "### 141 "#]],
142 ); 142 );
143} 143}
144 144
145#[test] 145#[test]
146fn infer_range_pattern() { 146fn infer_range_pattern() {
147 assert_snapshot!( 147 check_infer_with_mismatches(
148 infer_with_mismatches(r#" 148 r#"
149fn test(x: &i32) { 149 fn test(x: &i32) {
150 if let 1..76 = 2u32 {} 150 if let 1..76 = 2u32 {}
151 if let 1..=76 = 2u32 {} 151 if let 1..=76 = 2u32 {}
152} 152 }
153"#, true), 153 "#,
154 @r###" 154 expect![[r#"
155 8..9 'x': &i32 155 8..9 'x': &i32
156 17..75 '{ ...2 {} }': () 156 17..75 '{ ...2 {} }': ()
157 23..45 'if let...u32 {}': () 157 23..45 'if let...u32 {}': ()
158 30..35 '1..76': u32 158 30..35 '1..76': u32
159 38..42 '2u32': u32 159 38..42 '2u32': u32
160 43..45 '{}': () 160 43..45 '{}': ()
161 50..73 'if let...u32 {}': () 161 50..73 'if let...u32 {}': ()
162 57..63 '1..=76': u32 162 57..63 '1..=76': u32
163 66..70 '2u32': u32 163 66..70 '2u32': u32
164 71..73 '{}': () 164 71..73 '{}': ()
165 "### 165 "#]],
166 ); 166 );
167} 167}
168 168
169#[test] 169#[test]
170fn infer_pattern_match_ergonomics() { 170fn infer_pattern_match_ergonomics() {
171 assert_snapshot!( 171 check_infer(
172 infer(r#" 172 r#"
173struct A<T>(T); 173 struct A<T>(T);
174 174
175fn test() { 175 fn test() {
176 let A(n) = &A(1); 176 let A(n) = &A(1);
177 let A(n) = &mut A(1); 177 let A(n) = &mut A(1);
178} 178 }
179"#), 179 "#,
180 @r###" 180 expect![[r#"
181 27..78 '{ ...(1); }': () 181 27..78 '{ ...(1); }': ()
182 37..41 'A(n)': A<i32> 182 37..41 'A(n)': A<i32>
183 39..40 'n': &i32 183 39..40 'n': &i32
184 44..49 '&A(1)': &A<i32> 184 44..49 '&A(1)': &A<i32>
185 45..46 'A': A<i32>(i32) -> A<i32> 185 45..46 'A': A<i32>(i32) -> A<i32>
186 45..49 'A(1)': A<i32> 186 45..49 'A(1)': A<i32>
187 47..48 '1': i32 187 47..48 '1': i32
188 59..63 'A(n)': A<i32> 188 59..63 'A(n)': A<i32>
189 61..62 'n': &mut i32 189 61..62 'n': &mut i32
190 66..75 '&mut A(1)': &mut A<i32> 190 66..75 '&mut A(1)': &mut A<i32>
191 71..72 'A': A<i32>(i32) -> A<i32> 191 71..72 'A': A<i32>(i32) -> A<i32>
192 71..75 'A(1)': A<i32> 192 71..75 'A(1)': A<i32>
193 73..74 '1': i32 193 73..74 '1': i32
194 "### 194 "#]],
195 ); 195 );
196} 196}
197 197
198#[test] 198#[test]
199fn infer_pattern_match_ergonomics_ref() { 199fn infer_pattern_match_ergonomics_ref() {
200 mark::check!(match_ergonomics_ref); 200 mark::check!(match_ergonomics_ref);
201 assert_snapshot!( 201 check_infer(
202 infer(r#" 202 r#"
203fn test() { 203 fn test() {
204 let v = &(1, &2); 204 let v = &(1, &2);
205 let (_, &w) = v; 205 let (_, &w) = v;
206} 206 }
207"#), 207 "#,
208 @r###" 208 expect![[r#"
209 10..56 '{ ...= v; }': () 209 10..56 '{ ...= v; }': ()
210 20..21 'v': &(i32, &i32) 210 20..21 'v': &(i32, &i32)
211 24..32 '&(1, &2)': &(i32, &i32) 211 24..32 '&(1, &2)': &(i32, &i32)
212 25..32 '(1, &2)': (i32, &i32) 212 25..32 '(1, &2)': (i32, &i32)
213 26..27 '1': i32 213 26..27 '1': i32
214 29..31 '&2': &i32 214 29..31 '&2': &i32
215 30..31 '2': i32 215 30..31 '2': i32
216 42..49 '(_, &w)': (i32, &i32) 216 42..49 '(_, &w)': (i32, &i32)
217 43..44 '_': i32 217 43..44 '_': i32
218 46..48 '&w': &i32 218 46..48 '&w': &i32
219 47..48 'w': i32 219 47..48 'w': i32
220 52..53 'v': &(i32, &i32) 220 52..53 'v': &(i32, &i32)
221 "### 221 "#]],
222 ); 222 );
223} 223}
224 224
225#[test] 225#[test]
226fn infer_pattern_match_slice() { 226fn infer_pattern_match_slice() {
227 assert_snapshot!( 227 check_infer(
228 infer(r#" 228 r#"
229fn test() { 229 fn test() {
230 let slice: &[f64] = &[0.0]; 230 let slice: &[f64] = &[0.0];
231 match slice { 231 match slice {
232 &[] => {}, 232 &[] => {},
233 &[a] => { 233 &[a] => {
234 a; 234 a;
235 }, 235 },
236 &[b, c] => { 236 &[b, c] => {
237 b; 237 b;
238 c; 238 c;
239 }
240 _ => {}
241 }
239 } 242 }
240 _ => {} 243 "#,
241 } 244 expect![[r#"
242} 245 10..209 '{ ... } }': ()
243"#), 246 20..25 'slice': &[f64]
244 @r###" 247 36..42 '&[0.0]': &[f64; _]
245 10..209 '{ ... } }': () 248 37..42 '[0.0]': [f64; _]
246 20..25 'slice': &[f64] 249 38..41 '0.0': f64
247 36..42 '&[0.0]': &[f64; _] 250 48..207 'match ... }': ()
248 37..42 '[0.0]': [f64; _] 251 54..59 'slice': &[f64]
249 38..41 '0.0': f64 252 70..73 '&[]': &[f64]
250 48..207 'match ... }': () 253 71..73 '[]': [f64]
251 54..59 'slice': &[f64] 254 77..79 '{}': ()
252 70..73 '&[]': &[f64] 255 89..93 '&[a]': &[f64]
253 71..73 '[]': [f64] 256 90..93 '[a]': [f64]
254 77..79 '{}': () 257 91..92 'a': f64
255 89..93 '&[a]': &[f64] 258 97..123 '{ ... }': ()
256 90..93 '[a]': [f64] 259 111..112 'a': f64
257 91..92 'a': f64 260 133..140 '&[b, c]': &[f64]
258 97..123 '{ ... }': () 261 134..140 '[b, c]': [f64]
259 111..112 'a': f64 262 135..136 'b': f64
260 133..140 '&[b, c]': &[f64] 263 138..139 'c': f64
261 134..140 '[b, c]': [f64] 264 144..185 '{ ... }': ()
262 135..136 'b': f64 265 158..159 'b': f64
263 138..139 'c': f64 266 173..174 'c': f64
264 144..185 '{ ... }': () 267 194..195 '_': &[f64]
265 158..159 'b': f64 268 199..201 '{}': ()
266 173..174 'c': f64 269 "#]],
267 194..195 '_': &[f64]
268 199..201 '{}': ()
269 "###
270 ); 270 );
271} 271}
272 272
273#[test] 273#[test]
274fn infer_pattern_match_string_literal() { 274fn infer_pattern_match_string_literal() {
275 assert_snapshot!( 275 check_infer_with_mismatches(
276 infer_with_mismatches(r#" 276 r#"
277fn test() { 277 fn test() {
278 let s: &str = "hello"; 278 let s: &str = "hello";
279 match s { 279 match s {
280 "hello" => {} 280 "hello" => {}
281 _ => {} 281 _ => {}
282 } 282 }
283} 283 }
284"#, true), 284 "#,
285 @r###" 285 expect![[r#"
286 10..98 '{ ... } }': () 286 10..98 '{ ... } }': ()
287 20..21 's': &str 287 20..21 's': &str
288 30..37 '"hello"': &str 288 30..37 '"hello"': &str
289 43..96 'match ... }': () 289 43..96 'match ... }': ()
290 49..50 's': &str 290 49..50 's': &str
291 61..68 '"hello"': &str 291 61..68 '"hello"': &str
292 61..68 '"hello"': &str 292 61..68 '"hello"': &str
293 72..74 '{}': () 293 72..74 '{}': ()
294 83..84 '_': &str 294 83..84 '_': &str
295 88..90 '{}': () 295 88..90 '{}': ()
296 "### 296 "#]],
297 ); 297 );
298} 298}
299 299
300#[test] 300#[test]
301fn infer_pattern_match_or() { 301fn infer_pattern_match_or() {
302 assert_snapshot!( 302 check_infer_with_mismatches(
303 infer_with_mismatches(r#" 303 r#"
304fn test() { 304 fn test() {
305 let s: &str = "hello"; 305 let s: &str = "hello";
306 match s { 306 match s {
307 "hello" | "world" => {} 307 "hello" | "world" => {}
308 _ => {} 308 _ => {}
309 } 309 }
310} 310 }
311"#, true), 311 "#,
312 @r###" 312 expect![[r#"
313 10..108 '{ ... } }': () 313 10..108 '{ ... } }': ()
314 20..21 's': &str 314 20..21 's': &str
315 30..37 '"hello"': &str 315 30..37 '"hello"': &str
316 43..106 'match ... }': () 316 43..106 'match ... }': ()
317 49..50 's': &str 317 49..50 's': &str
318 61..68 '"hello"': &str 318 61..68 '"hello"': &str
319 61..68 '"hello"': &str 319 61..68 '"hello"': &str
320 61..78 '"hello...world"': &str 320 61..78 '"hello...world"': &str
321 71..78 '"world"': &str 321 71..78 '"world"': &str
322 71..78 '"world"': &str 322 71..78 '"world"': &str
323 82..84 '{}': () 323 82..84 '{}': ()
324 93..94 '_': &str 324 93..94 '_': &str
325 98..100 '{}': () 325 98..100 '{}': ()
326 "### 326 "#]],
327 ); 327 );
328} 328}
329 329
330#[test] 330#[test]
331fn infer_pattern_match_arr() { 331fn infer_pattern_match_arr() {
332 assert_snapshot!( 332 check_infer(
333 infer(r#" 333 r#"
334fn test() { 334 fn test() {
335 let arr: [f64; 2] = [0.0, 1.0]; 335 let arr: [f64; 2] = [0.0, 1.0];
336 match arr { 336 match arr {
337 [1.0, a] => { 337 [1.0, a] => {
338 a; 338 a;
339 }, 339 },
340 [b, c] => { 340 [b, c] => {
341 b; 341 b;
342 c; 342 c;
343 }
344 }
343 } 345 }
344 } 346 "#,
345} 347 expect![[r#"
346"#), 348 10..179 '{ ... } }': ()
347 @r###" 349 20..23 'arr': [f64; _]
348 10..179 '{ ... } }': () 350 36..46 '[0.0, 1.0]': [f64; _]
349 20..23 'arr': [f64; _] 351 37..40 '0.0': f64
350 36..46 '[0.0, 1.0]': [f64; _] 352 42..45 '1.0': f64
351 37..40 '0.0': f64 353 52..177 'match ... }': ()
352 42..45 '1.0': f64 354 58..61 'arr': [f64; _]
353 52..177 'match ... }': () 355 72..80 '[1.0, a]': [f64; _]
354 58..61 'arr': [f64; _] 356 73..76 '1.0': f64
355 72..80 '[1.0, a]': [f64; _] 357 73..76 '1.0': f64
356 73..76 '1.0': f64 358 78..79 'a': f64
357 73..76 '1.0': f64 359 84..110 '{ ... }': ()
358 78..79 'a': f64 360 98..99 'a': f64
359 84..110 '{ ... }': () 361 120..126 '[b, c]': [f64; _]
360 98..99 'a': f64 362 121..122 'b': f64
361 120..126 '[b, c]': [f64; _] 363 124..125 'c': f64
362 121..122 'b': f64 364 130..171 '{ ... }': ()
363 124..125 'c': f64 365 144..145 'b': f64
364 130..171 '{ ... }': () 366 159..160 'c': f64
365 144..145 'b': f64 367 "#]],
366 159..160 'c': f64
367 "###
368 ); 368 );
369} 369}
370 370
371#[test] 371#[test]
372fn infer_adt_pattern() { 372fn infer_adt_pattern() {
373 assert_snapshot!( 373 check_infer(
374 infer(r#" 374 r#"
375enum E { 375 enum E {
376 A { x: usize }, 376 A { x: usize },
377 B 377 B
378} 378 }
379 379
380struct S(u32, E); 380 struct S(u32, E);
381 381
382fn test() { 382 fn test() {
383 let e = E::A { x: 3 }; 383 let e = E::A { x: 3 };
384 384
385 let S(y, z) = foo; 385 let S(y, z) = foo;
386 let E::A { x: new_var } = e; 386 let E::A { x: new_var } = e;
387 387
388 match e { 388 match e {
389 E::A { x } => x, 389 E::A { x } => x,
390 E::B if foo => 1, 390 E::B if foo => 1,
391 E::B => 10, 391 E::B => 10,
392 }; 392 };
393 393
394 let ref d @ E::A { .. } = e; 394 let ref d @ E::A { .. } = e;
395 d; 395 d;
396} 396 }
397"#), 397 "#,
398 @r###" 398 expect![[r#"
399 67..288 '{ ... d; }': () 399 67..288 '{ ... d; }': ()
400 77..78 'e': E 400 77..78 'e': E
401 81..94 'E::A { x: 3 }': E 401 81..94 'E::A { x: 3 }': E
402 91..92 '3': usize 402 91..92 '3': usize
403 105..112 'S(y, z)': S 403 105..112 'S(y, z)': S
404 107..108 'y': u32 404 107..108 'y': u32
405 110..111 'z': E 405 110..111 'z': E
406 115..118 'foo': S 406 115..118 'foo': S
407 128..147 'E::A {..._var }': E 407 128..147 'E::A {..._var }': E
408 138..145 'new_var': usize 408 138..145 'new_var': usize
409 150..151 'e': E 409 150..151 'e': E
410 158..244 'match ... }': usize 410 158..244 'match ... }': usize
411 164..165 'e': E 411 164..165 'e': E
412 176..186 'E::A { x }': E 412 176..186 'E::A { x }': E
413 183..184 'x': usize 413 183..184 'x': usize
414 190..191 'x': usize 414 190..191 'x': usize
415 201..205 'E::B': E 415 201..205 'E::B': E
416 209..212 'foo': bool 416 209..212 'foo': bool
417 216..217 '1': usize 417 216..217 '1': usize
418 227..231 'E::B': E 418 227..231 'E::B': E
419 235..237 '10': usize 419 235..237 '10': usize
420 255..274 'ref d ...{ .. }': &E 420 255..274 'ref d ...{ .. }': &E
421 263..274 'E::A { .. }': E 421 263..274 'E::A { .. }': E
422 277..278 'e': E 422 277..278 'e': E
423 284..285 'd': &E 423 284..285 'd': &E
424 "### 424 "#]],
425 ); 425 );
426} 426}
427 427
428#[test] 428#[test]
429fn enum_variant_through_self_in_pattern() { 429fn enum_variant_through_self_in_pattern() {
430 assert_snapshot!( 430 check_infer(
431 infer(r#" 431 r#"
432enum E { 432 enum E {
433 A { x: usize }, 433 A { x: usize },
434 B(usize), 434 B(usize),
435 C 435 C
436} 436 }
437 437
438impl E { 438 impl E {
439 fn test() { 439 fn test() {
440 match (loop {}) { 440 match (loop {}) {
441 Self::A { x } => { x; }, 441 Self::A { x } => { x; },
442 Self::B(x) => { x; }, 442 Self::B(x) => { x; },
443 Self::C => {}, 443 Self::C => {},
444 }; 444 };
445 } 445 }
446} 446 }
447"#), 447 "#,
448 @r###" 448 expect![[r#"
449 75..217 '{ ... }': () 449 75..217 '{ ... }': ()
450 85..210 'match ... }': () 450 85..210 'match ... }': ()
451 92..99 'loop {}': ! 451 92..99 'loop {}': !
452 97..99 '{}': () 452 97..99 '{}': ()
453 115..128 'Self::A { x }': E 453 115..128 'Self::A { x }': E
454 125..126 'x': usize 454 125..126 'x': usize
455 132..138 '{ x; }': () 455 132..138 '{ x; }': ()
456 134..135 'x': usize 456 134..135 'x': usize
457 152..162 'Self::B(x)': E 457 152..162 'Self::B(x)': E
458 160..161 'x': usize 458 160..161 'x': usize
459 166..172 '{ x; }': () 459 166..172 '{ x; }': ()
460 168..169 'x': usize 460 168..169 'x': usize
461 186..193 'Self::C': E 461 186..193 'Self::C': E
462 197..199 '{}': () 462 197..199 '{}': ()
463 "### 463 "#]],
464 ); 464 );
465} 465}
466 466
467#[test] 467#[test]
468fn infer_generics_in_patterns() { 468fn infer_generics_in_patterns() {
469 assert_snapshot!( 469 check_infer(
470 infer(r#" 470 r#"
471struct A<T> { 471 struct A<T> {
472 x: T, 472 x: T,
473} 473 }
474 474
475enum Option<T> { 475 enum Option<T> {
476 Some(T), 476 Some(T),
477 None, 477 None,
478} 478 }
479 479
480fn test(a1: A<u32>, o: Option<u64>) { 480 fn test(a1: A<u32>, o: Option<u64>) {
481 let A { x: x2 } = a1; 481 let A { x: x2 } = a1;
482 let A::<i64> { x: x3 } = A { x: 1 }; 482 let A::<i64> { x: x3 } = A { x: 1 };
483 match o { 483 match o {
484 Option::Some(t) => t, 484 Option::Some(t) => t,
485 _ => 1, 485 _ => 1,
486 }; 486 };
487} 487 }
488"#), 488 "#,
489 @r###" 489 expect![[r#"
490 78..80 'a1': A<u32> 490 78..80 'a1': A<u32>
491 90..91 'o': Option<u64> 491 90..91 'o': Option<u64>
492 106..243 '{ ... }; }': () 492 106..243 '{ ... }; }': ()
493 116..127 'A { x: x2 }': A<u32> 493 116..127 'A { x: x2 }': A<u32>
494 123..125 'x2': u32 494 123..125 'x2': u32
495 130..132 'a1': A<u32> 495 130..132 'a1': A<u32>
496 142..160 'A::<i6...: x3 }': A<i64> 496 142..160 'A::<i6...: x3 }': A<i64>
497 156..158 'x3': i64 497 156..158 'x3': i64
498 163..173 'A { x: 1 }': A<i64> 498 163..173 'A { x: 1 }': A<i64>
499 170..171 '1': i64 499 170..171 '1': i64
500 179..240 'match ... }': u64 500 179..240 'match ... }': u64
501 185..186 'o': Option<u64> 501 185..186 'o': Option<u64>
502 197..212 'Option::Some(t)': Option<u64> 502 197..212 'Option::Some(t)': Option<u64>
503 210..211 't': u64 503 210..211 't': u64
504 216..217 't': u64 504 216..217 't': u64
505 227..228 '_': Option<u64> 505 227..228 '_': Option<u64>
506 232..233 '1': u64 506 232..233 '1': u64
507 "### 507 "#]],
508 ); 508 );
509} 509}
510 510
511#[test] 511#[test]
512fn infer_const_pattern() { 512fn infer_const_pattern() {
513 assert_snapshot!( 513 check_infer_with_mismatches(
514 infer_with_mismatches(r#" 514 r#"
515enum Option<T> { None } 515 enum Option<T> { None }
516use Option::None; 516 use Option::None;
517struct Foo; 517 struct Foo;
518const Bar: usize = 1; 518 const Bar: usize = 1;
519 519
520fn test() { 520 fn test() {
521 let a: Option<u32> = None; 521 let a: Option<u32> = None;
522 let b: Option<i64> = match a { 522 let b: Option<i64> = match a {
523 None => None, 523 None => None,
524 }; 524 };
525 let _: () = match () { Foo => Foo }; // Expected mismatch 525 let _: () = match () { Foo => Foo }; // Expected mismatch
526 let _: () = match () { Bar => Bar }; // Expected mismatch 526 let _: () = match () { Bar => Bar }; // Expected mismatch
527} 527 }
528"#, true), 528 "#,
529 @r###" 529 expect![[r#"
530 73..74 '1': usize 530 73..74 '1': usize
531 87..309 '{ ...atch }': () 531 87..309 '{ ...atch }': ()
532 97..98 'a': Option<u32> 532 97..98 'a': Option<u32>
533 114..118 'None': Option<u32> 533 114..118 'None': Option<u32>
534 128..129 'b': Option<i64> 534 128..129 'b': Option<i64>
535 145..182 'match ... }': Option<i64> 535 145..182 'match ... }': Option<i64>
536 151..152 'a': Option<u32> 536 151..152 'a': Option<u32>
537 163..167 'None': Option<u32> 537 163..167 'None': Option<u32>
538 171..175 'None': Option<i64> 538 171..175 'None': Option<i64>
539 192..193 '_': () 539 192..193 '_': ()
540 200..223 'match ... Foo }': Foo 540 200..223 'match ... Foo }': Foo
541 206..208 '()': () 541 206..208 '()': ()
542 211..214 'Foo': Foo 542 211..214 'Foo': Foo
543 218..221 'Foo': Foo 543 218..221 'Foo': Foo
544 254..255 '_': () 544 254..255 '_': ()
545 262..285 'match ... Bar }': usize 545 262..285 'match ... Bar }': usize
546 268..270 '()': () 546 268..270 '()': ()
547 273..276 'Bar': usize 547 273..276 'Bar': usize
548 280..283 'Bar': usize 548 280..283 'Bar': usize
549 200..223: expected (), got Foo 549 200..223: expected (), got Foo
550 262..285: expected (), got usize 550 262..285: expected (), got usize
551 "### 551 "#]],
552 ); 552 );
553} 553}
554 554
555#[test] 555#[test]
556fn infer_guard() { 556fn infer_guard() {
557 assert_snapshot!( 557 check_infer(
558 infer(r#" 558 r#"
559struct S; 559struct S;
560impl S { fn foo(&self) -> bool { false } } 560impl S { fn foo(&self) -> bool { false } }
561 561
@@ -564,91 +564,93 @@ fn main() {
564 s if s.foo() => (), 564 s if s.foo() => (),
565 } 565 }
566} 566}
567 "#), @r###" 567 "#,
568 27..31 'self': &S 568 expect![[r#"
569 41..50 '{ false }': bool 569 27..31 'self': &S
570 43..48 'false': bool 570 41..50 '{ false }': bool
571 64..115 '{ ... } }': () 571 43..48 'false': bool
572 70..113 'match ... }': () 572 64..115 '{ ... } }': ()
573 76..77 'S': S 573 70..113 'match ... }': ()
574 88..89 's': S 574 76..77 'S': S
575 93..94 's': S 575 88..89 's': S
576 93..100 's.foo()': bool 576 93..94 's': S
577 104..106 '()': () 577 93..100 's.foo()': bool
578 "###) 578 104..106 '()': ()
579 "#]],
580 )
579} 581}
580 582
581#[test] 583#[test]
582fn match_ergonomics_in_closure_params() { 584fn match_ergonomics_in_closure_params() {
583 assert_snapshot!( 585 check_infer(
584 infer(r#" 586 r#"
585#[lang = "fn_once"] 587 #[lang = "fn_once"]
586trait FnOnce<Args> { 588 trait FnOnce<Args> {
587 type Output; 589 type Output;
588} 590 }
589 591
590fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} } 592 fn foo<T, U, F: FnOnce(T) -> U>(t: T, f: F) -> U { loop {} }
591 593
592fn test() { 594 fn test() {
593 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics 595 foo(&(1, "a"), |&(x, y)| x); // normal, no match ergonomics
594 foo(&(1, "a"), |(x, y)| x); 596 foo(&(1, "a"), |(x, y)| x);
595} 597 }
596"#), 598 "#,
597 @r###" 599 expect![[r#"
598 93..94 't': T 600 93..94 't': T
599 99..100 'f': F 601 99..100 'f': F
600 110..121 '{ loop {} }': U 602 110..121 '{ loop {} }': U
601 112..119 'loop {}': ! 603 112..119 'loop {}': !
602 117..119 '{}': () 604 117..119 '{}': ()
603 133..232 '{ ... x); }': () 605 133..232 '{ ... x); }': ()
604 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32 606 139..142 'foo': fn foo<&(i32, &str), i32, |&(i32, &str)| -> i32>(&(i32, &str), |&(i32, &str)| -> i32) -> i32
605 139..166 'foo(&(...y)| x)': i32 607 139..166 'foo(&(...y)| x)': i32
606 143..152 '&(1, "a")': &(i32, &str) 608 143..152 '&(1, "a")': &(i32, &str)
607 144..152 '(1, "a")': (i32, &str) 609 144..152 '(1, "a")': (i32, &str)
608 145..146 '1': i32 610 145..146 '1': i32
609 148..151 '"a"': &str 611 148..151 '"a"': &str
610 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32 612 154..165 '|&(x, y)| x': |&(i32, &str)| -> i32
611 155..162 '&(x, y)': &(i32, &str) 613 155..162 '&(x, y)': &(i32, &str)
612 156..162 '(x, y)': (i32, &str) 614 156..162 '(x, y)': (i32, &str)
613 157..158 'x': i32 615 157..158 'x': i32
614 160..161 'y': &str 616 160..161 'y': &str
615 164..165 'x': i32 617 164..165 'x': i32
616 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32 618 203..206 'foo': fn foo<&(i32, &str), &i32, |&(i32, &str)| -> &i32>(&(i32, &str), |&(i32, &str)| -> &i32) -> &i32
617 203..229 'foo(&(...y)| x)': &i32 619 203..229 'foo(&(...y)| x)': &i32
618 207..216 '&(1, "a")': &(i32, &str) 620 207..216 '&(1, "a")': &(i32, &str)
619 208..216 '(1, "a")': (i32, &str) 621 208..216 '(1, "a")': (i32, &str)
620 209..210 '1': i32 622 209..210 '1': i32
621 212..215 '"a"': &str 623 212..215 '"a"': &str
622 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32 624 218..228 '|(x, y)| x': |&(i32, &str)| -> &i32
623 219..225 '(x, y)': (i32, &str) 625 219..225 '(x, y)': (i32, &str)
624 220..221 'x': &i32 626 220..221 'x': &i32
625 223..224 'y': &&str 627 223..224 'y': &&str
626 227..228 'x': &i32 628 227..228 'x': &i32
627 "### 629 "#]],
628 ); 630 );
629} 631}
630 632
631#[test] 633#[test]
632fn slice_tail_pattern() { 634fn slice_tail_pattern() {
633 assert_snapshot!( 635 check_infer(
634 infer(r#" 636 r#"
635fn foo(params: &[i32]) { 637 fn foo(params: &[i32]) {
636 match params { 638 match params {
637 [head, tail @ ..] => { 639 [head, tail @ ..] => {
640 }
641 }
638 } 642 }
639 } 643 "#,
640} 644 expect![[r#"
641"#), 645 7..13 'params': &[i32]
642 @r###" 646 23..92 '{ ... } }': ()
643 7..13 'params': &[i32] 647 29..90 'match ... }': ()
644 23..92 '{ ... } }': () 648 35..41 'params': &[i32]
645 29..90 'match ... }': () 649 52..69 '[head,... @ ..]': [i32]
646 35..41 'params': &[i32] 650 53..57 'head': &i32
647 52..69 '[head,... @ ..]': [i32] 651 59..68 'tail @ ..': &[i32]
648 53..57 'head': &i32 652 66..68 '..': [i32]
649 59..68 'tail @ ..': &[i32] 653 73..84 '{ }': ()
650 66..68 '..': [i32] 654 "#]],
651 73..84 '{ }': ()
652 "###
653 ); 655 );
654} 656}
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 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::{check_types, infer}; 4use super::{check_infer, check_types};
5 5
6#[test] 6#[test]
7fn bug_484() { 7fn bug_484() {
8 assert_snapshot!( 8 check_infer(
9 infer(r#" 9 r#"
10fn test() { 10 fn test() {
11 let x = if true {}; 11 let x = if true {};
12} 12 }
13"#), 13 "#,
14 @r###" 14 expect![[r#"
15 10..36 '{ l... {}; }': () 15 10..37 '{ ... {}; }': ()
16 19..20 'x': () 16 20..21 'x': ()
17 23..33 'if true {}': () 17 24..34 'if true {}': ()
18 26..30 'true': bool 18 27..31 'true': bool
19 31..33 '{}': () 19 32..34 '{}': ()
20 "### 20 "#]],
21 ); 21 );
22} 22}
23 23
24#[test] 24#[test]
25fn no_panic_on_field_of_enum() { 25fn no_panic_on_field_of_enum() {
26 assert_snapshot!( 26 check_infer(
27 infer(r#" 27 r#"
28enum X {} 28 enum X {}
29 29
30fn test(x: X) { 30 fn test(x: X) {
31 x.some_field; 31 x.some_field;
32} 32 }
33"#), 33 "#,
34 @r###" 34 expect![[r#"
35 19..20 'x': X 35 19..20 'x': X
36 25..46 '{ ...eld; }': () 36 25..46 '{ ...eld; }': ()
37 31..32 'x': X 37 31..32 'x': X
38 31..43 'x.some_field': {unknown} 38 31..43 'x.some_field': {unknown}
39 "### 39 "#]],
40 ); 40 );
41} 41}
42 42
43#[test] 43#[test]
44fn bug_585() { 44fn bug_585() {
45 assert_snapshot!( 45 check_infer(
46 infer(r#" 46 r#"
47fn test() { 47 fn test() {
48 X {}; 48 X {};
49 match x { 49 match x {
50 A::B {} => (), 50 A::B {} => (),
51 A::Y() => (), 51 A::Y() => (),
52 } 52 }
53} 53 }
54"#), 54 "#,
55 @r###" 55 expect![[r#"
56 10..88 '{ ... } }': () 56 10..88 '{ ... } }': ()
57 16..20 'X {}': {unknown} 57 16..20 'X {}': {unknown}
58 26..86 'match ... }': () 58 26..86 'match ... }': ()
59 32..33 'x': {unknown} 59 32..33 'x': {unknown}
60 44..51 'A::B {}': {unknown} 60 44..51 'A::B {}': {unknown}
61 55..57 '()': () 61 55..57 '()': ()
62 67..73 'A::Y()': {unknown} 62 67..73 'A::Y()': {unknown}
63 77..79 '()': () 63 77..79 '()': ()
64 "### 64 "#]],
65 ); 65 );
66} 66}
67 67
68#[test] 68#[test]
69fn bug_651() { 69fn bug_651() {
70 assert_snapshot!( 70 check_infer(
71 infer(r#" 71 r#"
72fn quux() { 72 fn quux() {
73 let y = 92; 73 let y = 92;
74 1 + y; 74 1 + y;
75} 75 }
76"#), 76 "#,
77 @r###" 77 expect![[r#"
78 10..40 '{ ...+ y; }': () 78 10..40 '{ ...+ y; }': ()
79 20..21 'y': i32 79 20..21 'y': i32
80 24..26 '92': i32 80 24..26 '92': i32
81 32..33 '1': i32 81 32..33 '1': i32
82 32..37 '1 + y': i32 82 32..37 '1 + y': i32
83 36..37 'y': i32 83 36..37 'y': i32
84 "### 84 "#]],
85 ); 85 );
86} 86}
87 87
@@ -89,78 +89,78 @@ fn quux() {
89fn recursive_vars() { 89fn recursive_vars() {
90 mark::check!(type_var_cycles_resolve_completely); 90 mark::check!(type_var_cycles_resolve_completely);
91 mark::check!(type_var_cycles_resolve_as_possible); 91 mark::check!(type_var_cycles_resolve_as_possible);
92 assert_snapshot!( 92 check_infer(
93 infer(r#" 93 r#"
94fn test() { 94 fn test() {
95 let y = unknown; 95 let y = unknown;
96 [y, &y]; 96 [y, &y];
97} 97 }
98"#), 98 "#,
99 @r###" 99 expect![[r#"
100 10..47 '{ ...&y]; }': () 100 10..47 '{ ...&y]; }': ()
101 20..21 'y': &{unknown} 101 20..21 'y': &{unknown}
102 24..31 'unknown': &{unknown} 102 24..31 'unknown': &{unknown}
103 37..44 '[y, &y]': [&&{unknown}; _] 103 37..44 '[y, &y]': [&&{unknown}; _]
104 38..39 'y': &{unknown} 104 38..39 'y': &{unknown}
105 41..43 '&y': &&{unknown} 105 41..43 '&y': &&{unknown}
106 42..43 'y': &{unknown} 106 42..43 'y': &{unknown}
107 "### 107 "#]],
108 ); 108 );
109} 109}
110 110
111#[test] 111#[test]
112fn recursive_vars_2() { 112fn recursive_vars_2() {
113 assert_snapshot!( 113 check_infer(
114 infer(r#" 114 r#"
115fn test() { 115 fn test() {
116 let x = unknown; 116 let x = unknown;
117 let y = unknown; 117 let y = unknown;
118 [(x, y), (&y, &x)]; 118 [(x, y), (&y, &x)];
119} 119 }
120"#), 120 "#,
121 @r###" 121 expect![[r#"
122 10..79 '{ ...x)]; }': () 122 10..79 '{ ...x)]; }': ()
123 20..21 'x': &&{unknown} 123 20..21 'x': &&{unknown}
124 24..31 'unknown': &&{unknown} 124 24..31 'unknown': &&{unknown}
125 41..42 'y': &&{unknown} 125 41..42 'y': &&{unknown}
126 45..52 'unknown': &&{unknown} 126 45..52 'unknown': &&{unknown}
127 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _] 127 58..76 '[(x, y..., &x)]': [(&&&{unknown}, &&&{unknown}); _]
128 59..65 '(x, y)': (&&&{unknown}, &&&{unknown}) 128 59..65 '(x, y)': (&&&{unknown}, &&&{unknown})
129 60..61 'x': &&{unknown} 129 60..61 'x': &&{unknown}
130 63..64 'y': &&{unknown} 130 63..64 'y': &&{unknown}
131 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown}) 131 67..75 '(&y, &x)': (&&&{unknown}, &&&{unknown})
132 68..70 '&y': &&&{unknown} 132 68..70 '&y': &&&{unknown}
133 69..70 'y': &&{unknown} 133 69..70 'y': &&{unknown}
134 72..74 '&x': &&&{unknown} 134 72..74 '&x': &&&{unknown}
135 73..74 'x': &&{unknown} 135 73..74 'x': &&{unknown}
136 "### 136 "#]],
137 ); 137 );
138} 138}
139 139
140#[test] 140#[test]
141fn infer_std_crash_1() { 141fn infer_std_crash_1() {
142 // caused stack overflow, taken from std 142 // caused stack overflow, taken from std
143 assert_snapshot!( 143 check_infer(
144 infer(r#" 144 r#"
145enum Maybe<T> { 145 enum Maybe<T> {
146 Real(T), 146 Real(T),
147 Fake, 147 Fake,
148} 148 }
149 149
150fn write() { 150 fn write() {
151 match something_unknown { 151 match something_unknown {
152 Maybe::Real(ref mut something) => (), 152 Maybe::Real(ref mut something) => (),
153 } 153 }
154} 154 }
155"#), 155 "#,
156 @r###" 156 expect![[r#"
157 53..138 '{ ... } }': () 157 53..138 '{ ... } }': ()
158 59..136 'match ... }': () 158 59..136 'match ... }': ()
159 65..82 'someth...nknown': Maybe<{unknown}> 159 65..82 'someth...nknown': Maybe<{unknown}>
160 93..123 'Maybe:...thing)': Maybe<{unknown}> 160 93..123 'Maybe:...thing)': Maybe<{unknown}>
161 105..122 'ref mu...ething': &mut {unknown} 161 105..122 'ref mu...ething': &mut {unknown}
162 127..129 '()': () 162 127..129 '()': ()
163 "### 163 "#]],
164 ); 164 );
165} 165}
166 166
@@ -168,234 +168,235 @@ fn write() {
168fn infer_std_crash_2() { 168fn infer_std_crash_2() {
169 mark::check!(type_var_resolves_to_int_var); 169 mark::check!(type_var_resolves_to_int_var);
170 // caused "equating two type variables, ...", taken from std 170 // caused "equating two type variables, ...", taken from std
171 assert_snapshot!( 171 check_infer(
172 infer(r#" 172 r#"
173fn test_line_buffer() { 173 fn test_line_buffer() {
174 &[0, b'\n', 1, b'\n']; 174 &[0, b'\n', 1, b'\n'];
175} 175 }
176"#), 176 "#,
177 @r###" 177 expect![[r#"
178 22..52 '{ ...n']; }': () 178 22..52 '{ ...n']; }': ()
179 28..49 '&[0, b...b'\n']': &[u8; _] 179 28..49 '&[0, b...b'\n']': &[u8; _]
180 29..49 '[0, b'...b'\n']': [u8; _] 180 29..49 '[0, b'...b'\n']': [u8; _]
181 30..31 '0': u8 181 30..31 '0': u8
182 33..38 'b'\n'': u8 182 33..38 'b'\n'': u8
183 40..41 '1': u8 183 40..41 '1': u8
184 43..48 'b'\n'': u8 184 43..48 'b'\n'': u8
185 "### 185 "#]],
186 ); 186 );
187} 187}
188 188
189#[test] 189#[test]
190fn infer_std_crash_3() { 190fn infer_std_crash_3() {
191 // taken from rustc 191 // taken from rustc
192 assert_snapshot!( 192 check_infer(
193 infer(r#" 193 r#"
194pub fn compute() { 194 pub fn compute() {
195 match nope!() { 195 match nope!() {
196 SizeSkeleton::Pointer { non_zero: true, tail } => {} 196 SizeSkeleton::Pointer { non_zero: true, tail } => {}
197 } 197 }
198} 198 }
199"#), 199 "#,
200 @r###" 200 expect![[r#"
201 17..107 '{ ... } }': () 201 17..107 '{ ... } }': ()
202 23..105 'match ... }': () 202 23..105 'match ... }': ()
203 29..36 'nope!()': {unknown} 203 29..36 'nope!()': {unknown}
204 47..93 'SizeSk...tail }': {unknown} 204 47..93 'SizeSk...tail }': {unknown}
205 81..85 'true': bool 205 81..85 'true': bool
206 81..85 'true': bool 206 81..85 'true': bool
207 87..91 'tail': {unknown} 207 87..91 'tail': {unknown}
208 97..99 '{}': () 208 97..99 '{}': ()
209 "### 209 "#]],
210 ); 210 );
211} 211}
212 212
213#[test] 213#[test]
214fn infer_std_crash_4() { 214fn infer_std_crash_4() {
215 // taken from rustc 215 // taken from rustc
216 assert_snapshot!( 216 check_infer(
217 infer(r#" 217 r#"
218pub fn primitive_type() { 218 pub fn primitive_type() {
219 match *self { 219 match *self {
220 BorrowedRef { type_: Primitive(p), ..} => {}, 220 BorrowedRef { type_: Primitive(p), ..} => {},
221 } 221 }
222} 222 }
223"#), 223 "#,
224 @r###" 224 expect![[r#"
225 24..105 '{ ... } }': () 225 24..105 '{ ... } }': ()
226 30..103 'match ... }': () 226 30..103 'match ... }': ()
227 36..41 '*self': {unknown} 227 36..41 '*self': {unknown}
228 37..41 'self': {unknown} 228 37..41 'self': {unknown}
229 52..90 'Borrow...), ..}': {unknown} 229 52..90 'Borrow...), ..}': {unknown}
230 73..85 'Primitive(p)': {unknown} 230 73..85 'Primitive(p)': {unknown}
231 83..84 'p': {unknown} 231 83..84 'p': {unknown}
232 94..96 '{}': () 232 94..96 '{}': ()
233 "### 233 "#]],
234 ); 234 );
235} 235}
236 236
237#[test] 237#[test]
238fn infer_std_crash_5() { 238fn infer_std_crash_5() {
239 // taken from rustc 239 // taken from rustc
240 assert_snapshot!( 240 check_infer(
241 infer(r#" 241 r#"
242fn extra_compiler_flags() { 242 fn extra_compiler_flags() {
243 for content in doesnt_matter { 243 for content in doesnt_matter {
244 let name = if doesnt_matter { 244 let name = if doesnt_matter {
245 first 245 first
246 } else { 246 } else {
247 &content 247 &content
248 }; 248 };
249 249
250 let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { 250 let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) {
251 name 251 name
252 } else { 252 } else {
253 content 253 content
254 }; 254 };
255 } 255 }
256} 256 }
257"#), 257 "#,
258 @r###" 258 expect![[r#"
259 26..322 '{ ... } }': () 259 26..322 '{ ... } }': ()
260 32..320 'for co... }': () 260 32..320 'for co... }': ()
261 36..43 'content': &{unknown} 261 36..43 'content': &{unknown}
262 47..60 'doesnt_matter': {unknown} 262 47..60 'doesnt_matter': {unknown}
263 61..320 '{ ... }': () 263 61..320 '{ ... }': ()
264 75..79 'name': &&{unknown} 264 75..79 'name': &&{unknown}
265 82..166 'if doe... }': &&{unknown} 265 82..166 'if doe... }': &&{unknown}
266 85..98 'doesnt_matter': bool 266 85..98 'doesnt_matter': bool
267 99..128 '{ ... }': &&{unknown} 267 99..128 '{ ... }': &&{unknown}
268 113..118 'first': &&{unknown} 268 113..118 'first': &&{unknown}
269 134..166 '{ ... }': &&{unknown} 269 134..166 '{ ... }': &&{unknown}
270 148..156 '&content': &&{unknown} 270 148..156 '&content': &&{unknown}
271 149..156 'content': &{unknown} 271 149..156 'content': &{unknown}
272 181..188 'content': &{unknown} 272 181..188 'content': &{unknown}
273 191..313 'if ICE... }': &{unknown} 273 191..313 'if ICE... }': &{unknown}
274 194..231 'ICE_RE..._VALUE': {unknown} 274 194..231 'ICE_RE..._VALUE': {unknown}
275 194..247 'ICE_RE...&name)': bool 275 194..247 'ICE_RE...&name)': bool
276 241..246 '&name': &&&{unknown} 276 241..246 '&name': &&&{unknown}
277 242..246 'name': &&{unknown} 277 242..246 'name': &&{unknown}
278 248..276 '{ ... }': &&{unknown} 278 248..276 '{ ... }': &&{unknown}
279 262..266 'name': &&{unknown} 279 262..266 'name': &&{unknown}
280 282..313 '{ ... }': &{unknown} 280 282..313 '{ ... }': &{unknown}
281 296..303 'content': &{unknown} 281 296..303 'content': &{unknown}
282 "### 282 "#]],
283 ); 283 );
284} 284}
285 285
286#[test] 286#[test]
287fn infer_nested_generics_crash() { 287fn infer_nested_generics_crash() {
288 // another crash found typechecking rustc 288 // another crash found typechecking rustc
289 assert_snapshot!( 289 check_infer(
290 infer(r#" 290 r#"
291struct Canonical<V> { 291 struct Canonical<V> {
292 value: V, 292 value: V,
293} 293 }
294struct QueryResponse<V> { 294 struct QueryResponse<V> {
295 value: V, 295 value: V,
296} 296 }
297fn test<R>(query_response: Canonical<QueryResponse<R>>) { 297 fn test<R>(query_response: Canonical<QueryResponse<R>>) {
298 &query_response.value; 298 &query_response.value;
299} 299 }
300"#), 300 "#,
301 @r###" 301 expect![[r#"
302 91..105 'query_response': Canonical<QueryResponse<R>> 302 91..105 'query_response': Canonical<QueryResponse<R>>
303 136..166 '{ ...lue; }': () 303 136..166 '{ ...lue; }': ()
304 142..163 '&query....value': &QueryResponse<R> 304 142..163 '&query....value': &QueryResponse<R>
305 143..157 'query_response': Canonical<QueryResponse<R>> 305 143..157 'query_response': Canonical<QueryResponse<R>>
306 143..163 'query_....value': QueryResponse<R> 306 143..163 'query_....value': QueryResponse<R>
307 "### 307 "#]],
308 ); 308 );
309} 309}
310 310
311#[test] 311#[test]
312fn infer_paren_macro_call() { 312fn infer_paren_macro_call() {
313 assert_snapshot!( 313 check_infer(
314 infer(r#" 314 r#"
315macro_rules! bar { () => {0u32} } 315 macro_rules! bar { () => {0u32} }
316fn test() { 316 fn test() {
317 let a = (bar!()); 317 let a = (bar!());
318} 318 }
319"#), 319 "#,
320 @r###" 320 expect![[r#"
321 !0..4 '0u32': u32 321 !0..4 '0u32': u32
322 44..69 '{ ...()); }': () 322 44..69 '{ ...()); }': ()
323 54..55 'a': u32 323 54..55 'a': u32
324 "### 324 "#]],
325 ); 325 );
326} 326}
327 327
328#[test] 328#[test]
329fn bug_1030() { 329fn bug_1030() {
330 assert_snapshot!(infer(r#" 330 check_infer(
331struct HashSet<T, H>; 331 r#"
332struct FxHasher; 332 struct HashSet<T, H>;
333type FxHashSet<T> = HashSet<T, FxHasher>; 333 struct FxHasher;
334 type FxHashSet<T> = HashSet<T, FxHasher>;
334 335
335impl<T, H> HashSet<T, H> { 336 impl<T, H> HashSet<T, H> {
336 fn default() -> HashSet<T, H> {} 337 fn default() -> HashSet<T, H> {}
337} 338 }
338 339
339pub fn main_loop() { 340 pub fn main_loop() {
340 FxHashSet::default(); 341 FxHashSet::default();
341} 342 }
342"#), 343 "#,
343 @r###" 344 expect![[r#"
344 143..145 '{}': () 345 143..145 '{}': ()
345 168..197 '{ ...t(); }': () 346 168..197 '{ ...t(); }': ()
346 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher> 347 174..192 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<{unknown}, FxHasher>
347 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher> 348 174..194 'FxHash...ault()': HashSet<{unknown}, FxHasher>
348 "### 349 "#]],
349 ); 350 );
350} 351}
351 352
352#[test] 353#[test]
353fn issue_2669() { 354fn issue_2669() {
354 assert_snapshot!( 355 check_infer(
355 infer( 356 r#"
356 r#"trait A {} 357 trait A {}
357 trait Write {} 358 trait Write {}
358 struct Response<T> {} 359 struct Response<T> {}
359 360
360 trait D { 361 trait D {
361 fn foo(); 362 fn foo();
362 } 363 }
363 364
364 impl<T:A> D for Response<T> { 365 impl<T:A> D for Response<T> {
365 fn foo() { 366 fn foo() {
366 end(); 367 end();
367 fn end<W: Write>() { 368 fn end<W: Write>() {
368 let _x: T = loop {}; 369 let _x: T = loop {};
370 }
369 } 371 }
370 } 372 }
371 }"# 373 "#,
372 ), 374 expect![[r#"
373 @r###" 375 119..214 '{ ... }': ()
374 147..262 '{ ... }': () 376 129..132 'end': fn end<{unknown}>()
375 161..164 'end': fn end<{unknown}>() 377 129..134 'end()': ()
376 161..166 'end()': () 378 163..208 '{ ... }': ()
377 199..252 '{ ... }': () 379 181..183 '_x': !
378 221..223 '_x': ! 380 190..197 'loop {}': !
379 230..237 'loop {}': ! 381 195..197 '{}': ()
380 235..237 '{}': () 382 "#]],
381 "###
382 ) 383 )
383} 384}
384 385
385#[test] 386#[test]
386fn issue_2705() { 387fn issue_2705() {
387 assert_snapshot!( 388 check_infer(
388 infer(r#" 389 r#"
389trait Trait {} 390 trait Trait {}
390fn test() { 391 fn test() {
391 <Trait<u32>>::foo() 392 <Trait<u32>>::foo()
392} 393 }
393"#), 394 "#,
394 @r###" 395 expect![[r#"
395 25..52 '{ ...oo() }': () 396 25..52 '{ ...oo() }': ()
396 31..48 '<Trait...>::foo': {unknown} 397 31..48 '<Trait...>::foo': {unknown}
397 31..50 '<Trait...:foo()': () 398 31..50 '<Trait...:foo()': ()
398 "### 399 "#]],
399 ); 400 );
400} 401}
401 402
@@ -479,25 +480,25 @@ fn main() {
479 480
480#[test] 481#[test]
481fn issue_3999_slice() { 482fn issue_3999_slice() {
482 assert_snapshot!( 483 check_infer(
483 infer(r#" 484 r#"
484fn foo(params: &[usize]) { 485 fn foo(params: &[usize]) {
485 match params { 486 match params {
486 [ps @ .., _] => {} 487 [ps @ .., _] => {}
487 } 488 }
488} 489 }
489"#), 490 "#,
490 @r###" 491 expect![[r#"
491 7..13 'params': &[usize] 492 7..13 'params': &[usize]
492 25..80 '{ ... } }': () 493 25..80 '{ ... } }': ()
493 31..78 'match ... }': () 494 31..78 'match ... }': ()
494 37..43 'params': &[usize] 495 37..43 'params': &[usize]
495 54..66 '[ps @ .., _]': [usize] 496 54..66 '[ps @ .., _]': [usize]
496 55..62 'ps @ ..': &[usize] 497 55..62 'ps @ ..': &[usize]
497 60..62 '..': [usize] 498 60..62 '..': [usize]
498 64..65 '_': usize 499 64..65 '_': usize
499 70..72 '{}': () 500 70..72 '{}': ()
500 "### 501 "#]],
501 ); 502 );
502} 503}
503 504
@@ -505,334 +506,337 @@ fn foo(params: &[usize]) {
505fn issue_3999_struct() { 506fn issue_3999_struct() {
506 // rust-analyzer should not panic on seeing this malformed 507 // rust-analyzer should not panic on seeing this malformed
507 // record pattern. 508 // record pattern.
508 assert_snapshot!( 509 check_infer(
509 infer(r#" 510 r#"
510struct Bar { 511 struct Bar {
511 a: bool, 512 a: bool,
512} 513 }
513fn foo(b: Bar) { 514 fn foo(b: Bar) {
514 match b { 515 match b {
515 Bar { a: .. } => {}, 516 Bar { a: .. } => {},
516 } 517 }
517} 518 }
518"#), 519 "#,
519 @r###" 520 expect![[r#"
520 35..36 'b': Bar 521 35..36 'b': Bar
521 43..95 '{ ... } }': () 522 43..95 '{ ... } }': ()
522 49..93 'match ... }': () 523 49..93 'match ... }': ()
523 55..56 'b': Bar 524 55..56 'b': Bar
524 67..80 'Bar { a: .. }': Bar 525 67..80 'Bar { a: .. }': Bar
525 76..78 '..': bool 526 76..78 '..': bool
526 84..86 '{}': () 527 84..86 '{}': ()
527 "### 528 "#]],
528 ); 529 );
529} 530}
530 531
531#[test] 532#[test]
532fn issue_4235_name_conflicts() { 533fn issue_4235_name_conflicts() {
533 assert_snapshot!( 534 check_infer(
534 infer(r#" 535 r#"
535struct FOO {} 536 struct FOO {}
536static FOO:FOO = FOO {}; 537 static FOO:FOO = FOO {};
537 538
538impl FOO { 539 impl FOO {
539 fn foo(&self) {} 540 fn foo(&self) {}
540} 541 }
541 542
542fn main() { 543 fn main() {
543 let a = &FOO; 544 let a = &FOO;
544 a.foo(); 545 a.foo();
545} 546 }
546"#), @r###" 547 "#,
547 31..37 'FOO {}': FOO 548 expect![[r#"
548 63..67 'self': &FOO 549 31..37 'FOO {}': FOO
549 69..71 '{}': () 550 63..67 'self': &FOO
550 85..119 '{ ...o(); }': () 551 69..71 '{}': ()
551 95..96 'a': &FOO 552 85..119 '{ ...o(); }': ()
552 99..103 '&FOO': &FOO 553 95..96 'a': &FOO
553 100..103 'FOO': FOO 554 99..103 '&FOO': &FOO
554 109..110 'a': &FOO 555 100..103 'FOO': FOO
555 109..116 'a.foo()': () 556 109..110 'a': &FOO
556 "### 557 109..116 'a.foo()': ()
558 "#]],
557 ); 559 );
558} 560}
559 561
560#[test] 562#[test]
561fn issue_4465_dollar_crate_at_type() { 563fn issue_4465_dollar_crate_at_type() {
562 assert_snapshot!( 564 check_infer(
563 infer(r#" 565 r#"
564pub struct Foo {} 566 pub struct Foo {}
565pub fn anything<T>() -> T { 567 pub fn anything<T>() -> T {
566 loop {} 568 loop {}
567} 569 }
568macro_rules! foo { 570 macro_rules! foo {
569 () => {{ 571 () => {{
570 let r: $crate::Foo = anything(); 572 let r: $crate::Foo = anything();
571 r 573 r
572 }}; 574 }};
573} 575 }
574fn main() { 576 fn main() {
575 let _a = foo!(); 577 let _a = foo!();
576} 578 }
577"#), @r###" 579 "#,
578 44..59 '{ loop {} }': T 580 expect![[r#"
579 50..57 'loop {}': ! 581 44..59 '{ loop {} }': T
580 55..57 '{}': () 582 50..57 'loop {}': !
581 !0..31 '{letr:...g();r}': Foo 583 55..57 '{}': ()
582 !4..5 'r': Foo 584 !0..31 '{letr:...g();r}': Foo
583 !18..26 'anything': fn anything<Foo>() -> Foo 585 !4..5 'r': Foo
584 !18..28 'anything()': Foo 586 !18..26 'anything': fn anything<Foo>() -> Foo
585 !29..30 'r': Foo 587 !18..28 'anything()': Foo
586 163..187 '{ ...!(); }': () 588 !29..30 'r': Foo
587 173..175 '_a': Foo 589 163..187 '{ ...!(); }': ()
588 "###); 590 173..175 '_a': Foo
591 "#]],
592 );
589} 593}
590 594
591#[test] 595#[test]
592fn issue_4053_diesel_where_clauses() { 596fn issue_4053_diesel_where_clauses() {
593 assert_snapshot!( 597 check_infer(
594 infer(r#" 598 r#"
595trait BoxedDsl<DB> { 599 trait BoxedDsl<DB> {
596 type Output; 600 type Output;
597 fn internal_into_boxed(self) -> Self::Output; 601 fn internal_into_boxed(self) -> Self::Output;
598} 602 }
599 603
600struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> { 604 struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> {
601 order: Order, 605 order: Order,
602} 606 }
603 607
604trait QueryFragment<DB: Backend> {} 608 trait QueryFragment<DB: Backend> {}
605 609
606trait Into<T> { fn into(self) -> T; } 610 trait Into<T> { fn into(self) -> T; }
607 611
608impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB> 612 impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB>
609 for SelectStatement<F, S, D, W, O, LOf, G> 613 for SelectStatement<F, S, D, W, O, LOf, G>
610where 614 where
611 O: Into<dyn QueryFragment<DB>>, 615 O: Into<dyn QueryFragment<DB>>,
612{ 616 {
613 type Output = XXX; 617 type Output = XXX;
614 618
615 fn internal_into_boxed(self) -> Self::Output { 619 fn internal_into_boxed(self) -> Self::Output {
616 self.order.into(); 620 self.order.into();
617 } 621 }
618} 622 }
619"#), 623 "#,
620 @r###" 624 expect![[r#"
621 65..69 'self': Self 625 65..69 'self': Self
622 267..271 'self': Self 626 267..271 'self': Self
623 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> 627 466..470 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
624 488..522 '{ ... }': () 628 488..522 '{ ... }': ()
625 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> 629 498..502 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}>
626 498..508 'self.order': O 630 498..508 'self.order': O
627 498..515 'self.o...into()': dyn QueryFragment<DB> 631 498..515 'self.o...into()': dyn QueryFragment<DB>
628 "### 632 "#]],
629 ); 633 );
630} 634}
631 635
632#[test] 636#[test]
633fn issue_4953() { 637fn issue_4953() {
634 assert_snapshot!( 638 check_infer(
635 infer(r#" 639 r#"
636pub struct Foo(pub i64); 640 pub struct Foo(pub i64);
637impl Foo { 641 impl Foo {
638 fn test() -> Self { Self(0i64) } 642 fn test() -> Self { Self(0i64) }
639} 643 }
640"#), 644 "#,
641 @r###" 645 expect![[r#"
642 58..72 '{ Self(0i64) }': Foo 646 58..72 '{ Self(0i64) }': Foo
643 60..64 'Self': Foo(i64) -> Foo 647 60..64 'Self': Foo(i64) -> Foo
644 60..70 'Self(0i64)': Foo 648 60..70 'Self(0i64)': Foo
645 65..69 '0i64': i64 649 65..69 '0i64': i64
646 "### 650 "#]],
647 ); 651 );
648 assert_snapshot!( 652 check_infer(
649 infer(r#" 653 r#"
650pub struct Foo<T>(pub T); 654 pub struct Foo<T>(pub T);
651impl Foo<i64> { 655 impl Foo<i64> {
652 fn test() -> Self { Self(0i64) } 656 fn test() -> Self { Self(0i64) }
653} 657 }
654"#), 658 "#,
655 @r###" 659 expect![[r#"
656 64..78 '{ Self(0i64) }': Foo<i64> 660 64..78 '{ Self(0i64) }': Foo<i64>
657 66..70 'Self': Foo<i64>(i64) -> Foo<i64> 661 66..70 'Self': Foo<i64>(i64) -> Foo<i64>
658 66..76 'Self(0i64)': Foo<i64> 662 66..76 'Self(0i64)': Foo<i64>
659 71..75 '0i64': i64 663 71..75 '0i64': i64
660 "### 664 "#]],
661 ); 665 );
662} 666}
663 667
664#[test] 668#[test]
665fn issue_4931() { 669fn issue_4931() {
666 assert_snapshot!( 670 check_infer(
667 infer(r#" 671 r#"
668trait Div<T> { 672 trait Div<T> {
669 type Output; 673 type Output;
670} 674 }
671 675
672trait CheckedDiv: Div<()> {} 676 trait CheckedDiv: Div<()> {}
673 677
674trait PrimInt: CheckedDiv<Output = ()> { 678 trait PrimInt: CheckedDiv<Output = ()> {
675 fn pow(self); 679 fn pow(self);
676} 680 }
677 681
678fn check<T: PrimInt>(i: T) { 682 fn check<T: PrimInt>(i: T) {
679 i.pow(); 683 i.pow();
680} 684 }
681"#), 685 "#,
682 @r###" 686 expect![[r#"
683 117..121 'self': Self 687 117..121 'self': Self
684 148..149 'i': T 688 148..149 'i': T
685 154..170 '{ ...w(); }': () 689 154..170 '{ ...w(); }': ()
686 160..161 'i': T 690 160..161 'i': T
687 160..167 'i.pow()': () 691 160..167 'i.pow()': ()
688 "### 692 "#]],
689 ); 693 );
690} 694}
691 695
692#[test] 696#[test]
693fn issue_4885() { 697fn issue_4885() {
694 assert_snapshot!( 698 check_infer(
695 infer(r#" 699 r#"
696#[lang = "coerce_unsized"] 700 #[lang = "coerce_unsized"]
697pub trait CoerceUnsized<T> {} 701 pub trait CoerceUnsized<T> {}
698 702
699trait Future { 703 trait Future {
700 type Output; 704 type Output;
701} 705 }
702trait Foo<R> { 706 trait Foo<R> {
703 type Bar; 707 type Bar;
704} 708 }
705fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> 709 fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
706where 710 where
707 K: Foo<R>, 711 K: Foo<R>,
708{ 712 {
709 bar(key) 713 bar(key)
710} 714 }
711fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> 715 fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
712where 716 where
713 K: Foo<R>, 717 K: Foo<R>,
714{ 718 {
715} 719 }
716"#), 720 "#,
717 @r###" 721 expect![[r#"
718 136..139 'key': &K 722 136..139 'key': &K
719 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar> 723 198..214 '{ ...key) }': impl Future<Output = <K as Foo<R>>::Bar>
720 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar> 724 204..207 'bar': fn bar<R, K>(&K) -> impl Future<Output = <K as Foo<R>>::Bar>
721 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar> 725 204..212 'bar(key)': impl Future<Output = <K as Foo<R>>::Bar>
722 208..211 'key': &K 726 208..211 'key': &K
723 228..231 'key': &K 727 228..231 'key': &K
724 290..293 '{ }': () 728 290..293 '{ }': ()
725 "### 729 "#]],
726 ); 730 );
727} 731}
728 732
729#[test] 733#[test]
730fn issue_4800() { 734fn issue_4800() {
731 assert_snapshot!( 735 check_infer(
732 infer(r#" 736 r#"
733trait Debug {} 737 trait Debug {}
734 738
735struct Foo<T>; 739 struct Foo<T>;
736 740
737type E1<T> = (T, T, T); 741 type E1<T> = (T, T, T);
738type E2<T> = E1<E1<E1<(T, T, T)>>>; 742 type E2<T> = E1<E1<E1<(T, T, T)>>>;
739 743
740impl Debug for Foo<E2<()>> {} 744 impl Debug for Foo<E2<()>> {}
741 745
742struct Request; 746 struct Request;
743 747
744pub trait Future { 748 pub trait Future {
745 type Output; 749 type Output;
746} 750 }
747 751
748pub struct PeerSet<D>; 752 pub struct PeerSet<D>;
749 753
750impl<D> Service<Request> for PeerSet<D> 754 impl<D> Service<Request> for PeerSet<D>
751where 755 where
752 D: Discover, 756 D: Discover,
753 D::Key: Debug, 757 D::Key: Debug,
754{ 758 {
755 type Error = (); 759 type Error = ();
756 type Future = dyn Future<Output = Self::Error>; 760 type Future = dyn Future<Output = Self::Error>;
757 761
758 fn call(&mut self) -> Self::Future { 762 fn call(&mut self) -> Self::Future {
759 loop {} 763 loop {}
760 } 764 }
761} 765 }
762 766
763pub trait Discover { 767 pub trait Discover {
764 type Key; 768 type Key;
765} 769 }
766 770
767pub trait Service<Request> { 771 pub trait Service<Request> {
768 type Error; 772 type Error;
769 type Future: Future<Output = Self::Error>; 773 type Future: Future<Output = Self::Error>;
770 fn call(&mut self) -> Self::Future; 774 fn call(&mut self) -> Self::Future;
771} 775 }
772"#), 776 "#,
773 @r###" 777 expect![[r#"
774 379..383 'self': &mut PeerSet<D> 778 379..383 'self': &mut PeerSet<D>
775 401..424 '{ ... }': dyn Future<Output = ()> 779 401..424 '{ ... }': dyn Future<Output = ()>
776 411..418 'loop {}': ! 780 411..418 'loop {}': !
777 416..418 '{}': () 781 416..418 '{}': ()
778 575..579 'self': &mut Self 782 575..579 'self': &mut Self
779 "### 783 "#]],
780 ); 784 );
781} 785}
782 786
783#[test] 787#[test]
784fn issue_4966() { 788fn issue_4966() {
785 assert_snapshot!( 789 check_infer(
786 infer(r#" 790 r#"
787pub trait IntoIterator { 791 pub trait IntoIterator {
788 type Item; 792 type Item;
789} 793 }
790 794
791struct Repeat<A> { element: A } 795 struct Repeat<A> { element: A }
792 796
793struct Map<F> { f: F } 797 struct Map<F> { f: F }
794 798
795struct Vec<T> {} 799 struct Vec<T> {}
796 800
797#[lang = "deref"] 801 #[lang = "deref"]
798pub trait Deref { 802 pub trait Deref {
799 type Target; 803 type Target;
800} 804 }
801 805
802impl<T> Deref for Vec<T> { 806 impl<T> Deref for Vec<T> {
803 type Target = [T]; 807 type Target = [T];
804} 808 }
805 809
806fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {} 810 fn from_iter<A, T: IntoIterator<Item = A>>(iter: T) -> Vec<A> {}
807 811
808fn main() { 812 fn main() {
809 let inner = Map { f: |_: &f64| 0.0 }; 813 let inner = Map { f: |_: &f64| 0.0 };
810 814
811 let repeat = Repeat { element: inner }; 815 let repeat = Repeat { element: inner };
812 816
813 let vec = from_iter(repeat); 817 let vec = from_iter(repeat);
814 818
815 vec.foo_bar(); 819 vec.foo_bar();
816} 820 }
817"#), 821 "#,
818 @r###" 822 expect![[r#"
819 270..274 'iter': T 823 270..274 'iter': T
820 289..291 '{}': () 824 289..291 '{}': ()
821 303..447 '{ ...r(); }': () 825 303..447 '{ ...r(); }': ()
822 313..318 'inner': Map<|&f64| -> f64> 826 313..318 'inner': Map<|&f64| -> f64>
823 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64> 827 321..345 'Map { ... 0.0 }': Map<|&f64| -> f64>
824 330..343 '|_: &f64| 0.0': |&f64| -> f64 828 330..343 '|_: &f64| 0.0': |&f64| -> f64
825 331..332 '_': &f64 829 331..332 '_': &f64
826 340..343 '0.0': f64 830 340..343 '0.0': f64
827 356..362 'repeat': Repeat<Map<|&f64| -> f64>> 831 356..362 'repeat': Repeat<Map<|&f64| -> f64>>
828 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> 832 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>>
829 383..388 'inner': Map<|&f64| -> f64> 833 383..388 'inner': Map<|&f64| -> f64>
830 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 834 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
831 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 835 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
832 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 836 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
833 417..423 'repeat': Repeat<Map<|&f64| -> f64>> 837 417..423 'repeat': Repeat<Map<|&f64| -> f64>>
834 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> 838 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>>
835 431..444 'vec.foo_bar()': {unknown} 839 431..444 'vec.foo_bar()': {unknown}
836 "### 840 "#]],
837 ); 841 );
838} 842}
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 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer}; 3use super::{check_infer, check_types};
4 4
5#[test] 5#[test]
6fn infer_box() { 6fn infer_box() {
@@ -45,43 +45,44 @@ fn test() {
45 45
46#[test] 46#[test]
47fn self_in_struct_lit() { 47fn self_in_struct_lit() {
48 assert_snapshot!(infer( 48 check_infer(
49 r#" 49 r#"
50//- /main.rs 50 //- /main.rs
51struct S<T> { x: T } 51 struct S<T> { x: T }
52 52
53impl S<u32> { 53 impl S<u32> {
54 fn foo() { 54 fn foo() {
55 Self { x: 1 }; 55 Self { x: 1 };
56 } 56 }
57} 57 }
58"#, 58 "#,
59 ), @r###" 59 expect![[r#"
60 49..79 '{ ... }': () 60 49..79 '{ ... }': ()
61 59..72 'Self { x: 1 }': S<u32> 61 59..72 'Self { x: 1 }': S<u32>
62 69..70 '1': u32 62 69..70 '1': u32
63 "###); 63 "#]],
64 );
64} 65}
65 66
66#[test] 67#[test]
67fn type_alias_in_struct_lit() { 68fn type_alias_in_struct_lit() {
68 assert_snapshot!(infer( 69 check_infer(
69 r#" 70 r#"
70//- /main.rs 71 //- /main.rs
71struct S<T> { x: T } 72 struct S<T> { x: T }
72 73
73type SS = S<u32>; 74 type SS = S<u32>;
74 75
75fn foo() { 76 fn foo() {
76 SS { x: 1 }; 77 SS { x: 1 };
77} 78 }
78 79 "#,
79"#, 80 expect![[r#"
80 ), @r###" 81 50..70 '{ ...1 }; }': ()
81 50..70 '{ ...1 }; }': () 82 56..67 'SS { x: 1 }': S<u32>
82 56..67 'SS { x: 1 }': S<u32> 83 64..65 '1': u32
83 64..65 '1': u32 84 "#]],
84 "###); 85 );
85} 86}
86 87
87#[test] 88#[test]
@@ -148,1549 +149,1549 @@ fn test() {
148 149
149#[test] 150#[test]
150fn infer_basics() { 151fn infer_basics() {
151 assert_snapshot!( 152 check_infer(
152 infer(r#" 153 r#"
153fn test(a: u32, b: isize, c: !, d: &str) { 154 fn test(a: u32, b: isize, c: !, d: &str) {
154 a; 155 a;
155 b; 156 b;
156 c; 157 c;
157 d; 158 d;
158 1usize; 159 1usize;
159 1isize; 160 1isize;
160 "test"; 161 "test";
161 1.0f32; 162 1.0f32;
162}"#), 163 }"#,
163 @r###" 164 expect![[r#"
164 8..9 'a': u32 165 8..9 'a': u32
165 16..17 'b': isize 166 16..17 'b': isize
166 26..27 'c': ! 167 26..27 'c': !
167 32..33 'd': &str 168 32..33 'd': &str
168 41..120 '{ ...f32; }': () 169 41..120 '{ ...f32; }': ()
169 47..48 'a': u32 170 47..48 'a': u32
170 54..55 'b': isize 171 54..55 'b': isize
171 61..62 'c': ! 172 61..62 'c': !
172 68..69 'd': &str 173 68..69 'd': &str
173 75..81 '1usize': usize 174 75..81 '1usize': usize
174 87..93 '1isize': isize 175 87..93 '1isize': isize
175 99..105 '"test"': &str 176 99..105 '"test"': &str
176 111..117 '1.0f32': f32 177 111..117 '1.0f32': f32
177 "### 178 "#]],
178 ); 179 );
179} 180}
180 181
181#[test] 182#[test]
182fn infer_let() { 183fn infer_let() {
183 assert_snapshot!( 184 check_infer(
184 infer(r#" 185 r#"
185fn test() { 186 fn test() {
186 let a = 1isize; 187 let a = 1isize;
187 let b: usize = 1; 188 let b: usize = 1;
188 let c = b; 189 let c = b;
189 let d: u32; 190 let d: u32;
190 let e; 191 let e;
191 let f: i32 = e; 192 let f: i32 = e;
192} 193 }
193"#), 194 "#,
194 @r###" 195 expect![[r#"
195 10..117 '{ ...= e; }': () 196 10..117 '{ ...= e; }': ()
196 20..21 'a': isize 197 20..21 'a': isize
197 24..30 '1isize': isize 198 24..30 '1isize': isize
198 40..41 'b': usize 199 40..41 'b': usize
199 51..52 '1': usize 200 51..52 '1': usize
200 62..63 'c': usize 201 62..63 'c': usize
201 66..67 'b': usize 202 66..67 'b': usize
202 77..78 'd': u32 203 77..78 'd': u32
203 93..94 'e': i32 204 93..94 'e': i32
204 104..105 'f': i32 205 104..105 'f': i32
205 113..114 'e': i32 206 113..114 'e': i32
206 "### 207 "#]],
207 ); 208 );
208} 209}
209 210
210#[test] 211#[test]
211fn infer_paths() { 212fn infer_paths() {
212 assert_snapshot!( 213 check_infer(
213 infer(r#" 214 r#"
214fn a() -> u32 { 1 } 215 fn a() -> u32 { 1 }
215 216
216mod b { 217 mod b {
217 fn c() -> u32 { 1 } 218 fn c() -> u32 { 1 }
218} 219 }
219 220
220fn test() { 221 fn test() {
221 a(); 222 a();
222 b::c(); 223 b::c();
223} 224 }
224"#), 225 "#,
225 @r###" 226 expect![[r#"
226 14..19 '{ 1 }': u32 227 14..19 '{ 1 }': u32
227 16..17 '1': u32 228 16..17 '1': u32
228 47..52 '{ 1 }': u32 229 47..52 '{ 1 }': u32
229 49..50 '1': u32 230 49..50 '1': u32
230 66..90 '{ ...c(); }': () 231 66..90 '{ ...c(); }': ()
231 72..73 'a': fn a() -> u32 232 72..73 'a': fn a() -> u32
232 72..75 'a()': u32 233 72..75 'a()': u32
233 81..85 'b::c': fn c() -> u32 234 81..85 'b::c': fn c() -> u32
234 81..87 'b::c()': u32 235 81..87 'b::c()': u32
235 "### 236 "#]],
236 ); 237 );
237} 238}
238 239
239#[test] 240#[test]
240fn infer_path_type() { 241fn infer_path_type() {
241 assert_snapshot!( 242 check_infer(
242 infer(r#" 243 r#"
243struct S; 244 struct S;
244 245
245impl S { 246 impl S {
246 fn foo() -> i32 { 1 } 247 fn foo() -> i32 { 1 }
247} 248 }
248 249
249fn test() { 250 fn test() {
250 S::foo(); 251 S::foo();
251 <S>::foo(); 252 <S>::foo();
252} 253 }
253"#), 254 "#,
254 @r###" 255 expect![[r#"
255 40..45 '{ 1 }': i32 256 40..45 '{ 1 }': i32
256 42..43 '1': i32 257 42..43 '1': i32
257 59..92 '{ ...o(); }': () 258 59..92 '{ ...o(); }': ()
258 65..71 'S::foo': fn foo() -> i32 259 65..71 'S::foo': fn foo() -> i32
259 65..73 'S::foo()': i32 260 65..73 'S::foo()': i32
260 79..87 '<S>::foo': fn foo() -> i32 261 79..87 '<S>::foo': fn foo() -> i32
261 79..89 '<S>::foo()': i32 262 79..89 '<S>::foo()': i32
262 "### 263 "#]],
263 ); 264 );
264} 265}
265 266
266#[test] 267#[test]
267fn infer_struct() { 268fn infer_struct() {
268 assert_snapshot!( 269 check_infer(
269 infer(r#" 270 r#"
270struct A { 271 struct A {
271 b: B, 272 b: B,
272 c: C, 273 c: C,
273} 274 }
274struct B; 275 struct B;
275struct C(usize); 276 struct C(usize);
276 277
277fn test() { 278 fn test() {
278 let c = C(1); 279 let c = C(1);
279 B; 280 B;
280 let a: A = A { b: B, c: C(1) }; 281 let a: A = A { b: B, c: C(1) };
281 a.b; 282 a.b;
282 a.c; 283 a.c;
283} 284 }
284"#), 285 "#,
285 @r###" 286 expect![[r#"
286 71..153 '{ ...a.c; }': () 287 71..153 '{ ...a.c; }': ()
287 81..82 'c': C 288 81..82 'c': C
288 85..86 'C': C(usize) -> C 289 85..86 'C': C(usize) -> C
289 85..89 'C(1)': C 290 85..89 'C(1)': C
290 87..88 '1': usize 291 87..88 '1': usize
291 95..96 'B': B 292 95..96 'B': B
292 106..107 'a': A 293 106..107 'a': A
293 113..132 'A { b:...C(1) }': A 294 113..132 'A { b:...C(1) }': A
294 120..121 'B': B 295 120..121 'B': B
295 126..127 'C': C(usize) -> C 296 126..127 'C': C(usize) -> C
296 126..130 'C(1)': C 297 126..130 'C(1)': C
297 128..129 '1': usize 298 128..129 '1': usize
298 138..139 'a': A 299 138..139 'a': A
299 138..141 'a.b': B 300 138..141 'a.b': B
300 147..148 'a': A 301 147..148 'a': A
301 147..150 'a.c': C 302 147..150 'a.c': C
302 "### 303 "#]],
303 ); 304 );
304} 305}
305 306
306#[test] 307#[test]
307fn infer_enum() { 308fn infer_enum() {
308 assert_snapshot!( 309 check_infer(
309 infer(r#" 310 r#"
310enum E { 311 enum E {
311 V1 { field: u32 }, 312 V1 { field: u32 },
312 V2 313 V2
313} 314 }
314fn test() { 315 fn test() {
315 E::V1 { field: 1 }; 316 E::V1 { field: 1 };
316 E::V2; 317 E::V2;
317}"#), 318 }"#,
318 @r###" 319 expect![[r#"
319 47..81 '{ E:...:V2; }': () 320 51..89 '{ ...:V2; }': ()
320 51..69 'E::V1 ...d: 1 }': E 321 57..75 'E::V1 ...d: 1 }': E
321 66..67 '1': u32 322 72..73 '1': u32
322 73..78 'E::V2': E 323 81..86 'E::V2': E
323 "### 324 "#]],
324 ); 325 );
325} 326}
326 327
327#[test] 328#[test]
328fn infer_union() { 329fn infer_union() {
329 assert_snapshot!( 330 check_infer(
330 infer(r#" 331 r#"
331union MyUnion { 332 union MyUnion {
332 foo: u32, 333 foo: u32,
333 bar: f32, 334 bar: f32,
334} 335 }
335 336
336unsafe fn baz(u: MyUnion) { 337 unsafe fn baz(u: MyUnion) {
337 let inner = u.foo; 338 let inner = u.foo;
338} 339 }
339"#), 340 "#,
340 @r###" 341 expect![[r#"
341 61..62 'u': MyUnion 342 61..62 'u': MyUnion
342 73..99 '{ ...foo; }': () 343 73..99 '{ ...foo; }': ()
343 83..88 'inner': u32 344 83..88 'inner': u32
344 91..92 'u': MyUnion 345 91..92 'u': MyUnion
345 91..96 'u.foo': u32 346 91..96 'u.foo': u32
346 "### 347 "#]],
347 ); 348 );
348} 349}
349 350
350#[test] 351#[test]
351fn infer_refs() { 352fn infer_refs() {
352 assert_snapshot!( 353 check_infer(
353 infer(r#" 354 r#"
354fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { 355 fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
355 a; 356 a;
356 *a; 357 *a;
357 &a; 358 &a;
358 &mut a; 359 &mut a;
359 b; 360 b;
360 *b; 361 *b;
361 &b; 362 &b;
362 c; 363 c;
363 *c; 364 *c;
364 d; 365 d;
365 *d; 366 *d;
366} 367 }
367"#), 368 "#,
368 @r###" 369 expect![[r#"
369 8..9 'a': &u32 370 8..9 'a': &u32
370 17..18 'b': &mut u32 371 17..18 'b': &mut u32
371 30..31 'c': *const u32 372 30..31 'c': *const u32
372 45..46 'd': *mut u32 373 45..46 'd': *mut u32
373 58..149 '{ ... *d; }': () 374 58..149 '{ ... *d; }': ()
374 64..65 'a': &u32 375 64..65 'a': &u32
375 71..73 '*a': u32 376 71..73 '*a': u32
376 72..73 'a': &u32 377 72..73 'a': &u32
377 79..81 '&a': &&u32 378 79..81 '&a': &&u32
378 80..81 'a': &u32 379 80..81 'a': &u32
379 87..93 '&mut a': &mut &u32 380 87..93 '&mut a': &mut &u32
380 92..93 'a': &u32 381 92..93 'a': &u32
381 99..100 'b': &mut u32 382 99..100 'b': &mut u32
382 106..108 '*b': u32 383 106..108 '*b': u32
383 107..108 'b': &mut u32 384 107..108 'b': &mut u32
384 114..116 '&b': &&mut u32 385 114..116 '&b': &&mut u32
385 115..116 'b': &mut u32 386 115..116 'b': &mut u32
386 122..123 'c': *const u32 387 122..123 'c': *const u32
387 129..131 '*c': u32 388 129..131 '*c': u32
388 130..131 'c': *const u32 389 130..131 'c': *const u32
389 137..138 'd': *mut u32 390 137..138 'd': *mut u32
390 144..146 '*d': u32 391 144..146 '*d': u32
391 145..146 'd': *mut u32 392 145..146 'd': *mut u32
392 "### 393 "#]],
393 ); 394 );
394} 395}
395 396
396#[test] 397#[test]
397fn infer_raw_ref() { 398fn infer_raw_ref() {
398 assert_snapshot!( 399 check_infer(
399 infer(r#" 400 r#"
400fn test(a: i32) { 401 fn test(a: i32) {
401 &raw mut a; 402 &raw mut a;
402 &raw const a; 403 &raw const a;
403} 404 }
404"#), 405 "#,
405 @r###" 406 expect![[r#"
406 8..9 'a': i32 407 8..9 'a': i32
407 16..53 '{ ...t a; }': () 408 16..53 '{ ...t a; }': ()
408 22..32 '&raw mut a': *mut i32 409 22..32 '&raw mut a': *mut i32
409 31..32 'a': i32 410 31..32 'a': i32
410 38..50 '&raw const a': *const i32 411 38..50 '&raw const a': *const i32
411 49..50 'a': i32 412 49..50 'a': i32
412 "### 413 "#]],
413 ); 414 );
414} 415}
415 416
416#[test] 417#[test]
417fn infer_literals() { 418fn infer_literals() {
418 assert_snapshot!( 419 check_infer(
419 infer(r##" 420 r##"
420fn test() { 421 fn test() {
421 5i32; 422 5i32;
422 5f32; 423 5f32;
423 5f64; 424 5f64;
424 "hello"; 425 "hello";
425 b"bytes"; 426 b"bytes";
426 'c'; 427 'c';
427 b'b'; 428 b'b';
428 3.14; 429 3.14;
429 5000; 430 5000;
430 false; 431 false;
431 true; 432 true;
432 r#" 433 r#"
433 //! doc 434 //! doc
434 // non-doc 435 // non-doc
435 mod foo {} 436 mod foo {}
436 "#; 437 "#;
437 br#"yolo"#; 438 br#"yolo"#;
438} 439 }
439"##), 440 "##,
440 @r###" 441 expect![[r##"
441 10..220 '{ ...o"#; }': () 442 10..216 '{ ...o"#; }': ()
442 16..20 '5i32': i32 443 16..20 '5i32': i32
443 26..30 '5f32': f32 444 26..30 '5f32': f32
444 36..40 '5f64': f64 445 36..40 '5f64': f64
445 46..53 '"hello"': &str 446 46..53 '"hello"': &str
446 59..67 'b"bytes"': &[u8; _] 447 59..67 'b"bytes"': &[u8; _]
447 73..76 ''c'': char 448 73..76 ''c'': char
448 82..86 'b'b'': u8 449 82..86 'b'b'': u8
449 92..96 '3.14': f64 450 92..96 '3.14': f64
450 102..106 '5000': i32 451 102..106 '5000': i32
451 112..117 'false': bool 452 112..117 'false': bool
452 123..127 'true': bool 453 123..127 'true': bool
453 133..201 'r#" ... "#': &str 454 133..197 'r#" ... "#': &str
454 207..217 'br#"yolo"#': &[u8; _] 455 203..213 'br#"yolo"#': &[u8; _]
455 "### 456 "##]],
456 ); 457 );
457} 458}
458 459
459#[test] 460#[test]
460fn infer_unary_op() { 461fn infer_unary_op() {
461 assert_snapshot!( 462 check_infer(
462 infer(r#" 463 r#"
463enum SomeType {} 464 enum SomeType {}
464 465
465fn test(x: SomeType) { 466 fn test(x: SomeType) {
466 let b = false; 467 let b = false;
467 let c = !b; 468 let c = !b;
468 let a = 100; 469 let a = 100;
469 let d: i128 = -a; 470 let d: i128 = -a;
470 let e = -100; 471 let e = -100;
471 let f = !!!true; 472 let f = !!!true;
472 let g = !42; 473 let g = !42;
473 let h = !10u32; 474 let h = !10u32;
474 let j = !a; 475 let j = !a;
475 -3.14; 476 -3.14;
476 !3; 477 !3;
477 -x; 478 -x;
478 !x; 479 !x;
479 -"hello"; 480 -"hello";
480 !"hello"; 481 !"hello";
481} 482 }
482"#), 483 "#,
483 @r###" 484 expect![[r#"
484 26..27 'x': SomeType 485 26..27 'x': SomeType
485 39..271 '{ ...lo"; }': () 486 39..271 '{ ...lo"; }': ()
486 49..50 'b': bool 487 49..50 'b': bool
487 53..58 'false': bool 488 53..58 'false': bool
488 68..69 'c': bool 489 68..69 'c': bool
489 72..74 '!b': bool 490 72..74 '!b': bool
490 73..74 'b': bool 491 73..74 'b': bool
491 84..85 'a': i128 492 84..85 'a': i128
492 88..91 '100': i128 493 88..91 '100': i128
493 101..102 'd': i128 494 101..102 'd': i128
494 111..113 '-a': i128 495 111..113 '-a': i128
495 112..113 'a': i128 496 112..113 'a': i128
496 123..124 'e': i32 497 123..124 'e': i32
497 127..131 '-100': i32 498 127..131 '-100': i32
498 128..131 '100': i32 499 128..131 '100': i32
499 141..142 'f': bool 500 141..142 'f': bool
500 145..152 '!!!true': bool 501 145..152 '!!!true': bool
501 146..152 '!!true': bool 502 146..152 '!!true': bool
502 147..152 '!true': bool 503 147..152 '!true': bool
503 148..152 'true': bool 504 148..152 'true': bool
504 162..163 'g': i32 505 162..163 'g': i32
505 166..169 '!42': i32 506 166..169 '!42': i32
506 167..169 '42': i32 507 167..169 '42': i32
507 179..180 'h': u32 508 179..180 'h': u32
508 183..189 '!10u32': u32 509 183..189 '!10u32': u32
509 184..189 '10u32': u32 510 184..189 '10u32': u32
510 199..200 'j': i128 511 199..200 'j': i128
511 203..205 '!a': i128 512 203..205 '!a': i128
512 204..205 'a': i128 513 204..205 'a': i128
513 211..216 '-3.14': f64 514 211..216 '-3.14': f64
514 212..216 '3.14': f64 515 212..216 '3.14': f64
515 222..224 '!3': i32 516 222..224 '!3': i32
516 223..224 '3': i32 517 223..224 '3': i32
517 230..232 '-x': {unknown} 518 230..232 '-x': {unknown}
518 231..232 'x': SomeType 519 231..232 'x': SomeType
519 238..240 '!x': {unknown} 520 238..240 '!x': {unknown}
520 239..240 'x': SomeType 521 239..240 'x': SomeType
521 246..254 '-"hello"': {unknown} 522 246..254 '-"hello"': {unknown}
522 247..254 '"hello"': &str 523 247..254 '"hello"': &str
523 260..268 '!"hello"': {unknown} 524 260..268 '!"hello"': {unknown}
524 261..268 '"hello"': &str 525 261..268 '"hello"': &str
525 "### 526 "#]],
526 ); 527 );
527} 528}
528 529
529#[test] 530#[test]
530fn infer_backwards() { 531fn infer_backwards() {
531 assert_snapshot!( 532 check_infer(
532 infer(r#" 533 r#"
533fn takes_u32(x: u32) {} 534 fn takes_u32(x: u32) {}
534 535
535struct S { i32_field: i32 } 536 struct S { i32_field: i32 }
536 537
537fn test() -> &mut &f64 { 538 fn test() -> &mut &f64 {
538 let a = unknown_function(); 539 let a = unknown_function();
539 takes_u32(a); 540 takes_u32(a);
540 let b = unknown_function(); 541 let b = unknown_function();
541 S { i32_field: b }; 542 S { i32_field: b };
542 let c = unknown_function(); 543 let c = unknown_function();
543 &mut &c 544 &mut &c
544} 545 }
545"#), 546 "#,
546 @r###" 547 expect![[r#"
547 13..14 'x': u32 548 13..14 'x': u32
548 21..23 '{}': () 549 21..23 '{}': ()
549 77..230 '{ ...t &c }': &mut &f64 550 77..230 '{ ...t &c }': &mut &f64
550 87..88 'a': u32 551 87..88 'a': u32
551 91..107 'unknow...nction': {unknown} 552 91..107 'unknow...nction': {unknown}
552 91..109 'unknow...tion()': u32 553 91..109 'unknow...tion()': u32
553 115..124 'takes_u32': fn takes_u32(u32) 554 115..124 'takes_u32': fn takes_u32(u32)
554 115..127 'takes_u32(a)': () 555 115..127 'takes_u32(a)': ()
555 125..126 'a': u32 556 125..126 'a': u32
556 137..138 'b': i32 557 137..138 'b': i32
557 141..157 'unknow...nction': {unknown} 558 141..157 'unknow...nction': {unknown}
558 141..159 'unknow...tion()': i32 559 141..159 'unknow...tion()': i32
559 165..183 'S { i3...d: b }': S 560 165..183 'S { i3...d: b }': S
560 180..181 'b': i32 561 180..181 'b': i32
561 193..194 'c': f64 562 193..194 'c': f64
562 197..213 'unknow...nction': {unknown} 563 197..213 'unknow...nction': {unknown}
563 197..215 'unknow...tion()': f64 564 197..215 'unknow...tion()': f64
564 221..228 '&mut &c': &mut &f64 565 221..228 '&mut &c': &mut &f64
565 226..228 '&c': &f64 566 226..228 '&c': &f64
566 227..228 'c': f64 567 227..228 'c': f64
567 "### 568 "#]],
568 ); 569 );
569} 570}
570 571
571#[test] 572#[test]
572fn infer_self() { 573fn infer_self() {
573 assert_snapshot!( 574 check_infer(
574 infer(r#" 575 r#"
575struct S; 576 struct S;
576 577
577impl S { 578 impl S {
578 fn test(&self) { 579 fn test(&self) {
579 self; 580 self;
580 } 581 }
581 fn test2(self: &Self) { 582 fn test2(self: &Self) {
582 self; 583 self;
583 } 584 }
584 fn test3() -> Self { 585 fn test3() -> Self {
585 S {} 586 S {}
586 } 587 }
587 fn test4() -> Self { 588 fn test4() -> Self {
588 Self {} 589 Self {}
589 } 590 }
590} 591 }
591"#), 592 "#,
592 @r###" 593 expect![[r#"
593 33..37 'self': &S 594 33..37 'self': &S
594 39..60 '{ ... }': () 595 39..60 '{ ... }': ()
595 49..53 'self': &S 596 49..53 'self': &S
596 74..78 'self': &S 597 74..78 'self': &S
597 87..108 '{ ... }': () 598 87..108 '{ ... }': ()
598 97..101 'self': &S 599 97..101 'self': &S
599 132..152 '{ ... }': S 600 132..152 '{ ... }': S
600 142..146 'S {}': S 601 142..146 'S {}': S
601 176..199 '{ ... }': S 602 176..199 '{ ... }': S
602 186..193 'Self {}': S 603 186..193 'Self {}': S
603 "### 604 "#]],
604 ); 605 );
605} 606}
606 607
607#[test] 608#[test]
608fn infer_self_as_path() { 609fn infer_self_as_path() {
609 assert_snapshot!( 610 check_infer(
610 infer(r#" 611 r#"
611struct S1; 612 struct S1;
612struct S2(isize); 613 struct S2(isize);
613enum E { 614 enum E {
614 V1, 615 V1,
615 V2(u32), 616 V2(u32),
616} 617 }
617 618
618impl S1 { 619 impl S1 {
619 fn test() { 620 fn test() {
620 Self; 621 Self;
621 } 622 }
622} 623 }
623impl S2 { 624 impl S2 {
624 fn test() { 625 fn test() {
625 Self(1); 626 Self(1);
626 } 627 }
627} 628 }
628impl E { 629 impl E {
629 fn test() { 630 fn test() {
630 Self::V1; 631 Self::V1;
631 Self::V2(1); 632 Self::V2(1);
632 } 633 }
633} 634 }
634"#), 635 "#,
635 @r###" 636 expect![[r#"
636 86..107 '{ ... }': () 637 86..107 '{ ... }': ()
637 96..100 'Self': S1 638 96..100 'Self': S1
638 134..158 '{ ... }': () 639 134..158 '{ ... }': ()
639 144..148 'Self': S2(isize) -> S2 640 144..148 'Self': S2(isize) -> S2
640 144..151 'Self(1)': S2 641 144..151 'Self(1)': S2
641 149..150 '1': isize 642 149..150 '1': isize
642 184..230 '{ ... }': () 643 184..230 '{ ... }': ()
643 194..202 'Self::V1': E 644 194..202 'Self::V1': E
644 212..220 'Self::V2': V2(u32) -> E 645 212..220 'Self::V2': V2(u32) -> E
645 212..223 'Self::V2(1)': E 646 212..223 'Self::V2(1)': E
646 221..222 '1': u32 647 221..222 '1': u32
647 "### 648 "#]],
648 ); 649 );
649} 650}
650 651
651#[test] 652#[test]
652fn infer_binary_op() { 653fn infer_binary_op() {
653 assert_snapshot!( 654 check_infer(
654 infer(r#" 655 r#"
655fn f(x: bool) -> i32 { 656 fn f(x: bool) -> i32 {
656 0i32 657 0i32
657} 658 }
658 659
659fn test() -> bool { 660 fn test() -> bool {
660 let x = a && b; 661 let x = a && b;
661 let y = true || false; 662 let y = true || false;
662 let z = x == y; 663 let z = x == y;
663 let t = x != y; 664 let t = x != y;
664 let minus_forty: isize = -40isize; 665 let minus_forty: isize = -40isize;
665 let h = minus_forty <= CONST_2; 666 let h = minus_forty <= CONST_2;
666 let c = f(z || y) + 5; 667 let c = f(z || y) + 5;
667 let d = b; 668 let d = b;
668 let g = minus_forty ^= i; 669 let g = minus_forty ^= i;
669 let ten: usize = 10; 670 let ten: usize = 10;
670 let ten_is_eleven = ten == some_num; 671 let ten_is_eleven = ten == some_num;
671 672
672 ten < 3 673 ten < 3
673} 674 }
674"#), 675 "#,
675 @r###" 676 expect![[r#"
676 5..6 'x': bool 677 5..6 'x': bool
677 21..33 '{ 0i32 }': i32 678 21..33 '{ 0i32 }': i32
678 27..31 '0i32': i32 679 27..31 '0i32': i32
679 53..369 '{ ... < 3 }': bool 680 53..369 '{ ... < 3 }': bool
680 63..64 'x': bool 681 63..64 'x': bool
681 67..68 'a': bool 682 67..68 'a': bool
682 67..73 'a && b': bool 683 67..73 'a && b': bool
683 72..73 'b': bool 684 72..73 'b': bool
684 83..84 'y': bool 685 83..84 'y': bool
685 87..91 'true': bool 686 87..91 'true': bool
686 87..100 'true || false': bool 687 87..100 'true || false': bool
687 95..100 'false': bool 688 95..100 'false': bool
688 110..111 'z': bool 689 110..111 'z': bool
689 114..115 'x': bool 690 114..115 'x': bool
690 114..120 'x == y': bool 691 114..120 'x == y': bool
691 119..120 'y': bool 692 119..120 'y': bool
692 130..131 't': bool 693 130..131 't': bool
693 134..135 'x': bool 694 134..135 'x': bool
694 134..140 'x != y': bool 695 134..140 'x != y': bool
695 139..140 'y': bool 696 139..140 'y': bool
696 150..161 'minus_forty': isize 697 150..161 'minus_forty': isize
697 171..179 '-40isize': isize 698 171..179 '-40isize': isize
698 172..179 '40isize': isize 699 172..179 '40isize': isize
699 189..190 'h': bool 700 189..190 'h': bool
700 193..204 'minus_forty': isize 701 193..204 'minus_forty': isize
701 193..215 'minus_...ONST_2': bool 702 193..215 'minus_...ONST_2': bool
702 208..215 'CONST_2': isize 703 208..215 'CONST_2': isize
703 225..226 'c': i32 704 225..226 'c': i32
704 229..230 'f': fn f(bool) -> i32 705 229..230 'f': fn f(bool) -> i32
705 229..238 'f(z || y)': i32 706 229..238 'f(z || y)': i32
706 229..242 'f(z || y) + 5': i32 707 229..242 'f(z || y) + 5': i32
707 231..232 'z': bool 708 231..232 'z': bool
708 231..237 'z || y': bool 709 231..237 'z || y': bool
709 236..237 'y': bool 710 236..237 'y': bool
710 241..242 '5': i32 711 241..242 '5': i32
711 252..253 'd': {unknown} 712 252..253 'd': {unknown}
712 256..257 'b': {unknown} 713 256..257 'b': {unknown}
713 267..268 'g': () 714 267..268 'g': ()
714 271..282 'minus_forty': isize 715 271..282 'minus_forty': isize
715 271..287 'minus_...y ^= i': () 716 271..287 'minus_...y ^= i': ()
716 286..287 'i': isize 717 286..287 'i': isize
717 297..300 'ten': usize 718 297..300 'ten': usize
718 310..312 '10': usize 719 310..312 '10': usize
719 322..335 'ten_is_eleven': bool 720 322..335 'ten_is_eleven': bool
720 338..341 'ten': usize 721 338..341 'ten': usize
721 338..353 'ten == some_num': bool 722 338..353 'ten == some_num': bool
722 345..353 'some_num': usize 723 345..353 'some_num': usize
723 360..363 'ten': usize 724 360..363 'ten': usize
724 360..367 'ten < 3': bool 725 360..367 'ten < 3': bool
725 366..367 '3': usize 726 366..367 '3': usize
726 "### 727 "#]],
727 ); 728 );
728} 729}
729 730
730#[test] 731#[test]
731fn infer_shift_op() { 732fn infer_shift_op() {
732 assert_snapshot!( 733 check_infer(
733 infer(r#" 734 r#"
734fn test() { 735 fn test() {
735 1u32 << 5u8; 736 1u32 << 5u8;
736 1u32 >> 5u8; 737 1u32 >> 5u8;
737} 738 }
738"#), 739 "#,
739 @r###" 740 expect![[r#"
740 10..47 '{ ...5u8; }': () 741 10..47 '{ ...5u8; }': ()
741 16..20 '1u32': u32 742 16..20 '1u32': u32
742 16..27 '1u32 << 5u8': u32 743 16..27 '1u32 << 5u8': u32
743 24..27 '5u8': u8 744 24..27 '5u8': u8
744 33..37 '1u32': u32 745 33..37 '1u32': u32
745 33..44 '1u32 >> 5u8': u32 746 33..44 '1u32 >> 5u8': u32
746 41..44 '5u8': u8 747 41..44 '5u8': u8
747 "### 748 "#]],
748 ); 749 );
749} 750}
750 751
751#[test] 752#[test]
752fn infer_field_autoderef() { 753fn infer_field_autoderef() {
753 assert_snapshot!( 754 check_infer(
754 infer(r#" 755 r#"
755struct A { 756 struct A {
756 b: B, 757 b: B,
757} 758 }
758struct B; 759 struct B;
759 760
760fn test1(a: A) { 761 fn test1(a: A) {
761 let a1 = a; 762 let a1 = a;
762 a1.b; 763 a1.b;
763 let a2 = &a; 764 let a2 = &a;
764 a2.b; 765 a2.b;
765 let a3 = &mut a; 766 let a3 = &mut a;
766 a3.b; 767 a3.b;
767 let a4 = &&&&&&&a; 768 let a4 = &&&&&&&a;
768 a4.b; 769 a4.b;
769 let a5 = &mut &&mut &&mut a; 770 let a5 = &mut &&mut &&mut a;
770 a5.b; 771 a5.b;
771} 772 }
772 773
773fn test2(a1: *const A, a2: *mut A) { 774 fn test2(a1: *const A, a2: *mut A) {
774 a1.b; 775 a1.b;
775 a2.b; 776 a2.b;
776} 777 }
777"#), 778 "#,
778 @r###" 779 expect![[r#"
779 43..44 'a': A 780 43..44 'a': A
780 49..212 '{ ...5.b; }': () 781 49..212 '{ ...5.b; }': ()
781 59..61 'a1': A 782 59..61 'a1': A
782 64..65 'a': A 783 64..65 'a': A
783 71..73 'a1': A 784 71..73 'a1': A
784 71..75 'a1.b': B 785 71..75 'a1.b': B
785 85..87 'a2': &A 786 85..87 'a2': &A
786 90..92 '&a': &A 787 90..92 '&a': &A
787 91..92 'a': A 788 91..92 'a': A
788 98..100 'a2': &A 789 98..100 'a2': &A
789 98..102 'a2.b': B 790 98..102 'a2.b': B
790 112..114 'a3': &mut A 791 112..114 'a3': &mut A
791 117..123 '&mut a': &mut A 792 117..123 '&mut a': &mut A
792 122..123 'a': A 793 122..123 'a': A
793 129..131 'a3': &mut A 794 129..131 'a3': &mut A
794 129..133 'a3.b': B 795 129..133 'a3.b': B
795 143..145 'a4': &&&&&&&A 796 143..145 'a4': &&&&&&&A
796 148..156 '&&&&&&&a': &&&&&&&A 797 148..156 '&&&&&&&a': &&&&&&&A
797 149..156 '&&&&&&a': &&&&&&A 798 149..156 '&&&&&&a': &&&&&&A
798 150..156 '&&&&&a': &&&&&A 799 150..156 '&&&&&a': &&&&&A
799 151..156 '&&&&a': &&&&A 800 151..156 '&&&&a': &&&&A
800 152..156 '&&&a': &&&A 801 152..156 '&&&a': &&&A
801 153..156 '&&a': &&A 802 153..156 '&&a': &&A
802 154..156 '&a': &A 803 154..156 '&a': &A
803 155..156 'a': A 804 155..156 'a': A
804 162..164 'a4': &&&&&&&A 805 162..164 'a4': &&&&&&&A
805 162..166 'a4.b': B 806 162..166 'a4.b': B
806 176..178 'a5': &mut &&mut &&mut A 807 176..178 'a5': &mut &&mut &&mut A
807 181..199 '&mut &...&mut a': &mut &&mut &&mut A 808 181..199 '&mut &...&mut a': &mut &&mut &&mut A
808 186..199 '&&mut &&mut a': &&mut &&mut A 809 186..199 '&&mut &&mut a': &&mut &&mut A
809 187..199 '&mut &&mut a': &mut &&mut A 810 187..199 '&mut &&mut a': &mut &&mut A
810 192..199 '&&mut a': &&mut A 811 192..199 '&&mut a': &&mut A
811 193..199 '&mut a': &mut A 812 193..199 '&mut a': &mut A
812 198..199 'a': A 813 198..199 'a': A
813 205..207 'a5': &mut &&mut &&mut A 814 205..207 'a5': &mut &&mut &&mut A
814 205..209 'a5.b': B 815 205..209 'a5.b': B
815 223..225 'a1': *const A 816 223..225 'a1': *const A
816 237..239 'a2': *mut A 817 237..239 'a2': *mut A
817 249..272 '{ ...2.b; }': () 818 249..272 '{ ...2.b; }': ()
818 255..257 'a1': *const A 819 255..257 'a1': *const A
819 255..259 'a1.b': B 820 255..259 'a1.b': B
820 265..267 'a2': *mut A 821 265..267 'a2': *mut A
821 265..269 'a2.b': B 822 265..269 'a2.b': B
822 "### 823 "#]],
823 ); 824 );
824} 825}
825 826
826#[test] 827#[test]
827fn infer_argument_autoderef() { 828fn infer_argument_autoderef() {
828 assert_snapshot!( 829 check_infer(
829 infer(r#" 830 r#"
830#[lang = "deref"] 831 #[lang = "deref"]
831pub trait Deref { 832 pub trait Deref {
832 type Target; 833 type Target;
833 fn deref(&self) -> &Self::Target; 834 fn deref(&self) -> &Self::Target;
834} 835 }
835 836
836struct A<T>(T); 837 struct A<T>(T);
837 838
838impl<T> A<T> { 839 impl<T> A<T> {
839 fn foo(&self) -> &T { 840 fn foo(&self) -> &T {
840 &self.0 841 &self.0
841 } 842 }
842} 843 }
843 844
844struct B<T>(T); 845 struct B<T>(T);
845 846
846impl<T> Deref for B<T> { 847 impl<T> Deref for B<T> {
847 type Target = T; 848 type Target = T;
848 fn deref(&self) -> &Self::Target { 849 fn deref(&self) -> &Self::Target {
849 &self.0 850 &self.0
850 } 851 }
851} 852 }
852 853
853fn test() { 854 fn test() {
854 let t = A::foo(&&B(B(A(42)))); 855 let t = A::foo(&&B(B(A(42))));
855} 856 }
856"#), 857 "#,
857 @r###" 858 expect![[r#"
858 67..71 'self': &Self 859 67..71 'self': &Self
859 138..142 'self': &A<T> 860 138..142 'self': &A<T>
860 150..173 '{ ... }': &T 861 150..173 '{ ... }': &T
861 160..167 '&self.0': &T 862 160..167 '&self.0': &T
862 161..165 'self': &A<T> 863 161..165 'self': &A<T>
863 161..167 'self.0': T 864 161..167 'self.0': T
864 254..258 'self': &B<T> 865 254..258 'self': &B<T>
865 277..300 '{ ... }': &T 866 277..300 '{ ... }': &T
866 287..294 '&self.0': &T 867 287..294 '&self.0': &T
867 288..292 'self': &B<T> 868 288..292 'self': &B<T>
868 288..294 'self.0': T 869 288..294 'self.0': T
869 314..352 '{ ...))); }': () 870 314..352 '{ ...))); }': ()
870 324..325 't': &i32 871 324..325 't': &i32
871 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32 872 328..334 'A::foo': fn foo<i32>(&A<i32>) -> &i32
872 328..349 'A::foo...42))))': &i32 873 328..349 'A::foo...42))))': &i32
873 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>> 874 335..348 '&&B(B(A(42)))': &&B<B<A<i32>>>
874 336..348 '&B(B(A(42)))': &B<B<A<i32>>> 875 336..348 '&B(B(A(42)))': &B<B<A<i32>>>
875 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> 876 337..338 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
876 337..348 'B(B(A(42)))': B<B<A<i32>>> 877 337..348 'B(B(A(42)))': B<B<A<i32>>>
877 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>> 878 339..340 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
878 339..347 'B(A(42))': B<A<i32>> 879 339..347 'B(A(42))': B<A<i32>>
879 341..342 'A': A<i32>(i32) -> A<i32> 880 341..342 'A': A<i32>(i32) -> A<i32>
880 341..346 'A(42)': A<i32> 881 341..346 'A(42)': A<i32>
881 343..345 '42': i32 882 343..345 '42': i32
882 "### 883 "#]],
883 ); 884 );
884} 885}
885 886
886#[test] 887#[test]
887fn infer_method_argument_autoderef() { 888fn infer_method_argument_autoderef() {
888 assert_snapshot!( 889 check_infer(
889 infer(r#" 890 r#"
890#[lang = "deref"] 891 #[lang = "deref"]
891pub trait Deref { 892 pub trait Deref {
892 type Target; 893 type Target;
893 fn deref(&self) -> &Self::Target; 894 fn deref(&self) -> &Self::Target;
894} 895 }
895 896
896struct A<T>(*mut T); 897 struct A<T>(*mut T);
897 898
898impl<T> A<T> { 899 impl<T> A<T> {
899 fn foo(&self, x: &A<T>) -> &T { 900 fn foo(&self, x: &A<T>) -> &T {
900 &*x.0 901 &*x.0
901 } 902 }
902} 903 }
903 904
904struct B<T>(T); 905 struct B<T>(T);
905 906
906impl<T> Deref for B<T> { 907 impl<T> Deref for B<T> {
907 type Target = T; 908 type Target = T;
908 fn deref(&self) -> &Self::Target { 909 fn deref(&self) -> &Self::Target {
909 &self.0 910 &self.0
910 } 911 }
911} 912 }
912 913
913fn test(a: A<i32>) { 914 fn test(a: A<i32>) {
914 let t = A(0 as *mut _).foo(&&B(B(a))); 915 let t = A(0 as *mut _).foo(&&B(B(a)));
915} 916 }
916"#), 917 "#,
917 @r###" 918 expect![[r#"
918 67..71 'self': &Self 919 67..71 'self': &Self
919 143..147 'self': &A<T> 920 143..147 'self': &A<T>
920 149..150 'x': &A<T> 921 149..150 'x': &A<T>
921 165..186 '{ ... }': &T 922 165..186 '{ ... }': &T
922 175..180 '&*x.0': &T 923 175..180 '&*x.0': &T
923 176..180 '*x.0': T 924 176..180 '*x.0': T
924 177..178 'x': &A<T> 925 177..178 'x': &A<T>
925 177..180 'x.0': *mut T 926 177..180 'x.0': *mut T
926 267..271 'self': &B<T> 927 267..271 'self': &B<T>
927 290..313 '{ ... }': &T 928 290..313 '{ ... }': &T
928 300..307 '&self.0': &T 929 300..307 '&self.0': &T
929 301..305 'self': &B<T> 930 301..305 'self': &B<T>
930 301..307 'self.0': T 931 301..307 'self.0': T
931 325..326 'a': A<i32> 932 325..326 'a': A<i32>
932 336..382 '{ ...))); }': () 933 336..382 '{ ...))); }': ()
933 346..347 't': &i32 934 346..347 't': &i32
934 350..351 'A': A<i32>(*mut i32) -> A<i32> 935 350..351 'A': A<i32>(*mut i32) -> A<i32>
935 350..364 'A(0 as *mut _)': A<i32> 936 350..364 'A(0 as *mut _)': A<i32>
936 350..379 'A(0 as...B(a)))': &i32 937 350..379 'A(0 as...B(a)))': &i32
937 352..353 '0': i32 938 352..353 '0': i32
938 352..363 '0 as *mut _': *mut i32 939 352..363 '0 as *mut _': *mut i32
939 369..378 '&&B(B(a))': &&B<B<A<i32>>> 940 369..378 '&&B(B(a))': &&B<B<A<i32>>>
940 370..378 '&B(B(a))': &B<B<A<i32>>> 941 370..378 '&B(B(a))': &B<B<A<i32>>>
941 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>> 942 371..372 'B': B<B<A<i32>>>(B<A<i32>>) -> B<B<A<i32>>>
942 371..378 'B(B(a))': B<B<A<i32>>> 943 371..378 'B(B(a))': B<B<A<i32>>>
943 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>> 944 373..374 'B': B<A<i32>>(A<i32>) -> B<A<i32>>
944 373..377 'B(a)': B<A<i32>> 945 373..377 'B(a)': B<A<i32>>
945 375..376 'a': A<i32> 946 375..376 'a': A<i32>
946 "### 947 "#]],
947 ); 948 );
948} 949}
949 950
950#[test] 951#[test]
951fn infer_in_elseif() { 952fn infer_in_elseif() {
952 assert_snapshot!( 953 check_infer(
953 infer(r#" 954 r#"
954struct Foo { field: i32 } 955 struct Foo { field: i32 }
955fn main(foo: Foo) { 956 fn main(foo: Foo) {
956 if true { 957 if true {
957 958
958 } else if false { 959 } else if false {
959 foo.field 960 foo.field
960 } 961 }
961} 962 }
962"#), 963 "#,
963 @r###" 964 expect![[r#"
964 34..37 'foo': Foo 965 34..37 'foo': Foo
965 44..108 '{ ... } }': () 966 44..108 '{ ... } }': ()
966 50..106 'if tru... }': () 967 50..106 'if tru... }': ()
967 53..57 'true': bool 968 53..57 'true': bool
968 58..66 '{ }': () 969 58..66 '{ }': ()
969 72..106 'if fal... }': i32 970 72..106 'if fal... }': i32
970 75..80 'false': bool 971 75..80 'false': bool
971 81..106 '{ ... }': i32 972 81..106 '{ ... }': i32
972 91..94 'foo': Foo 973 91..94 'foo': Foo
973 91..100 'foo.field': i32 974 91..100 'foo.field': i32
974 "### 975 "#]],
975 ) 976 )
976} 977}
977 978
978#[test] 979#[test]
979fn infer_if_match_with_return() { 980fn infer_if_match_with_return() {
980 assert_snapshot!( 981 check_infer(
981 infer(r#" 982 r#"
982fn foo() { 983 fn foo() {
983 let _x1 = if true { 984 let _x1 = if true {
984 1 985 1
985 } else { 986 } else {
986 return; 987 return;
987 }; 988 };
988 let _x2 = if true { 989 let _x2 = if true {
989 2 990 2
990 } else { 991 } else {
991 return 992 return
992 }; 993 };
993 let _x3 = match true { 994 let _x3 = match true {
994 true => 3, 995 true => 3,
995 _ => { 996 _ => {
996 return; 997 return;
997 } 998 }
998 }; 999 };
999 let _x4 = match true { 1000 let _x4 = match true {
1000 true => 4, 1001 true => 4,
1001 _ => return 1002 _ => return
1002 }; 1003 };
1003}"#), 1004 }"#,
1004 @r###" 1005 expect![[r#"
1005 9..322 '{ ... }; }': () 1006 9..322 '{ ... }; }': ()
1006 19..22 '_x1': i32 1007 19..22 '_x1': i32
1007 25..79 'if tru... }': i32 1008 25..79 'if tru... }': i32
1008 28..32 'true': bool 1009 28..32 'true': bool
1009 33..50 '{ ... }': i32 1010 33..50 '{ ... }': i32
1010 43..44 '1': i32 1011 43..44 '1': i32
1011 56..79 '{ ... }': i32 1012 56..79 '{ ... }': i32
1012 66..72 'return': ! 1013 66..72 'return': !
1013 89..92 '_x2': i32 1014 89..92 '_x2': i32
1014 95..148 'if tru... }': i32 1015 95..148 'if tru... }': i32
1015 98..102 'true': bool 1016 98..102 'true': bool
1016 103..120 '{ ... }': i32 1017 103..120 '{ ... }': i32
1017 113..114 '2': i32 1018 113..114 '2': i32
1018 126..148 '{ ... }': ! 1019 126..148 '{ ... }': !
1019 136..142 'return': ! 1020 136..142 'return': !
1020 158..161 '_x3': i32 1021 158..161 '_x3': i32
1021 164..246 'match ... }': i32 1022 164..246 'match ... }': i32
1022 170..174 'true': bool 1023 170..174 'true': bool
1023 185..189 'true': bool 1024 185..189 'true': bool
1024 185..189 'true': bool 1025 185..189 'true': bool
1025 193..194 '3': i32 1026 193..194 '3': i32
1026 204..205 '_': bool 1027 204..205 '_': bool
1027 209..240 '{ ... }': i32 1028 209..240 '{ ... }': i32
1028 223..229 'return': ! 1029 223..229 'return': !
1029 256..259 '_x4': i32 1030 256..259 '_x4': i32
1030 262..319 'match ... }': i32 1031 262..319 'match ... }': i32
1031 268..272 'true': bool 1032 268..272 'true': bool
1032 283..287 'true': bool 1033 283..287 'true': bool
1033 283..287 'true': bool 1034 283..287 'true': bool
1034 291..292 '4': i32 1035 291..292 '4': i32
1035 302..303 '_': bool 1036 302..303 '_': bool
1036 307..313 'return': ! 1037 307..313 'return': !
1037 "### 1038 "#]],
1038 ) 1039 )
1039} 1040}
1040 1041
1041#[test] 1042#[test]
1042fn infer_inherent_method() { 1043fn infer_inherent_method() {
1043 assert_snapshot!( 1044 check_infer(
1044 infer(r#" 1045 r#"
1045struct A; 1046 struct A;
1046 1047
1047impl A { 1048 impl A {
1048 fn foo(self, x: u32) -> i32 {} 1049 fn foo(self, x: u32) -> i32 {}
1049} 1050 }
1050 1051
1051mod b { 1052 mod b {
1052 impl super::A { 1053 impl super::A {
1053 fn bar(&self, x: u64) -> i64 {} 1054 fn bar(&self, x: u64) -> i64 {}
1054 } 1055 }
1055} 1056 }
1056 1057
1057fn test(a: A) { 1058 fn test(a: A) {
1058 a.foo(1); 1059 a.foo(1);
1059 (&a).bar(1); 1060 (&a).bar(1);
1060 a.bar(1); 1061 a.bar(1);
1061} 1062 }
1062"#), 1063 "#,
1063 @r###" 1064 expect![[r#"
1064 31..35 'self': A 1065 31..35 'self': A
1065 37..38 'x': u32 1066 37..38 'x': u32
1066 52..54 '{}': () 1067 52..54 '{}': ()
1067 102..106 'self': &A 1068 102..106 'self': &A
1068 108..109 'x': u64 1069 108..109 'x': u64
1069 123..125 '{}': () 1070 123..125 '{}': ()
1070 143..144 'a': A 1071 143..144 'a': A
1071 149..197 '{ ...(1); }': () 1072 149..197 '{ ...(1); }': ()
1072 155..156 'a': A 1073 155..156 'a': A
1073 155..163 'a.foo(1)': i32 1074 155..163 'a.foo(1)': i32
1074 161..162 '1': u32 1075 161..162 '1': u32
1075 169..180 '(&a).bar(1)': i64 1076 169..180 '(&a).bar(1)': i64
1076 170..172 '&a': &A 1077 170..172 '&a': &A
1077 171..172 'a': A 1078 171..172 'a': A
1078 178..179 '1': u64 1079 178..179 '1': u64
1079 186..187 'a': A 1080 186..187 'a': A
1080 186..194 'a.bar(1)': i64 1081 186..194 'a.bar(1)': i64
1081 192..193 '1': u64 1082 192..193 '1': u64
1082 "### 1083 "#]],
1083 ); 1084 );
1084} 1085}
1085 1086
1086#[test] 1087#[test]
1087fn infer_inherent_method_str() { 1088fn infer_inherent_method_str() {
1088 assert_snapshot!( 1089 check_infer(
1089 infer(r#" 1090 r#"
1090#[lang = "str"] 1091 #[lang = "str"]
1091impl str { 1092 impl str {
1092 fn foo(&self) -> i32 {} 1093 fn foo(&self) -> i32 {}
1093} 1094 }
1094 1095
1095fn test() { 1096 fn test() {
1096 "foo".foo(); 1097 "foo".foo();
1097} 1098 }
1098"#), 1099 "#,
1099 @r###" 1100 expect![[r#"
1100 39..43 'self': &str 1101 39..43 'self': &str
1101 52..54 '{}': () 1102 52..54 '{}': ()
1102 68..88 '{ ...o(); }': () 1103 68..88 '{ ...o(); }': ()
1103 74..79 '"foo"': &str 1104 74..79 '"foo"': &str
1104 74..85 '"foo".foo()': i32 1105 74..85 '"foo".foo()': i32
1105 "### 1106 "#]],
1106 ); 1107 );
1107} 1108}
1108 1109
1109#[test] 1110#[test]
1110fn infer_tuple() { 1111fn infer_tuple() {
1111 assert_snapshot!( 1112 check_infer(
1112 infer(r#" 1113 r#"
1113fn test(x: &str, y: isize) { 1114 fn test(x: &str, y: isize) {
1114 let a: (u32, &str) = (1, "a"); 1115 let a: (u32, &str) = (1, "a");
1115 let b = (a, x); 1116 let b = (a, x);
1116 let c = (y, x); 1117 let c = (y, x);
1117 let d = (c, x); 1118 let d = (c, x);
1118 let e = (1, "e"); 1119 let e = (1, "e");
1119 let f = (e, "d"); 1120 let f = (e, "d");
1120} 1121 }
1121"#), 1122 "#,
1122 @r###" 1123 expect![[r#"
1123 8..9 'x': &str 1124 8..9 'x': &str
1124 17..18 'y': isize 1125 17..18 'y': isize
1125 27..169 '{ ...d"); }': () 1126 27..169 '{ ...d"); }': ()
1126 37..38 'a': (u32, &str) 1127 37..38 'a': (u32, &str)
1127 54..62 '(1, "a")': (u32, &str) 1128 54..62 '(1, "a")': (u32, &str)
1128 55..56 '1': u32 1129 55..56 '1': u32
1129 58..61 '"a"': &str 1130 58..61 '"a"': &str
1130 72..73 'b': ((u32, &str), &str) 1131 72..73 'b': ((u32, &str), &str)
1131 76..82 '(a, x)': ((u32, &str), &str) 1132 76..82 '(a, x)': ((u32, &str), &str)
1132 77..78 'a': (u32, &str) 1133 77..78 'a': (u32, &str)
1133 80..81 'x': &str 1134 80..81 'x': &str
1134 92..93 'c': (isize, &str) 1135 92..93 'c': (isize, &str)
1135 96..102 '(y, x)': (isize, &str) 1136 96..102 '(y, x)': (isize, &str)
1136 97..98 'y': isize 1137 97..98 'y': isize
1137 100..101 'x': &str 1138 100..101 'x': &str
1138 112..113 'd': ((isize, &str), &str) 1139 112..113 'd': ((isize, &str), &str)
1139 116..122 '(c, x)': ((isize, &str), &str) 1140 116..122 '(c, x)': ((isize, &str), &str)
1140 117..118 'c': (isize, &str) 1141 117..118 'c': (isize, &str)
1141 120..121 'x': &str 1142 120..121 'x': &str
1142 132..133 'e': (i32, &str) 1143 132..133 'e': (i32, &str)
1143 136..144 '(1, "e")': (i32, &str) 1144 136..144 '(1, "e")': (i32, &str)
1144 137..138 '1': i32 1145 137..138 '1': i32
1145 140..143 '"e"': &str 1146 140..143 '"e"': &str
1146 154..155 'f': ((i32, &str), &str) 1147 154..155 'f': ((i32, &str), &str)
1147 158..166 '(e, "d")': ((i32, &str), &str) 1148 158..166 '(e, "d")': ((i32, &str), &str)
1148 159..160 'e': (i32, &str) 1149 159..160 'e': (i32, &str)
1149 162..165 '"d"': &str 1150 162..165 '"d"': &str
1150 "### 1151 "#]],
1151 ); 1152 );
1152} 1153}
1153 1154
1154#[test] 1155#[test]
1155fn infer_array() { 1156fn infer_array() {
1156 assert_snapshot!( 1157 check_infer(
1157 infer(r#" 1158 r#"
1158fn test(x: &str, y: isize) { 1159 fn test(x: &str, y: isize) {
1159 let a = [x]; 1160 let a = [x];
1160 let b = [a, a]; 1161 let b = [a, a];
1161 let c = [b, b]; 1162 let c = [b, b];
1162 1163
1163 let d = [y, 1, 2, 3]; 1164 let d = [y, 1, 2, 3];
1164 let d = [1, y, 2, 3]; 1165 let d = [1, y, 2, 3];
1165 let e = [y]; 1166 let e = [y];
1166 let f = [d, d]; 1167 let f = [d, d];
1167 let g = [e, e]; 1168 let g = [e, e];
1168 1169
1169 let h = [1, 2]; 1170 let h = [1, 2];
1170 let i = ["a", "b"]; 1171 let i = ["a", "b"];
1171 1172
1172 let b = [a, ["b"]]; 1173 let b = [a, ["b"]];
1173 let x: [u8; 0] = []; 1174 let x: [u8; 0] = [];
1174} 1175 }
1175"#), 1176 "#,
1176 @r###" 1177 expect![[r#"
1177 8..9 'x': &str 1178 8..9 'x': &str
1178 17..18 'y': isize 1179 17..18 'y': isize
1179 27..292 '{ ... []; }': () 1180 27..292 '{ ... []; }': ()
1180 37..38 'a': [&str; _] 1181 37..38 'a': [&str; _]
1181 41..44 '[x]': [&str; _] 1182 41..44 '[x]': [&str; _]
1182 42..43 'x': &str 1183 42..43 'x': &str
1183 54..55 'b': [[&str; _]; _] 1184 54..55 'b': [[&str; _]; _]
1184 58..64 '[a, a]': [[&str; _]; _] 1185 58..64 '[a, a]': [[&str; _]; _]
1185 59..60 'a': [&str; _] 1186 59..60 'a': [&str; _]
1186 62..63 'a': [&str; _] 1187 62..63 'a': [&str; _]
1187 74..75 'c': [[[&str; _]; _]; _] 1188 74..75 'c': [[[&str; _]; _]; _]
1188 78..84 '[b, b]': [[[&str; _]; _]; _] 1189 78..84 '[b, b]': [[[&str; _]; _]; _]
1189 79..80 'b': [[&str; _]; _] 1190 79..80 'b': [[&str; _]; _]
1190 82..83 'b': [[&str; _]; _] 1191 82..83 'b': [[&str; _]; _]
1191 95..96 'd': [isize; _] 1192 95..96 'd': [isize; _]
1192 99..111 '[y, 1, 2, 3]': [isize; _] 1193 99..111 '[y, 1, 2, 3]': [isize; _]
1193 100..101 'y': isize 1194 100..101 'y': isize
1194 103..104 '1': isize 1195 103..104 '1': isize
1195 106..107 '2': isize 1196 106..107 '2': isize
1196 109..110 '3': isize 1197 109..110 '3': isize
1197 121..122 'd': [isize; _] 1198 121..122 'd': [isize; _]
1198 125..137 '[1, y, 2, 3]': [isize; _] 1199 125..137 '[1, y, 2, 3]': [isize; _]
1199 126..127 '1': isize 1200 126..127 '1': isize
1200 129..130 'y': isize 1201 129..130 'y': isize
1201 132..133 '2': isize 1202 132..133 '2': isize
1202 135..136 '3': isize 1203 135..136 '3': isize
1203 147..148 'e': [isize; _] 1204 147..148 'e': [isize; _]
1204 151..154 '[y]': [isize; _] 1205 151..154 '[y]': [isize; _]
1205 152..153 'y': isize 1206 152..153 'y': isize
1206 164..165 'f': [[isize; _]; _] 1207 164..165 'f': [[isize; _]; _]
1207 168..174 '[d, d]': [[isize; _]; _] 1208 168..174 '[d, d]': [[isize; _]; _]
1208 169..170 'd': [isize; _] 1209 169..170 'd': [isize; _]
1209 172..173 'd': [isize; _] 1210 172..173 'd': [isize; _]
1210 184..185 'g': [[isize; _]; _] 1211 184..185 'g': [[isize; _]; _]
1211 188..194 '[e, e]': [[isize; _]; _] 1212 188..194 '[e, e]': [[isize; _]; _]
1212 189..190 'e': [isize; _] 1213 189..190 'e': [isize; _]
1213 192..193 'e': [isize; _] 1214 192..193 'e': [isize; _]
1214 205..206 'h': [i32; _] 1215 205..206 'h': [i32; _]
1215 209..215 '[1, 2]': [i32; _] 1216 209..215 '[1, 2]': [i32; _]
1216 210..211 '1': i32 1217 210..211 '1': i32
1217 213..214 '2': i32 1218 213..214 '2': i32
1218 225..226 'i': [&str; _] 1219 225..226 'i': [&str; _]
1219 229..239 '["a", "b"]': [&str; _] 1220 229..239 '["a", "b"]': [&str; _]
1220 230..233 '"a"': &str 1221 230..233 '"a"': &str
1221 235..238 '"b"': &str 1222 235..238 '"b"': &str
1222 250..251 'b': [[&str; _]; _] 1223 250..251 'b': [[&str; _]; _]
1223 254..264 '[a, ["b"]]': [[&str; _]; _] 1224 254..264 '[a, ["b"]]': [[&str; _]; _]
1224 255..256 'a': [&str; _] 1225 255..256 'a': [&str; _]
1225 258..263 '["b"]': [&str; _] 1226 258..263 '["b"]': [&str; _]
1226 259..262 '"b"': &str 1227 259..262 '"b"': &str
1227 274..275 'x': [u8; _] 1228 274..275 'x': [u8; _]
1228 287..289 '[]': [u8; _] 1229 287..289 '[]': [u8; _]
1229 "### 1230 "#]],
1230 ); 1231 );
1231} 1232}
1232 1233
1233#[test] 1234#[test]
1234fn infer_struct_generics() { 1235fn infer_struct_generics() {
1235 assert_snapshot!( 1236 check_infer(
1236 infer(r#" 1237 r#"
1237struct A<T> { 1238 struct A<T> {
1238 x: T, 1239 x: T,
1239} 1240 }
1240 1241
1241fn test(a1: A<u32>, i: i32) { 1242 fn test(a1: A<u32>, i: i32) {
1242 a1.x; 1243 a1.x;
1243 let a2 = A { x: i }; 1244 let a2 = A { x: i };
1244 a2.x; 1245 a2.x;
1245 let a3 = A::<i128> { x: 1 }; 1246 let a3 = A::<i128> { x: 1 };
1246 a3.x; 1247 a3.x;
1247} 1248 }
1248"#), 1249 "#,
1249 @r###" 1250 expect![[r#"
1250 35..37 'a1': A<u32> 1251 35..37 'a1': A<u32>
1251 47..48 'i': i32 1252 47..48 'i': i32
1252 55..146 '{ ...3.x; }': () 1253 55..146 '{ ...3.x; }': ()
1253 61..63 'a1': A<u32> 1254 61..63 'a1': A<u32>
1254 61..65 'a1.x': u32 1255 61..65 'a1.x': u32
1255 75..77 'a2': A<i32> 1256 75..77 'a2': A<i32>
1256 80..90 'A { x: i }': A<i32> 1257 80..90 'A { x: i }': A<i32>
1257 87..88 'i': i32 1258 87..88 'i': i32
1258 96..98 'a2': A<i32> 1259 96..98 'a2': A<i32>
1259 96..100 'a2.x': i32 1260 96..100 'a2.x': i32
1260 110..112 'a3': A<i128> 1261 110..112 'a3': A<i128>
1261 115..133 'A::<i1...x: 1 }': A<i128> 1262 115..133 'A::<i1...x: 1 }': A<i128>
1262 130..131 '1': i128 1263 130..131 '1': i128
1263 139..141 'a3': A<i128> 1264 139..141 'a3': A<i128>
1264 139..143 'a3.x': i128 1265 139..143 'a3.x': i128
1265 "### 1266 "#]],
1266 ); 1267 );
1267} 1268}
1268 1269
1269#[test] 1270#[test]
1270fn infer_tuple_struct_generics() { 1271fn infer_tuple_struct_generics() {
1271 assert_snapshot!( 1272 check_infer(
1272 infer(r#" 1273 r#"
1273struct A<T>(T); 1274 struct A<T>(T);
1274enum Option<T> { Some(T), None } 1275 enum Option<T> { Some(T), None }
1275use Option::*; 1276 use Option::*;
1276 1277
1277fn test() { 1278 fn test() {
1278 A(42); 1279 A(42);
1279 A(42u128); 1280 A(42u128);
1280 Some("x"); 1281 Some("x");
1281 Option::Some("x"); 1282 Option::Some("x");
1282 None; 1283 None;
1283 let x: Option<i64> = None; 1284 let x: Option<i64> = None;
1284} 1285 }
1285"#), 1286 "#,
1286 @r###" 1287 expect![[r#"
1287 75..183 '{ ...one; }': () 1288 75..183 '{ ...one; }': ()
1288 81..82 'A': A<i32>(i32) -> A<i32> 1289 81..82 'A': A<i32>(i32) -> A<i32>
1289 81..86 'A(42)': A<i32> 1290 81..86 'A(42)': A<i32>
1290 83..85 '42': i32 1291 83..85 '42': i32
1291 92..93 'A': A<u128>(u128) -> A<u128> 1292 92..93 'A': A<u128>(u128) -> A<u128>
1292 92..101 'A(42u128)': A<u128> 1293 92..101 'A(42u128)': A<u128>
1293 94..100 '42u128': u128 1294 94..100 '42u128': u128
1294 107..111 'Some': Some<&str>(&str) -> Option<&str> 1295 107..111 'Some': Some<&str>(&str) -> Option<&str>
1295 107..116 'Some("x")': Option<&str> 1296 107..116 'Some("x")': Option<&str>
1296 112..115 '"x"': &str 1297 112..115 '"x"': &str
1297 122..134 'Option::Some': Some<&str>(&str) -> Option<&str> 1298 122..134 'Option::Some': Some<&str>(&str) -> Option<&str>
1298 122..139 'Option...e("x")': Option<&str> 1299 122..139 'Option...e("x")': Option<&str>
1299 135..138 '"x"': &str 1300 135..138 '"x"': &str
1300 145..149 'None': Option<{unknown}> 1301 145..149 'None': Option<{unknown}>
1301 159..160 'x': Option<i64> 1302 159..160 'x': Option<i64>
1302 176..180 'None': Option<i64> 1303 176..180 'None': Option<i64>
1303 "### 1304 "#]],
1304 ); 1305 );
1305} 1306}
1306 1307
1307#[test] 1308#[test]
1308fn infer_function_generics() { 1309fn infer_function_generics() {
1309 assert_snapshot!( 1310 check_infer(
1310 infer(r#" 1311 r#"
1311fn id<T>(t: T) -> T { t } 1312 fn id<T>(t: T) -> T { t }
1312 1313
1313fn test() { 1314 fn test() {
1314 id(1u32); 1315 id(1u32);
1315 id::<i128>(1); 1316 id::<i128>(1);
1316 let x: u64 = id(1); 1317 let x: u64 = id(1);
1317} 1318 }
1318"#), 1319 "#,
1319 @r###" 1320 expect![[r#"
1320 9..10 't': T 1321 9..10 't': T
1321 20..25 '{ t }': T 1322 20..25 '{ t }': T
1322 22..23 't': T 1323 22..23 't': T
1323 37..97 '{ ...(1); }': () 1324 37..97 '{ ...(1); }': ()
1324 43..45 'id': fn id<u32>(u32) -> u32 1325 43..45 'id': fn id<u32>(u32) -> u32
1325 43..51 'id(1u32)': u32 1326 43..51 'id(1u32)': u32
1326 46..50 '1u32': u32 1327 46..50 '1u32': u32
1327 57..67 'id::<i128>': fn id<i128>(i128) -> i128 1328 57..67 'id::<i128>': fn id<i128>(i128) -> i128
1328 57..70 'id::<i128>(1)': i128 1329 57..70 'id::<i128>(1)': i128
1329 68..69 '1': i128 1330 68..69 '1': i128
1330 80..81 'x': u64 1331 80..81 'x': u64
1331 89..91 'id': fn id<u64>(u64) -> u64 1332 89..91 'id': fn id<u64>(u64) -> u64
1332 89..94 'id(1)': u64 1333 89..94 'id(1)': u64
1333 92..93 '1': u64 1334 92..93 '1': u64
1334 "### 1335 "#]],
1335 ); 1336 );
1336} 1337}
1337 1338
1338#[test] 1339#[test]
1339fn infer_impl_generics_basic() { 1340fn infer_impl_generics_basic() {
1340 assert_snapshot!( 1341 check_infer(
1341 infer(r#" 1342 r#"
1342struct A<T1, T2> { 1343 struct A<T1, T2> {
1343 x: T1, 1344 x: T1,
1344 y: T2, 1345 y: T2,
1345} 1346 }
1346impl<Y, X> A<X, Y> { 1347 impl<Y, X> A<X, Y> {
1347 fn x(self) -> X { 1348 fn x(self) -> X {
1348 self.x 1349 self.x
1349 } 1350 }
1350 fn y(self) -> Y { 1351 fn y(self) -> Y {
1351 self.y 1352 self.y
1352 } 1353 }
1353 fn z<T>(self, t: T) -> (X, Y, T) { 1354 fn z<T>(self, t: T) -> (X, Y, T) {
1354 (self.x, self.y, t) 1355 (self.x, self.y, t)
1355 } 1356 }
1356} 1357 }
1357 1358
1358fn test() -> i128 { 1359 fn test() -> i128 {
1359 let a = A { x: 1u64, y: 1i64 }; 1360 let a = A { x: 1u64, y: 1i64 };
1360 a.x(); 1361 a.x();
1361 a.y(); 1362 a.y();
1362 a.z(1i128); 1363 a.z(1i128);
1363 a.z::<u128>(1); 1364 a.z::<u128>(1);
1364} 1365 }
1365"#), 1366 "#,
1366 @r###" 1367 expect![[r#"
1367 73..77 'self': A<X, Y> 1368 73..77 'self': A<X, Y>
1368 84..106 '{ ... }': X 1369 84..106 '{ ... }': X
1369 94..98 'self': A<X, Y> 1370 94..98 'self': A<X, Y>
1370 94..100 'self.x': X 1371 94..100 'self.x': X
1371 116..120 'self': A<X, Y> 1372 116..120 'self': A<X, Y>
1372 127..149 '{ ... }': Y 1373 127..149 '{ ... }': Y
1373 137..141 'self': A<X, Y> 1374 137..141 'self': A<X, Y>
1374 137..143 'self.y': Y 1375 137..143 'self.y': Y
1375 162..166 'self': A<X, Y> 1376 162..166 'self': A<X, Y>
1376 168..169 't': T 1377 168..169 't': T
1377 187..222 '{ ... }': (X, Y, T) 1378 187..222 '{ ... }': (X, Y, T)
1378 197..216 '(self.....y, t)': (X, Y, T) 1379 197..216 '(self.....y, t)': (X, Y, T)
1379 198..202 'self': A<X, Y> 1380 198..202 'self': A<X, Y>
1380 198..204 'self.x': X 1381 198..204 'self.x': X
1381 206..210 'self': A<X, Y> 1382 206..210 'self': A<X, Y>
1382 206..212 'self.y': Y 1383 206..212 'self.y': Y
1383 214..215 't': T 1384 214..215 't': T
1384 244..341 '{ ...(1); }': () 1385 244..341 '{ ...(1); }': ()
1385 254..255 'a': A<u64, i64> 1386 254..255 'a': A<u64, i64>
1386 258..280 'A { x:...1i64 }': A<u64, i64> 1387 258..280 'A { x:...1i64 }': A<u64, i64>
1387 265..269 '1u64': u64 1388 265..269 '1u64': u64
1388 274..278 '1i64': i64 1389 274..278 '1i64': i64
1389 286..287 'a': A<u64, i64> 1390 286..287 'a': A<u64, i64>
1390 286..291 'a.x()': u64 1391 286..291 'a.x()': u64
1391 297..298 'a': A<u64, i64> 1392 297..298 'a': A<u64, i64>
1392 297..302 'a.y()': i64 1393 297..302 'a.y()': i64
1393 308..309 'a': A<u64, i64> 1394 308..309 'a': A<u64, i64>
1394 308..318 'a.z(1i128)': (u64, i64, i128) 1395 308..318 'a.z(1i128)': (u64, i64, i128)
1395 312..317 '1i128': i128 1396 312..317 '1i128': i128
1396 324..325 'a': A<u64, i64> 1397 324..325 'a': A<u64, i64>
1397 324..338 'a.z::<u128>(1)': (u64, i64, u128) 1398 324..338 'a.z::<u128>(1)': (u64, i64, u128)
1398 336..337 '1': u128 1399 336..337 '1': u128
1399 "### 1400 "#]],
1400 ); 1401 );
1401} 1402}
1402 1403
1403#[test] 1404#[test]
1404fn infer_impl_generics_with_autoderef() { 1405fn infer_impl_generics_with_autoderef() {
1405 assert_snapshot!( 1406 check_infer(
1406 infer(r#" 1407 r#"
1407enum Option<T> { 1408 enum Option<T> {
1408 Some(T), 1409 Some(T),
1409 None, 1410 None,
1410} 1411 }
1411impl<T> Option<T> { 1412 impl<T> Option<T> {
1412 fn as_ref(&self) -> Option<&T> {} 1413 fn as_ref(&self) -> Option<&T> {}
1413} 1414 }
1414fn test(o: Option<u32>) { 1415 fn test(o: Option<u32>) {
1415 (&o).as_ref(); 1416 (&o).as_ref();
1416 o.as_ref(); 1417 o.as_ref();
1417} 1418 }
1418"#), 1419 "#,
1419 @r###" 1420 expect![[r#"
1420 77..81 'self': &Option<T> 1421 77..81 'self': &Option<T>
1421 97..99 '{}': () 1422 97..99 '{}': ()
1422 110..111 'o': Option<u32> 1423 110..111 'o': Option<u32>
1423 126..164 '{ ...f(); }': () 1424 126..164 '{ ...f(); }': ()
1424 132..145 '(&o).as_ref()': Option<&u32> 1425 132..145 '(&o).as_ref()': Option<&u32>
1425 133..135 '&o': &Option<u32> 1426 133..135 '&o': &Option<u32>
1426 134..135 'o': Option<u32> 1427 134..135 'o': Option<u32>
1427 151..152 'o': Option<u32> 1428 151..152 'o': Option<u32>
1428 151..161 'o.as_ref()': Option<&u32> 1429 151..161 'o.as_ref()': Option<&u32>
1429 "### 1430 "#]],
1430 ); 1431 );
1431} 1432}
1432 1433
1433#[test] 1434#[test]
1434fn infer_generic_chain() { 1435fn infer_generic_chain() {
1435 assert_snapshot!( 1436 check_infer(
1436 infer(r#" 1437 r#"
1437struct A<T> { 1438 struct A<T> {
1438 x: T, 1439 x: T,
1439} 1440 }
1440impl<T2> A<T2> { 1441 impl<T2> A<T2> {
1441 fn x(self) -> T2 { 1442 fn x(self) -> T2 {
1442 self.x 1443 self.x
1443 } 1444 }
1444} 1445 }
1445fn id<T>(t: T) -> T { t } 1446 fn id<T>(t: T) -> T { t }
1446 1447
1447fn test() -> i128 { 1448 fn test() -> i128 {
1448 let x = 1; 1449 let x = 1;
1449 let y = id(x); 1450 let y = id(x);
1450 let a = A { x: id(y) }; 1451 let a = A { x: id(y) };
1451 let z = id(a.x); 1452 let z = id(a.x);
1452 let b = A { x: z }; 1453 let b = A { x: z };
1453 b.x() 1454 b.x()
1454} 1455 }
1455"#), 1456 "#,
1456 @r###" 1457 expect![[r#"
1457 52..56 'self': A<T2> 1458 52..56 'self': A<T2>
1458 64..86 '{ ... }': T2 1459 64..86 '{ ... }': T2
1459 74..78 'self': A<T2> 1460 74..78 'self': A<T2>
1460 74..80 'self.x': T2 1461 74..80 'self.x': T2
1461 98..99 't': T 1462 98..99 't': T
1462 109..114 '{ t }': T 1463 109..114 '{ t }': T
1463 111..112 't': T 1464 111..112 't': T
1464 134..260 '{ ....x() }': i128 1465 134..254 '{ ....x() }': i128
1465 145..146 'x': i128 1466 144..145 'x': i128
1466 149..150 '1': i128 1467 148..149 '1': i128
1467 161..162 'y': i128 1468 159..160 'y': i128
1468 165..167 'id': fn id<i128>(i128) -> i128 1469 163..165 'id': fn id<i128>(i128) -> i128
1469 165..170 'id(x)': i128 1470 163..168 'id(x)': i128
1470 168..169 'x': i128 1471 166..167 'x': i128
1471 181..182 'a': A<i128> 1472 178..179 'a': A<i128>
1472 185..199 'A { x: id(y) }': A<i128> 1473 182..196 'A { x: id(y) }': A<i128>
1473 192..194 'id': fn id<i128>(i128) -> i128 1474 189..191 'id': fn id<i128>(i128) -> i128
1474 192..197 'id(y)': i128 1475 189..194 'id(y)': i128
1475 195..196 'y': i128 1476 192..193 'y': i128
1476 210..211 'z': i128 1477 206..207 'z': i128
1477 214..216 'id': fn id<i128>(i128) -> i128 1478 210..212 'id': fn id<i128>(i128) -> i128
1478 214..221 'id(a.x)': i128 1479 210..217 'id(a.x)': i128
1479 217..218 'a': A<i128> 1480 213..214 'a': A<i128>
1480 217..220 'a.x': i128 1481 213..216 'a.x': i128
1481 232..233 'b': A<i128> 1482 227..228 'b': A<i128>
1482 236..246 'A { x: z }': A<i128> 1483 231..241 'A { x: z }': A<i128>
1483 243..244 'z': i128 1484 238..239 'z': i128
1484 253..254 'b': A<i128> 1485 247..248 'b': A<i128>
1485 253..258 'b.x()': i128 1486 247..252 'b.x()': i128
1486 "### 1487 "#]],
1487 ); 1488 );
1488} 1489}
1489 1490
1490#[test] 1491#[test]
1491fn infer_associated_const() { 1492fn infer_associated_const() {
1492 assert_snapshot!( 1493 check_infer(
1493 infer(r#" 1494 r#"
1494struct Struct; 1495 struct Struct;
1495 1496
1496impl Struct { 1497 impl Struct {
1497 const FOO: u32 = 1; 1498 const FOO: u32 = 1;
1498} 1499 }
1499 1500
1500enum Enum {} 1501 enum Enum {}
1501 1502
1502impl Enum { 1503 impl Enum {
1503 const BAR: u32 = 2; 1504 const BAR: u32 = 2;
1504} 1505 }
1505 1506
1506trait Trait { 1507 trait Trait {
1507 const ID: u32; 1508 const ID: u32;
1508} 1509 }
1509 1510
1510struct TraitTest; 1511 struct TraitTest;
1511 1512
1512impl Trait for TraitTest { 1513 impl Trait for TraitTest {
1513 const ID: u32 = 5; 1514 const ID: u32 = 5;
1514} 1515 }
1515 1516
1516fn test() { 1517 fn test() {
1517 let x = Struct::FOO; 1518 let x = Struct::FOO;
1518 let y = Enum::BAR; 1519 let y = Enum::BAR;
1519 let z = TraitTest::ID; 1520 let z = TraitTest::ID;
1520} 1521 }
1521"#), 1522 "#,
1522 @r###" 1523 expect![[r#"
1523 51..52 '1': u32 1524 51..52 '1': u32
1524 104..105 '2': u32 1525 104..105 '2': u32
1525 212..213 '5': u32 1526 212..213 '5': u32
1526 228..306 '{ ...:ID; }': () 1527 228..306 '{ ...:ID; }': ()
1527 238..239 'x': u32 1528 238..239 'x': u32
1528 242..253 'Struct::FOO': u32 1529 242..253 'Struct::FOO': u32
1529 263..264 'y': u32 1530 263..264 'y': u32
1530 267..276 'Enum::BAR': u32 1531 267..276 'Enum::BAR': u32
1531 286..287 'z': u32 1532 286..287 'z': u32
1532 290..303 'TraitTest::ID': u32 1533 290..303 'TraitTest::ID': u32
1533 "### 1534 "#]],
1534 ); 1535 );
1535} 1536}
1536 1537
1537#[test] 1538#[test]
1538fn infer_type_alias() { 1539fn infer_type_alias() {
1539 assert_snapshot!( 1540 check_infer(
1540 infer(r#" 1541 r#"
1541struct A<X, Y> { x: X, y: Y } 1542 struct A<X, Y> { x: X, y: Y }
1542type Foo = A<u32, i128>; 1543 type Foo = A<u32, i128>;
1543type Bar<T> = A<T, u128>; 1544 type Bar<T> = A<T, u128>;
1544type Baz<U, V> = A<V, U>; 1545 type Baz<U, V> = A<V, U>;
1545fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) { 1546 fn test(x: Foo, y: Bar<&str>, z: Baz<i8, u8>) {
1546 x.x; 1547 x.x;
1547 x.y; 1548 x.y;
1548 y.x; 1549 y.x;
1549 y.y; 1550 y.y;
1550 z.x; 1551 z.x;
1551 z.y; 1552 z.y;
1552} 1553 }
1553"#), 1554 "#,
1554 @r###" 1555 expect![[r#"
1555 115..116 'x': A<u32, i128> 1556 115..116 'x': A<u32, i128>
1556 123..124 'y': A<&str, u128> 1557 123..124 'y': A<&str, u128>
1557 137..138 'z': A<u8, i8> 1558 137..138 'z': A<u8, i8>
1558 153..210 '{ ...z.y; }': () 1559 153..210 '{ ...z.y; }': ()
1559 159..160 'x': A<u32, i128> 1560 159..160 'x': A<u32, i128>
1560 159..162 'x.x': u32 1561 159..162 'x.x': u32
1561 168..169 'x': A<u32, i128> 1562 168..169 'x': A<u32, i128>
1562 168..171 'x.y': i128 1563 168..171 'x.y': i128
1563 177..178 'y': A<&str, u128> 1564 177..178 'y': A<&str, u128>
1564 177..180 'y.x': &str 1565 177..180 'y.x': &str
1565 186..187 'y': A<&str, u128> 1566 186..187 'y': A<&str, u128>
1566 186..189 'y.y': u128 1567 186..189 'y.y': u128
1567 195..196 'z': A<u8, i8> 1568 195..196 'z': A<u8, i8>
1568 195..198 'z.x': u8 1569 195..198 'z.x': u8
1569 204..205 'z': A<u8, i8> 1570 204..205 'z': A<u8, i8>
1570 204..207 'z.y': i8 1571 204..207 'z.y': i8
1571 "### 1572 "#]],
1572 ) 1573 )
1573} 1574}
1574 1575
1575#[test] 1576#[test]
1576fn recursive_type_alias() { 1577fn recursive_type_alias() {
1577 assert_snapshot!( 1578 check_infer(
1578 infer(r#" 1579 r#"
1579struct A<X> {} 1580 struct A<X> {}
1580type Foo = Foo; 1581 type Foo = Foo;
1581type Bar = A<Bar>; 1582 type Bar = A<Bar>;
1582fn test(x: Foo) {} 1583 fn test(x: Foo) {}
1583"#), 1584 "#,
1584 @r###" 1585 expect![[r#"
1585 58..59 'x': {unknown} 1586 58..59 'x': {unknown}
1586 66..68 '{}': () 1587 66..68 '{}': ()
1587 "### 1588 "#]],
1588 ) 1589 )
1589} 1590}
1590 1591
1591#[test] 1592#[test]
1592fn infer_type_param() { 1593fn infer_type_param() {
1593 assert_snapshot!( 1594 check_infer(
1594 infer(r#" 1595 r#"
1595fn id<T>(x: T) -> T { 1596 fn id<T>(x: T) -> T {
1596 x 1597 x
1597} 1598 }
1598 1599
1599fn clone<T>(x: &T) -> T { 1600 fn clone<T>(x: &T) -> T {
1600 *x 1601 *x
1601} 1602 }
1602 1603
1603fn test() { 1604 fn test() {
1604 let y = 10u32; 1605 let y = 10u32;
1605 id(y); 1606 id(y);
1606 let x: bool = clone(z); 1607 let x: bool = clone(z);
1607 id::<i128>(1); 1608 id::<i128>(1);
1608} 1609 }
1609"#), 1610 "#,
1610 @r###" 1611 expect![[r#"
1611 9..10 'x': T 1612 9..10 'x': T
1612 20..29 '{ x }': T 1613 20..29 '{ x }': T
1613 26..27 'x': T 1614 26..27 'x': T
1614 43..44 'x': &T 1615 43..44 'x': &T
1615 55..65 '{ *x }': T 1616 55..65 '{ *x }': T
1616 61..63 '*x': T 1617 61..63 '*x': T
1617 62..63 'x': &T 1618 62..63 'x': &T
1618 77..157 '{ ...(1); }': () 1619 77..157 '{ ...(1); }': ()
1619 87..88 'y': u32 1620 87..88 'y': u32
1620 91..96 '10u32': u32 1621 91..96 '10u32': u32
1621 102..104 'id': fn id<u32>(u32) -> u32 1622 102..104 'id': fn id<u32>(u32) -> u32
1622 102..107 'id(y)': u32 1623 102..107 'id(y)': u32
1623 105..106 'y': u32 1624 105..106 'y': u32
1624 117..118 'x': bool 1625 117..118 'x': bool
1625 127..132 'clone': fn clone<bool>(&bool) -> bool 1626 127..132 'clone': fn clone<bool>(&bool) -> bool
1626 127..135 'clone(z)': bool 1627 127..135 'clone(z)': bool
1627 133..134 'z': &bool 1628 133..134 'z': &bool
1628 141..151 'id::<i128>': fn id<i128>(i128) -> i128 1629 141..151 'id::<i128>': fn id<i128>(i128) -> i128
1629 141..154 'id::<i128>(1)': i128 1630 141..154 'id::<i128>(1)': i128
1630 152..153 '1': i128 1631 152..153 '1': i128
1631 "### 1632 "#]],
1632 ); 1633 );
1633} 1634}
1634 1635
1635#[test] 1636#[test]
1636fn infer_const() { 1637fn infer_const() {
1637 assert_snapshot!( 1638 check_infer(
1638 infer(r#" 1639 r#"
1639struct Foo; 1640 struct Foo;
1640impl Foo { const ASSOC_CONST: u32 = 0; } 1641 impl Foo { const ASSOC_CONST: u32 = 0; }
1641const GLOBAL_CONST: u32 = 101; 1642 const GLOBAL_CONST: u32 = 101;
1642fn test() { 1643 fn test() {
1643 const LOCAL_CONST: u32 = 99; 1644 const LOCAL_CONST: u32 = 99;
1644 let x = LOCAL_CONST; 1645 let x = LOCAL_CONST;
1645 let z = GLOBAL_CONST; 1646 let z = GLOBAL_CONST;
1646 let id = Foo::ASSOC_CONST; 1647 let id = Foo::ASSOC_CONST;
1647} 1648 }
1648"#), 1649 "#,
1649 @r###" 1650 expect![[r#"
1650 48..49 '0': u32 1651 48..49 '0': u32
1651 79..82 '101': u32 1652 79..82 '101': u32
1652 94..212 '{ ...NST; }': () 1653 94..212 '{ ...NST; }': ()
1653 137..138 'x': u32 1654 137..138 'x': u32
1654 141..152 'LOCAL_CONST': u32 1655 141..152 'LOCAL_CONST': u32
1655 162..163 'z': u32 1656 162..163 'z': u32
1656 166..178 'GLOBAL_CONST': u32 1657 166..178 'GLOBAL_CONST': u32
1657 188..190 'id': u32 1658 188..190 'id': u32
1658 193..209 'Foo::A..._CONST': u32 1659 193..209 'Foo::A..._CONST': u32
1659 125..127 '99': u32 1660 125..127 '99': u32
1660 "### 1661 "#]],
1661 ); 1662 );
1662} 1663}
1663 1664
1664#[test] 1665#[test]
1665fn infer_static() { 1666fn infer_static() {
1666 assert_snapshot!( 1667 check_infer(
1667 infer(r#" 1668 r#"
1668static GLOBAL_STATIC: u32 = 101; 1669 static GLOBAL_STATIC: u32 = 101;
1669static mut GLOBAL_STATIC_MUT: u32 = 101; 1670 static mut GLOBAL_STATIC_MUT: u32 = 101;
1670fn test() { 1671 fn test() {
1671 static LOCAL_STATIC: u32 = 99; 1672 static LOCAL_STATIC: u32 = 99;
1672 static mut LOCAL_STATIC_MUT: u32 = 99; 1673 static mut LOCAL_STATIC_MUT: u32 = 99;
1673 let x = LOCAL_STATIC; 1674 let x = LOCAL_STATIC;
1674 let y = LOCAL_STATIC_MUT; 1675 let y = LOCAL_STATIC_MUT;
1675 let z = GLOBAL_STATIC; 1676 let z = GLOBAL_STATIC;
1676 let w = GLOBAL_STATIC_MUT; 1677 let w = GLOBAL_STATIC_MUT;
1677} 1678 }
1678"#), 1679 "#,
1679 @r###" 1680 expect![[r#"
1680 28..31 '101': u32 1681 28..31 '101': u32
1681 69..72 '101': u32 1682 69..72 '101': u32
1682 84..279 '{ ...MUT; }': () 1683 84..279 '{ ...MUT; }': ()
1683 172..173 'x': u32 1684 172..173 'x': u32
1684 176..188 'LOCAL_STATIC': u32 1685 176..188 'LOCAL_STATIC': u32
1685 198..199 'y': u32 1686 198..199 'y': u32
1686 202..218 'LOCAL_...IC_MUT': u32 1687 202..218 'LOCAL_...IC_MUT': u32
1687 228..229 'z': u32 1688 228..229 'z': u32
1688 232..245 'GLOBAL_STATIC': u32 1689 232..245 'GLOBAL_STATIC': u32
1689 255..256 'w': u32 1690 255..256 'w': u32
1690 259..276 'GLOBAL...IC_MUT': u32 1691 259..276 'GLOBAL...IC_MUT': u32
1691 117..119 '99': u32 1692 117..119 '99': u32
1692 160..162 '99': u32 1693 160..162 '99': u32
1693 "### 1694 "#]],
1694 ); 1695 );
1695} 1696}
1696 1697
@@ -1777,413 +1778,413 @@ fn main() {
1777 1778
1778#[test] 1779#[test]
1779fn closure_return() { 1780fn closure_return() {
1780 assert_snapshot!( 1781 check_infer(
1781 infer(r#" 1782 r#"
1782fn foo() -> u32 { 1783 fn foo() -> u32 {
1783 let x = || -> usize { return 1; }; 1784 let x = || -> usize { return 1; };
1784} 1785 }
1785"#), 1786 "#,
1786 @r###" 1787 expect![[r#"
1787 16..58 '{ ...; }; }': () 1788 16..58 '{ ...; }; }': ()
1788 26..27 'x': || -> usize 1789 26..27 'x': || -> usize
1789 30..55 '|| -> ...n 1; }': || -> usize 1790 30..55 '|| -> ...n 1; }': || -> usize
1790 42..55 '{ return 1; }': usize 1791 42..55 '{ return 1; }': usize
1791 44..52 'return 1': ! 1792 44..52 'return 1': !
1792 51..52 '1': usize 1793 51..52 '1': usize
1793 "### 1794 "#]],
1794 ); 1795 );
1795} 1796}
1796 1797
1797#[test] 1798#[test]
1798fn closure_return_unit() { 1799fn closure_return_unit() {
1799 assert_snapshot!( 1800 check_infer(
1800 infer(r#" 1801 r#"
1801fn foo() -> u32 { 1802 fn foo() -> u32 {
1802 let x = || { return; }; 1803 let x = || { return; };
1803} 1804 }
1804"#), 1805 "#,
1805 @r###" 1806 expect![[r#"
1806 16..47 '{ ...; }; }': () 1807 16..47 '{ ...; }; }': ()
1807 26..27 'x': || -> () 1808 26..27 'x': || -> ()
1808 30..44 '|| { return; }': || -> () 1809 30..44 '|| { return; }': || -> ()
1809 33..44 '{ return; }': () 1810 33..44 '{ return; }': ()
1810 35..41 'return': ! 1811 35..41 'return': !
1811 "### 1812 "#]],
1812 ); 1813 );
1813} 1814}
1814 1815
1815#[test] 1816#[test]
1816fn closure_return_inferred() { 1817fn closure_return_inferred() {
1817 assert_snapshot!( 1818 check_infer(
1818 infer(r#" 1819 r#"
1819fn foo() -> u32 { 1820 fn foo() -> u32 {
1820 let x = || { "test" }; 1821 let x = || { "test" };
1821} 1822 }
1822"#), 1823 "#,
1823 @r###" 1824 expect![[r#"
1824 16..46 '{ ..." }; }': () 1825 16..46 '{ ..." }; }': ()
1825 26..27 'x': || -> &str 1826 26..27 'x': || -> &str
1826 30..43 '|| { "test" }': || -> &str 1827 30..43 '|| { "test" }': || -> &str
1827 33..43 '{ "test" }': &str 1828 33..43 '{ "test" }': &str
1828 35..41 '"test"': &str 1829 35..41 '"test"': &str
1829 "### 1830 "#]],
1830 ); 1831 );
1831} 1832}
1832 1833
1833#[test] 1834#[test]
1834fn fn_pointer_return() { 1835fn fn_pointer_return() {
1835 assert_snapshot!( 1836 check_infer(
1836 infer(r#" 1837 r#"
1837struct Vtable { 1838 struct Vtable {
1838 method: fn(), 1839 method: fn(),
1839} 1840 }
1840 1841
1841fn main() { 1842 fn main() {
1842 let vtable = Vtable { method: || {} }; 1843 let vtable = Vtable { method: || {} };
1843 let m = vtable.method; 1844 let m = vtable.method;
1844} 1845 }
1845"#), 1846 "#,
1846 @r###" 1847 expect![[r#"
1847 47..120 '{ ...hod; }': () 1848 47..120 '{ ...hod; }': ()
1848 57..63 'vtable': Vtable 1849 57..63 'vtable': Vtable
1849 66..90 'Vtable...| {} }': Vtable 1850 66..90 'Vtable...| {} }': Vtable
1850 83..88 '|| {}': || -> () 1851 83..88 '|| {}': || -> ()
1851 86..88 '{}': () 1852 86..88 '{}': ()
1852 100..101 'm': fn() 1853 100..101 'm': fn()
1853 104..110 'vtable': Vtable 1854 104..110 'vtable': Vtable
1854 104..117 'vtable.method': fn() 1855 104..117 'vtable.method': fn()
1855 "### 1856 "#]],
1856 ); 1857 );
1857} 1858}
1858 1859
1859#[test] 1860#[test]
1860fn effects_smoke_test() { 1861fn effects_smoke_test() {
1861 assert_snapshot!( 1862 check_infer(
1862 infer(r#" 1863 r#"
1863fn main() { 1864 fn main() {
1864 let x = unsafe { 92 }; 1865 let x = unsafe { 92 };
1865 let y = async { async { () }.await }; 1866 let y = async { async { () }.await };
1866 let z = try { () }; 1867 let z = try { () };
1867 let t = 'a: { 92 }; 1868 let t = 'a: { 92 };
1868} 1869 }
1869"#), 1870 "#,
1870 @r###" 1871 expect![[r#"
1871 10..130 '{ ...2 }; }': () 1872 10..130 '{ ...2 }; }': ()
1872 20..21 'x': i32 1873 20..21 'x': i32
1873 24..37 'unsafe { 92 }': i32 1874 24..37 'unsafe { 92 }': i32
1874 31..37 '{ 92 }': i32 1875 31..37 '{ 92 }': i32
1875 33..35 '92': i32 1876 33..35 '92': i32
1876 47..48 'y': {unknown} 1877 47..48 'y': {unknown}
1877 57..79 '{ asyn...wait }': {unknown} 1878 57..79 '{ asyn...wait }': {unknown}
1878 59..77 'async ....await': {unknown} 1879 59..77 'async ....await': {unknown}
1879 65..71 '{ () }': () 1880 65..71 '{ () }': ()
1880 67..69 '()': () 1881 67..69 '()': ()
1881 89..90 'z': {unknown} 1882 89..90 'z': {unknown}
1882 93..103 'try { () }': {unknown} 1883 93..103 'try { () }': {unknown}
1883 97..103 '{ () }': () 1884 97..103 '{ () }': ()
1884 99..101 '()': () 1885 99..101 '()': ()
1885 113..114 't': i32 1886 113..114 't': i32
1886 121..127 '{ 92 }': i32 1887 121..127 '{ 92 }': i32
1887 123..125 '92': i32 1888 123..125 '92': i32
1888 "### 1889 "#]],
1889 ) 1890 )
1890} 1891}
1891 1892
1892#[test] 1893#[test]
1893fn infer_generic_from_later_assignment() { 1894fn infer_generic_from_later_assignment() {
1894 assert_snapshot!( 1895 check_infer(
1895 infer(r#" 1896 r#"
1896enum Option<T> { Some(T), None } 1897 enum Option<T> { Some(T), None }
1897use Option::*; 1898 use Option::*;
1898 1899
1899fn test() { 1900 fn test() {
1900 let mut end = None; 1901 let mut end = None;
1901 loop { 1902 loop {
1902 end = Some(true); 1903 end = Some(true);
1903 } 1904 }
1904} 1905 }
1905"#), 1906 "#,
1906 @r###" 1907 expect![[r#"
1907 59..129 '{ ... } }': () 1908 59..129 '{ ... } }': ()
1908 69..76 'mut end': Option<bool> 1909 69..76 'mut end': Option<bool>
1909 79..83 'None': Option<bool> 1910 79..83 'None': Option<bool>
1910 89..127 'loop {... }': ! 1911 89..127 'loop {... }': !
1911 94..127 '{ ... }': () 1912 94..127 '{ ... }': ()
1912 104..107 'end': Option<bool> 1913 104..107 'end': Option<bool>
1913 104..120 'end = ...(true)': () 1914 104..120 'end = ...(true)': ()
1914 110..114 'Some': Some<bool>(bool) -> Option<bool> 1915 110..114 'Some': Some<bool>(bool) -> Option<bool>
1915 110..120 'Some(true)': Option<bool> 1916 110..120 'Some(true)': Option<bool>
1916 115..119 'true': bool 1917 115..119 'true': bool
1917 "### 1918 "#]],
1918 ); 1919 );
1919} 1920}
1920 1921
1921#[test] 1922#[test]
1922fn infer_loop_break_with_val() { 1923fn infer_loop_break_with_val() {
1923 assert_snapshot!( 1924 check_infer(
1924 infer(r#" 1925 r#"
1925enum Option<T> { Some(T), None } 1926 enum Option<T> { Some(T), None }
1926use Option::*; 1927 use Option::*;
1927 1928
1928fn test() { 1929 fn test() {
1929 let x = loop { 1930 let x = loop {
1930 if false { 1931 if false {
1931 break None; 1932 break None;
1932 } 1933 }
1933 1934
1934 break Some(true); 1935 break Some(true);
1935 }; 1936 };
1936} 1937 }
1937"#), 1938 "#,
1938 @r###" 1939 expect![[r#"
1939 59..168 '{ ... }; }': () 1940 59..168 '{ ... }; }': ()
1940 69..70 'x': Option<bool> 1941 69..70 'x': Option<bool>
1941 73..165 'loop {... }': Option<bool> 1942 73..165 'loop {... }': Option<bool>
1942 78..165 '{ ... }': () 1943 78..165 '{ ... }': ()
1943 88..132 'if fal... }': () 1944 88..132 'if fal... }': ()
1944 91..96 'false': bool 1945 91..96 'false': bool
1945 97..132 '{ ... }': () 1946 97..132 '{ ... }': ()
1946 111..121 'break None': ! 1947 111..121 'break None': !
1947 117..121 'None': Option<bool> 1948 117..121 'None': Option<bool>
1948 142..158 'break ...(true)': ! 1949 142..158 'break ...(true)': !
1949 148..152 'Some': Some<bool>(bool) -> Option<bool> 1950 148..152 'Some': Some<bool>(bool) -> Option<bool>
1950 148..158 'Some(true)': Option<bool> 1951 148..158 'Some(true)': Option<bool>
1951 153..157 'true': bool 1952 153..157 'true': bool
1952 "### 1953 "#]],
1953 ); 1954 );
1954} 1955}
1955 1956
1956#[test] 1957#[test]
1957fn infer_loop_break_without_val() { 1958fn infer_loop_break_without_val() {
1958 assert_snapshot!( 1959 check_infer(
1959 infer(r#" 1960 r#"
1960enum Option<T> { Some(T), None } 1961 enum Option<T> { Some(T), None }
1961use Option::*; 1962 use Option::*;
1962 1963
1963fn test() { 1964 fn test() {
1964 let x = loop { 1965 let x = loop {
1965 if false { 1966 if false {
1966 break; 1967 break;
1967 } 1968 }
1968 }; 1969 };
1969} 1970 }
1970"#), 1971 "#,
1971 @r###" 1972 expect![[r#"
1972 59..136 '{ ... }; }': () 1973 59..136 '{ ... }; }': ()
1973 69..70 'x': () 1974 69..70 'x': ()
1974 73..133 'loop {... }': () 1975 73..133 'loop {... }': ()
1975 78..133 '{ ... }': () 1976 78..133 '{ ... }': ()
1976 88..127 'if fal... }': () 1977 88..127 'if fal... }': ()
1977 91..96 'false': bool 1978 91..96 'false': bool
1978 97..127 '{ ... }': () 1979 97..127 '{ ... }': ()
1979 111..116 'break': ! 1980 111..116 'break': !
1980 "### 1981 "#]],
1981 ); 1982 );
1982} 1983}
1983 1984
1984#[test] 1985#[test]
1985fn infer_labelled_break_with_val() { 1986fn infer_labelled_break_with_val() {
1986 assert_snapshot!( 1987 check_infer(
1987 infer(r#" 1988 r#"
1988fn foo() { 1989 fn foo() {
1989 let _x = || 'outer: loop { 1990 let _x = || 'outer: loop {
1990 let inner = 'inner: loop { 1991 let inner = 'inner: loop {
1991 let i = Default::default(); 1992 let i = Default::default();
1992 if (break 'outer i) { 1993 if (break 'outer i) {
1993 loop { break 'inner 5i8; }; 1994 loop { break 'inner 5i8; };
1994 } else if true { 1995 } else if true {
1995 break 'inner 6; 1996 break 'inner 6;
1996 } 1997 }
1997 break 7; 1998 break 7;
1998 }; 1999 };
1999 break inner < 8; 2000 break inner < 8;
2000 }; 2001 };
2001} 2002 }
2002"#), 2003 "#,
2003 @r###" 2004 expect![[r#"
2004 9..335 '{ ... }; }': () 2005 9..335 '{ ... }; }': ()
2005 19..21 '_x': || -> bool 2006 19..21 '_x': || -> bool
2006 24..332 '|| 'ou... }': || -> bool 2007 24..332 '|| 'ou... }': || -> bool
2007 27..332 ''outer... }': bool 2008 27..332 ''outer... }': bool
2008 40..332 '{ ... }': () 2009 40..332 '{ ... }': ()
2009 54..59 'inner': i8 2010 54..59 'inner': i8
2010 62..300 ''inner... }': i8 2011 62..300 ''inner... }': i8
2011 75..300 '{ ... }': () 2012 75..300 '{ ... }': ()
2012 93..94 'i': bool 2013 93..94 'i': bool
2013 97..113 'Defaul...efault': {unknown} 2014 97..113 'Defaul...efault': {unknown}
2014 97..115 'Defaul...ault()': bool 2015 97..115 'Defaul...ault()': bool
2015 129..269 'if (br... }': () 2016 129..269 'if (br... }': ()
2016 133..147 'break 'outer i': ! 2017 133..147 'break 'outer i': !
2017 146..147 'i': bool 2018 146..147 'i': bool
2018 149..208 '{ ... }': () 2019 149..208 '{ ... }': ()
2019 167..193 'loop {...5i8; }': ! 2020 167..193 'loop {...5i8; }': !
2020 172..193 '{ brea...5i8; }': () 2021 172..193 '{ brea...5i8; }': ()
2021 174..190 'break ...er 5i8': ! 2022 174..190 'break ...er 5i8': !
2022 187..190 '5i8': i8 2023 187..190 '5i8': i8
2023 214..269 'if tru... }': () 2024 214..269 'if tru... }': ()
2024 217..221 'true': bool 2025 217..221 'true': bool
2025 222..269 '{ ... }': () 2026 222..269 '{ ... }': ()
2026 240..254 'break 'inner 6': ! 2027 240..254 'break 'inner 6': !
2027 253..254 '6': i8 2028 253..254 '6': i8
2028 282..289 'break 7': ! 2029 282..289 'break 7': !
2029 288..289 '7': i8 2030 288..289 '7': i8
2030 310..325 'break inner < 8': ! 2031 310..325 'break inner < 8': !
2031 316..321 'inner': i8 2032 316..321 'inner': i8
2032 316..325 'inner < 8': bool 2033 316..325 'inner < 8': bool
2033 324..325 '8': i8 2034 324..325 '8': i8
2034 "### 2035 "#]],
2035 ); 2036 );
2036} 2037}
2037 2038
2038#[test] 2039#[test]
2039fn generic_default() { 2040fn generic_default() {
2040 assert_snapshot!( 2041 check_infer(
2041 infer(r#" 2042 r#"
2042struct Thing<T = ()> { t: T } 2043 struct Thing<T = ()> { t: T }
2043enum OtherThing<T = ()> { 2044 enum OtherThing<T = ()> {
2044 One { t: T }, 2045 One { t: T },
2045 Two(T), 2046 Two(T),
2046} 2047 }
2047 2048
2048fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) { 2049 fn test(t1: Thing, t2: OtherThing, t3: Thing<i32>, t4: OtherThing<i32>) {
2049 t1.t; 2050 t1.t;
2050 t3.t; 2051 t3.t;
2051 match t2 { 2052 match t2 {
2052 OtherThing::One { t } => { t; }, 2053 OtherThing::One { t } => { t; },
2053 OtherThing::Two(t) => { t; }, 2054 OtherThing::Two(t) => { t; },
2054 } 2055 }
2055 match t4 { 2056 match t4 {
2056 OtherThing::One { t } => { t; }, 2057 OtherThing::One { t } => { t; },
2057 OtherThing::Two(t) => { t; }, 2058 OtherThing::Two(t) => { t; },
2058 } 2059 }
2059} 2060 }
2060"#), 2061 "#,
2061 @r###" 2062 expect![[r#"
2062 97..99 't1': Thing<()> 2063 97..99 't1': Thing<()>
2063 108..110 't2': OtherThing<()> 2064 108..110 't2': OtherThing<()>
2064 124..126 't3': Thing<i32> 2065 124..126 't3': Thing<i32>
2065 140..142 't4': OtherThing<i32> 2066 140..142 't4': OtherThing<i32>
2066 161..384 '{ ... } }': () 2067 161..384 '{ ... } }': ()
2067 167..169 't1': Thing<()> 2068 167..169 't1': Thing<()>
2068 167..171 't1.t': () 2069 167..171 't1.t': ()
2069 177..179 't3': Thing<i32> 2070 177..179 't3': Thing<i32>
2070 177..181 't3.t': i32 2071 177..181 't3.t': i32
2071 187..282 'match ... }': () 2072 187..282 'match ... }': ()
2072 193..195 't2': OtherThing<()> 2073 193..195 't2': OtherThing<()>
2073 206..227 'OtherT... { t }': OtherThing<()> 2074 206..227 'OtherT... { t }': OtherThing<()>
2074 224..225 't': () 2075 224..225 't': ()
2075 231..237 '{ t; }': () 2076 231..237 '{ t; }': ()
2076 233..234 't': () 2077 233..234 't': ()
2077 247..265 'OtherT...Two(t)': OtherThing<()> 2078 247..265 'OtherT...Two(t)': OtherThing<()>
2078 263..264 't': () 2079 263..264 't': ()
2079 269..275 '{ t; }': () 2080 269..275 '{ t; }': ()
2080 271..272 't': () 2081 271..272 't': ()
2081 287..382 'match ... }': () 2082 287..382 'match ... }': ()
2082 293..295 't4': OtherThing<i32> 2083 293..295 't4': OtherThing<i32>
2083 306..327 'OtherT... { t }': OtherThing<i32> 2084 306..327 'OtherT... { t }': OtherThing<i32>
2084 324..325 't': i32 2085 324..325 't': i32
2085 331..337 '{ t; }': () 2086 331..337 '{ t; }': ()
2086 333..334 't': i32 2087 333..334 't': i32
2087 347..365 'OtherT...Two(t)': OtherThing<i32> 2088 347..365 'OtherT...Two(t)': OtherThing<i32>
2088 363..364 't': i32 2089 363..364 't': i32
2089 369..375 '{ t; }': () 2090 369..375 '{ t; }': ()
2090 371..372 't': i32 2091 371..372 't': i32
2091 "### 2092 "#]],
2092 ); 2093 );
2093} 2094}
2094 2095
2095#[test] 2096#[test]
2096fn generic_default_in_struct_literal() { 2097fn generic_default_in_struct_literal() {
2097 assert_snapshot!( 2098 check_infer(
2098 infer(r#" 2099 r#"
2099struct Thing<T = ()> { t: T } 2100 struct Thing<T = ()> { t: T }
2100enum OtherThing<T = ()> { 2101 enum OtherThing<T = ()> {
2101 One { t: T }, 2102 One { t: T },
2102 Two(T), 2103 Two(T),
2103} 2104 }
2104 2105
2105fn test() { 2106 fn test() {
2106 let x = Thing { t: loop {} }; 2107 let x = Thing { t: loop {} };
2107 let y = Thing { t: () }; 2108 let y = Thing { t: () };
2108 let z = Thing { t: 1i32 }; 2109 let z = Thing { t: 1i32 };
2109 if let Thing { t } = z { 2110 if let Thing { t } = z {
2110 t; 2111 t;
2111 } 2112 }
2112 2113
2113 let a = OtherThing::One { t: 1i32 }; 2114 let a = OtherThing::One { t: 1i32 };
2114 let b = OtherThing::Two(1i32); 2115 let b = OtherThing::Two(1i32);
2115} 2116 }
2116"#), 2117 "#,
2117 @r###" 2118 expect![[r#"
2118 99..319 '{ ...32); }': () 2119 99..319 '{ ...32); }': ()
2119 109..110 'x': Thing<!> 2120 109..110 'x': Thing<!>
2120 113..133 'Thing ...p {} }': Thing<!> 2121 113..133 'Thing ...p {} }': Thing<!>
2121 124..131 'loop {}': ! 2122 124..131 'loop {}': !
2122 129..131 '{}': () 2123 129..131 '{}': ()
2123 143..144 'y': Thing<()> 2124 143..144 'y': Thing<()>
2124 147..162 'Thing { t: () }': Thing<()> 2125 147..162 'Thing { t: () }': Thing<()>
2125 158..160 '()': () 2126 158..160 '()': ()
2126 172..173 'z': Thing<i32> 2127 172..173 'z': Thing<i32>
2127 176..193 'Thing ...1i32 }': Thing<i32> 2128 176..193 'Thing ...1i32 }': Thing<i32>
2128 187..191 '1i32': i32 2129 187..191 '1i32': i32
2129 199..240 'if let... }': () 2130 199..240 'if let... }': ()
2130 206..217 'Thing { t }': Thing<i32> 2131 206..217 'Thing { t }': Thing<i32>
2131 214..215 't': i32 2132 214..215 't': i32
2132 220..221 'z': Thing<i32> 2133 220..221 'z': Thing<i32>
2133 222..240 '{ ... }': () 2134 222..240 '{ ... }': ()
2134 232..233 't': i32 2135 232..233 't': i32
2135 250..251 'a': OtherThing<i32> 2136 250..251 'a': OtherThing<i32>
2136 254..281 'OtherT...1i32 }': OtherThing<i32> 2137 254..281 'OtherT...1i32 }': OtherThing<i32>
2137 275..279 '1i32': i32 2138 275..279 '1i32': i32
2138 291..292 'b': OtherThing<i32> 2139 291..292 'b': OtherThing<i32>
2139 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32> 2140 295..310 'OtherThing::Two': Two<i32>(i32) -> OtherThing<i32>
2140 295..316 'OtherT...(1i32)': OtherThing<i32> 2141 295..316 'OtherT...(1i32)': OtherThing<i32>
2141 311..315 '1i32': i32 2142 311..315 '1i32': i32
2142 "### 2143 "#]],
2143 ); 2144 );
2144} 2145}
2145 2146
2146#[test] 2147#[test]
2147fn generic_default_depending_on_other_type_arg() { 2148fn generic_default_depending_on_other_type_arg() {
2148 assert_snapshot!( 2149 // FIXME: the {unknown} is a bug
2149 infer(r#" 2150 check_infer(
2150struct Thing<T = u128, F = fn() -> T> { t: T } 2151 r#"
2151 2152 struct Thing<T = u128, F = fn() -> T> { t: T }
2152fn test(t1: Thing<u32>, t2: Thing) { 2153
2153 t1; 2154 fn test(t1: Thing<u32>, t2: Thing) {
2154 t2; 2155 t1;
2155 Thing::<_> { t: 1u32 }; 2156 t2;
2156} 2157 Thing::<_> { t: 1u32 };
2157"#), 2158 }
2158 // FIXME: the {unknown} is a bug 2159 "#,
2159 @r###" 2160 expect![[r#"
2160 56..58 't1': Thing<u32, fn() -> u32> 2161 56..58 't1': Thing<u32, fn() -> u32>
2161 72..74 't2': Thing<u128, fn() -> u128> 2162 72..74 't2': Thing<u128, fn() -> u128>
2162 83..130 '{ ...2 }; }': () 2163 83..130 '{ ...2 }; }': ()
2163 89..91 't1': Thing<u32, fn() -> u32> 2164 89..91 't1': Thing<u32, fn() -> u32>
2164 97..99 't2': Thing<u128, fn() -> u128> 2165 97..99 't2': Thing<u128, fn() -> u128>
2165 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}> 2166 105..127 'Thing:...1u32 }': Thing<u32, fn() -> {unknown}>
2166 121..125 '1u32': u32 2167 121..125 '1u32': u32
2167 "### 2168 "#]],
2168 ); 2169 );
2169} 2170}
2170 2171
2171#[test] 2172#[test]
2172fn generic_default_depending_on_other_type_arg_forward() { 2173fn generic_default_depending_on_other_type_arg_forward() {
2173 assert_snapshot!( 2174 // the {unknown} here is intentional, as defaults are not allowed to
2174 infer(r#" 2175 // refer to type parameters coming later
2175struct Thing<F = fn() -> T, T = u128> { t: T } 2176 check_infer(
2176 2177 r#"
2177fn test(t1: Thing) { 2178 struct Thing<F = fn() -> T, T = u128> { t: T }
2178 t1; 2179
2179} 2180 fn test(t1: Thing) {
2180"#), 2181 t1;
2181 // the {unknown} here is intentional, as defaults are not allowed to 2182 }
2182 // refer to type parameters coming later 2183 "#,
2183 @r###" 2184 expect![[r#"
2184 56..58 't1': Thing<fn() -> {unknown}, u128> 2185 56..58 't1': Thing<fn() -> {unknown}, u128>
2185 67..78 '{ t1; }': () 2186 67..78 '{ t1; }': ()
2186 73..75 't1': Thing<fn() -> {unknown}, u128> 2187 73..75 't1': Thing<fn() -> {unknown}, u128>
2187 "### 2188 "#]],
2188 ); 2189 );
2189} 2190}
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 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::{check_types, infer, infer_with_mismatches}; 4use super::{check_infer, check_infer_with_mismatches, check_types};
5 5
6#[test] 6#[test]
7fn infer_await() { 7fn infer_await() {
@@ -38,7 +38,7 @@ fn infer_async() {
38 r#" 38 r#"
39//- /main.rs crate:main deps:core 39//- /main.rs crate:main deps:core
40async fn foo() -> u64 { 40async fn foo() -> u64 {
41 128 41 128
42} 42}
43 43
44fn test() { 44fn test() {
@@ -65,7 +65,7 @@ fn infer_desugar_async() {
65 r#" 65 r#"
66//- /main.rs crate:main deps:core 66//- /main.rs crate:main deps:core
67async fn foo() -> u64 { 67async fn foo() -> u64 {
68 128 68 128
69} 69}
70 70
71fn test() { 71fn test() {
@@ -222,291 +222,291 @@ mod ops {
222 222
223#[test] 223#[test]
224fn infer_from_bound_1() { 224fn infer_from_bound_1() {
225 assert_snapshot!( 225 check_infer(
226 infer(r#" 226 r#"
227trait Trait<T> {} 227 trait Trait<T> {}
228struct S<T>(T); 228 struct S<T>(T);
229impl<U> Trait<U> for S<U> {} 229 impl<U> Trait<U> for S<U> {}
230fn foo<T: Trait<u32>>(t: T) {} 230 fn foo<T: Trait<u32>>(t: T) {}
231fn test() { 231 fn test() {
232 let s = S(unknown); 232 let s = S(unknown);
233 foo(s); 233 foo(s);
234} 234 }
235"#), 235 "#,
236 @r###" 236 expect![[r#"
237 85..86 't': T 237 85..86 't': T
238 91..93 '{}': () 238 91..93 '{}': ()
239 104..143 '{ ...(s); }': () 239 104..143 '{ ...(s); }': ()
240 114..115 's': S<u32> 240 114..115 's': S<u32>
241 118..119 'S': S<u32>(u32) -> S<u32> 241 118..119 'S': S<u32>(u32) -> S<u32>
242 118..128 'S(unknown)': S<u32> 242 118..128 'S(unknown)': S<u32>
243 120..127 'unknown': u32 243 120..127 'unknown': u32
244 134..137 'foo': fn foo<S<u32>>(S<u32>) 244 134..137 'foo': fn foo<S<u32>>(S<u32>)
245 134..140 'foo(s)': () 245 134..140 'foo(s)': ()
246 138..139 's': S<u32> 246 138..139 's': S<u32>
247 "### 247 "#]],
248 ); 248 );
249} 249}
250 250
251#[test] 251#[test]
252fn infer_from_bound_2() { 252fn infer_from_bound_2() {
253 assert_snapshot!( 253 check_infer(
254 infer(r#" 254 r#"
255trait Trait<T> {} 255 trait Trait<T> {}
256struct S<T>(T); 256 struct S<T>(T);
257impl<U> Trait<U> for S<U> {} 257 impl<U> Trait<U> for S<U> {}
258fn foo<U, T: Trait<U>>(t: T) -> U {} 258 fn foo<U, T: Trait<U>>(t: T) -> U {}
259fn test() { 259 fn test() {
260 let s = S(unknown); 260 let s = S(unknown);
261 let x: u32 = foo(s); 261 let x: u32 = foo(s);
262} 262 }
263"#), 263 "#,
264 @r###" 264 expect![[r#"
265 86..87 't': T 265 86..87 't': T
266 97..99 '{}': () 266 97..99 '{}': ()
267 110..162 '{ ...(s); }': () 267 110..162 '{ ...(s); }': ()
268 120..121 's': S<u32> 268 120..121 's': S<u32>
269 124..125 'S': S<u32>(u32) -> S<u32> 269 124..125 'S': S<u32>(u32) -> S<u32>
270 124..134 'S(unknown)': S<u32> 270 124..134 'S(unknown)': S<u32>
271 126..133 'unknown': u32 271 126..133 'unknown': u32
272 144..145 'x': u32 272 144..145 'x': u32
273 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 273 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32
274 153..159 'foo(s)': u32 274 153..159 'foo(s)': u32
275 157..158 's': S<u32> 275 157..158 's': S<u32>
276 "### 276 "#]],
277 ); 277 );
278} 278}
279 279
280#[test] 280#[test]
281fn trait_default_method_self_bound_implements_trait() { 281fn trait_default_method_self_bound_implements_trait() {
282 mark::check!(trait_self_implements_self); 282 mark::check!(trait_self_implements_self);
283 assert_snapshot!( 283 check_infer(
284 infer(r#" 284 r#"
285trait Trait { 285 trait Trait {
286 fn foo(&self) -> i64; 286 fn foo(&self) -> i64;
287 fn bar(&self) -> { 287 fn bar(&self) -> {
288 let x = self.foo(); 288 let x = self.foo();
289 } 289 }
290} 290 }
291"#), 291 "#,
292 @r###" 292 expect![[r#"
293 26..30 'self': &Self 293 26..30 'self': &Self
294 52..56 'self': &Self 294 52..56 'self': &Self
295 61..96 '{ ... }': () 295 61..96 '{ ... }': ()
296 75..76 'x': i64 296 75..76 'x': i64
297 79..83 'self': &Self 297 79..83 'self': &Self
298 79..89 'self.foo()': i64 298 79..89 'self.foo()': i64
299 "### 299 "#]],
300 ); 300 );
301} 301}
302 302
303#[test] 303#[test]
304fn trait_default_method_self_bound_implements_super_trait() { 304fn trait_default_method_self_bound_implements_super_trait() {
305 assert_snapshot!( 305 check_infer(
306 infer(r#" 306 r#"
307trait SuperTrait { 307 trait SuperTrait {
308 fn foo(&self) -> i64; 308 fn foo(&self) -> i64;
309} 309 }
310trait Trait: SuperTrait { 310 trait Trait: SuperTrait {
311 fn bar(&self) -> { 311 fn bar(&self) -> {
312 let x = self.foo(); 312 let x = self.foo();
313 } 313 }
314} 314 }
315"#), 315 "#,
316 @r###" 316 expect![[r#"
317 31..35 'self': &Self 317 31..35 'self': &Self
318 85..89 'self': &Self 318 85..89 'self': &Self
319 94..129 '{ ... }': () 319 94..129 '{ ... }': ()
320 108..109 'x': i64 320 108..109 'x': i64
321 112..116 'self': &Self 321 112..116 'self': &Self
322 112..122 'self.foo()': i64 322 112..122 'self.foo()': i64
323 "### 323 "#]],
324 ); 324 );
325} 325}
326 326
327#[test] 327#[test]
328fn infer_project_associated_type() { 328fn infer_project_associated_type() {
329 assert_snapshot!( 329 check_infer(
330 infer(r#" 330 r#"
331trait Iterable { 331 trait Iterable {
332 type Item; 332 type Item;
333} 333 }
334struct S; 334 struct S;
335impl Iterable for S { type Item = u32; } 335 impl Iterable for S { type Item = u32; }
336fn test<T: Iterable>() { 336 fn test<T: Iterable>() {
337 let x: <S as Iterable>::Item = 1; 337 let x: <S as Iterable>::Item = 1;
338 let y: <T as Iterable>::Item = no_matter; 338 let y: <T as Iterable>::Item = no_matter;
339 let z: T::Item = no_matter; 339 let z: T::Item = no_matter;
340 let a: <T>::Item = no_matter; 340 let a: <T>::Item = no_matter;
341} 341 }
342"#), 342 "#,
343 @r###" 343 expect![[r#"
344 107..260 '{ ...ter; }': () 344 108..261 '{ ...ter; }': ()
345 117..118 'x': u32 345 118..119 'x': u32
346 144..145 '1': u32 346 145..146 '1': u32
347 155..156 'y': Iterable::Item<T> 347 156..157 'y': Iterable::Item<T>
348 182..191 'no_matter': Iterable::Item<T> 348 183..192 'no_matter': Iterable::Item<T>
349 201..202 'z': Iterable::Item<T> 349 202..203 'z': Iterable::Item<T>
350 214..223 'no_matter': Iterable::Item<T> 350 215..224 'no_matter': Iterable::Item<T>
351 233..234 'a': Iterable::Item<T> 351 234..235 'a': Iterable::Item<T>
352 248..257 'no_matter': Iterable::Item<T> 352 249..258 'no_matter': Iterable::Item<T>
353 "### 353 "#]],
354 ); 354 );
355} 355}
356 356
357#[test] 357#[test]
358fn infer_return_associated_type() { 358fn infer_return_associated_type() {
359 assert_snapshot!( 359 check_infer(
360 infer(r#" 360 r#"
361trait Iterable { 361 trait Iterable {
362 type Item; 362 type Item;
363} 363 }
364struct S; 364 struct S;
365impl Iterable for S { type Item = u32; } 365 impl Iterable for S { type Item = u32; }
366fn foo1<T: Iterable>(t: T) -> T::Item {} 366 fn foo1<T: Iterable>(t: T) -> T::Item {}
367fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} 367 fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {}
368fn foo3<T: Iterable>(t: T) -> <T>::Item {} 368 fn foo3<T: Iterable>(t: T) -> <T>::Item {}
369fn test() { 369 fn test() {
370 let x = foo1(S); 370 let x = foo1(S);
371 let y = foo2(S); 371 let y = foo2(S);
372 let z = foo3(S); 372 let z = foo3(S);
373} 373 }
374"#), 374 "#,
375 @r###" 375 expect![[r#"
376 105..106 't': T 376 106..107 't': T
377 122..124 '{}': () 377 123..125 '{}': ()
378 146..147 't': T 378 147..148 't': T
379 177..179 '{}': () 379 178..180 '{}': ()
380 201..202 't': T 380 202..203 't': T
381 220..222 '{}': () 381 221..223 '{}': ()
382 233..299 '{ ...(S); }': () 382 234..300 '{ ...(S); }': ()
383 243..244 'x': u32 383 244..245 'x': u32
384 247..251 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item 384 248..252 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item
385 247..254 'foo1(S)': u32 385 248..255 'foo1(S)': u32
386 252..253 'S': S 386 253..254 'S': S
387 264..265 'y': u32 387 265..266 'y': u32
388 268..272 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item 388 269..273 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item
389 268..275 'foo2(S)': u32 389 269..276 'foo2(S)': u32
390 273..274 'S': S 390 274..275 'S': S
391 285..286 'z': u32 391 286..287 'z': u32
392 289..293 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item 392 290..294 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item
393 289..296 'foo3(S)': u32 393 290..297 'foo3(S)': u32
394 294..295 'S': S 394 295..296 'S': S
395 "### 395 "#]],
396 ); 396 );
397} 397}
398 398
399#[test] 399#[test]
400fn infer_associated_type_bound() { 400fn infer_associated_type_bound() {
401 assert_snapshot!( 401 check_infer(
402 infer(r#" 402 r#"
403trait Iterable { 403 trait Iterable {
404 type Item; 404 type Item;
405} 405 }
406fn test<T: Iterable<Item=u32>>() { 406 fn test<T: Iterable<Item=u32>>() {
407 let y: T::Item = unknown; 407 let y: T::Item = unknown;
408} 408 }
409"#), 409 "#,
410 @r###" 410 expect![[r#"
411 66..99 '{ ...own; }': () 411 67..100 '{ ...own; }': ()
412 76..77 'y': u32 412 77..78 'y': u32
413 89..96 'unknown': u32 413 90..97 'unknown': u32
414 "### 414 "#]],
415 ); 415 );
416} 416}
417 417
418#[test] 418#[test]
419fn infer_const_body() { 419fn infer_const_body() {
420 assert_snapshot!( 420 check_infer(
421 infer(r#" 421 r#"
422const A: u32 = 1 + 1; 422 const A: u32 = 1 + 1;
423static B: u64 = { let x = 1; x }; 423 static B: u64 = { let x = 1; x };
424"#), 424 "#,
425 @r###" 425 expect![[r#"
426 15..16 '1': u32 426 15..16 '1': u32
427 15..20 '1 + 1': u32 427 15..20 '1 + 1': u32
428 19..20 '1': u32 428 19..20 '1': u32
429 38..54 '{ let ...1; x }': u64 429 38..54 '{ let ...1; x }': u64
430 44..45 'x': u64 430 44..45 'x': u64
431 48..49 '1': u64 431 48..49 '1': u64
432 51..52 'x': u64 432 51..52 'x': u64
433 "### 433 "#]],
434 ); 434 );
435} 435}
436 436
437#[test] 437#[test]
438fn tuple_struct_fields() { 438fn tuple_struct_fields() {
439 assert_snapshot!( 439 check_infer(
440 infer(r#" 440 r#"
441struct S(i32, u64); 441 struct S(i32, u64);
442fn test() -> u64 { 442 fn test() -> u64 {
443 let a = S(4, 6); 443 let a = S(4, 6);
444 let b = a.0; 444 let b = a.0;
445 a.1 445 a.1
446} 446 }
447"#), 447 "#,
448 @r###" 448 expect![[r#"
449 37..86 '{ ... a.1 }': u64 449 37..86 '{ ... a.1 }': u64
450 47..48 'a': S 450 47..48 'a': S
451 51..52 'S': S(i32, u64) -> S 451 51..52 'S': S(i32, u64) -> S
452 51..58 'S(4, 6)': S 452 51..58 'S(4, 6)': S
453 53..54 '4': i32 453 53..54 '4': i32
454 56..57 '6': u64 454 56..57 '6': u64
455 68..69 'b': i32 455 68..69 'b': i32
456 72..73 'a': S 456 72..73 'a': S
457 72..75 'a.0': i32 457 72..75 'a.0': i32
458 81..82 'a': S 458 81..82 'a': S
459 81..84 'a.1': u64 459 81..84 'a.1': u64
460 "### 460 "#]],
461 ); 461 );
462} 462}
463 463
464#[test] 464#[test]
465fn tuple_struct_with_fn() { 465fn tuple_struct_with_fn() {
466 assert_snapshot!( 466 check_infer(
467 infer(r#" 467 r#"
468struct S(fn(u32) -> u64); 468 struct S(fn(u32) -> u64);
469fn test() -> u64 { 469 fn test() -> u64 {
470 let a = S(|i| 2*i); 470 let a = S(|i| 2*i);
471 let b = a.0(4); 471 let b = a.0(4);
472 a.0(2) 472 a.0(2)
473} 473 }
474"#), 474 "#,
475 @r###" 475 expect![[r#"
476 43..101 '{ ...0(2) }': u64 476 43..101 '{ ...0(2) }': u64
477 53..54 'a': S 477 53..54 'a': S
478 57..58 'S': S(fn(u32) -> u64) -> S 478 57..58 'S': S(fn(u32) -> u64) -> S
479 57..67 'S(|i| 2*i)': S 479 57..67 'S(|i| 2*i)': S
480 59..66 '|i| 2*i': |u32| -> u64 480 59..66 '|i| 2*i': |u32| -> u64
481 60..61 'i': u32 481 60..61 'i': u32
482 63..64 '2': u32 482 63..64 '2': u32
483 63..66 '2*i': u32 483 63..66 '2*i': u32
484 65..66 'i': u32 484 65..66 'i': u32
485 77..78 'b': u64 485 77..78 'b': u64
486 81..82 'a': S 486 81..82 'a': S
487 81..84 'a.0': fn(u32) -> u64 487 81..84 'a.0': fn(u32) -> u64
488 81..87 'a.0(4)': u64 488 81..87 'a.0(4)': u64
489 85..86 '4': u32 489 85..86 '4': u32
490 93..94 'a': S 490 93..94 'a': S
491 93..96 'a.0': fn(u32) -> u64 491 93..96 'a.0': fn(u32) -> u64
492 93..99 'a.0(2)': u64 492 93..99 'a.0(2)': u64
493 97..98 '2': u32 493 97..98 '2': u32
494 "### 494 "#]],
495 ); 495 );
496} 496}
497 497
498#[test] 498#[test]
499fn indexing_arrays() { 499fn indexing_arrays() {
500 assert_snapshot!( 500 check_infer(
501 infer("fn main() { &mut [9][2]; }"), 501 "fn main() { &mut [9][2]; }",
502 @r###" 502 expect![[r#"
503 10..26 '{ &mut...[2]; }': () 503 10..26 '{ &mut...[2]; }': ()
504 12..23 '&mut [9][2]': &mut {unknown} 504 12..23 '&mut [9][2]': &mut {unknown}
505 17..20 '[9]': [i32; _] 505 17..20 '[9]': [i32; _]
506 17..23 '[9][2]': {unknown} 506 17..23 '[9][2]': {unknown}
507 18..19 '9': i32 507 18..19 '9': i32
508 21..22 '2': i32 508 21..22 '2': i32
509 "### 509 "#]],
510 ) 510 )
511} 511}
512 512
@@ -908,476 +908,475 @@ fn test<T: ApplyL>(t: T) {
908 908
909#[test] 909#[test]
910fn argument_impl_trait() { 910fn argument_impl_trait() {
911 assert_snapshot!( 911 check_infer_with_mismatches(
912 infer_with_mismatches(r#" 912 r#"
913trait Trait<T> { 913 trait Trait<T> {
914 fn foo(&self) -> T; 914 fn foo(&self) -> T;
915 fn foo2(&self) -> i64; 915 fn foo2(&self) -> i64;
916} 916 }
917fn bar(x: impl Trait<u16>) {} 917 fn bar(x: impl Trait<u16>) {}
918struct S<T>(T); 918 struct S<T>(T);
919impl<T> Trait<T> for S<T> {} 919 impl<T> Trait<T> for S<T> {}
920 920
921fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { 921 fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
922 x; 922 x;
923 y; 923 y;
924 let z = S(1); 924 let z = S(1);
925 bar(z); 925 bar(z);
926 x.foo(); 926 x.foo();
927 y.foo(); 927 y.foo();
928 z.foo(); 928 z.foo();
929 x.foo2(); 929 x.foo2();
930 y.foo2(); 930 y.foo2();
931 z.foo2(); 931 z.foo2();
932} 932 }
933"#, true), 933 "#,
934 @r###" 934 expect![[r#"
935 29..33 'self': &Self 935 29..33 'self': &Self
936 54..58 'self': &Self 936 54..58 'self': &Self
937 77..78 'x': impl Trait<u16> 937 77..78 'x': impl Trait<u16>
938 97..99 '{}': () 938 97..99 '{}': ()
939 154..155 'x': impl Trait<u64> 939 154..155 'x': impl Trait<u64>
940 174..175 'y': &impl Trait<u32> 940 174..175 'y': &impl Trait<u32>
941 195..323 '{ ...2(); }': () 941 195..323 '{ ...2(); }': ()
942 201..202 'x': impl Trait<u64> 942 201..202 'x': impl Trait<u64>
943 208..209 'y': &impl Trait<u32> 943 208..209 'y': &impl Trait<u32>
944 219..220 'z': S<u16> 944 219..220 'z': S<u16>
945 223..224 'S': S<u16>(u16) -> S<u16> 945 223..224 'S': S<u16>(u16) -> S<u16>
946 223..227 'S(1)': S<u16> 946 223..227 'S(1)': S<u16>
947 225..226 '1': u16 947 225..226 '1': u16
948 233..236 'bar': fn bar(S<u16>) 948 233..236 'bar': fn bar(S<u16>)
949 233..239 'bar(z)': () 949 233..239 'bar(z)': ()
950 237..238 'z': S<u16> 950 237..238 'z': S<u16>
951 245..246 'x': impl Trait<u64> 951 245..246 'x': impl Trait<u64>
952 245..252 'x.foo()': u64 952 245..252 'x.foo()': u64
953 258..259 'y': &impl Trait<u32> 953 258..259 'y': &impl Trait<u32>
954 258..265 'y.foo()': u32 954 258..265 'y.foo()': u32
955 271..272 'z': S<u16> 955 271..272 'z': S<u16>
956 271..278 'z.foo()': u16 956 271..278 'z.foo()': u16
957 284..285 'x': impl Trait<u64> 957 284..285 'x': impl Trait<u64>
958 284..292 'x.foo2()': i64 958 284..292 'x.foo2()': i64
959 298..299 'y': &impl Trait<u32> 959 298..299 'y': &impl Trait<u32>
960 298..306 'y.foo2()': i64 960 298..306 'y.foo2()': i64
961 312..313 'z': S<u16> 961 312..313 'z': S<u16>
962 312..320 'z.foo2()': i64 962 312..320 'z.foo2()': i64
963 "### 963 "#]],
964 ); 964 );
965} 965}
966 966
967#[test] 967#[test]
968fn argument_impl_trait_type_args_1() { 968fn argument_impl_trait_type_args_1() {
969 assert_snapshot!( 969 check_infer_with_mismatches(
970 infer_with_mismatches(r#" 970 r#"
971trait Trait {} 971 trait Trait {}
972trait Foo { 972 trait Foo {
973 // this function has an implicit Self param, an explicit type param, 973 // this function has an implicit Self param, an explicit type param,
974 // and an implicit impl Trait param! 974 // and an implicit impl Trait param!
975 fn bar<T>(x: impl Trait) -> T { loop {} } 975 fn bar<T>(x: impl Trait) -> T { loop {} }
976} 976 }
977fn foo<T>(x: impl Trait) -> T { loop {} } 977 fn foo<T>(x: impl Trait) -> T { loop {} }
978struct S; 978 struct S;
979impl Trait for S {} 979 impl Trait for S {}
980struct F; 980 struct F;
981impl Foo for F {} 981 impl Foo for F {}
982 982
983fn test() { 983 fn test() {
984 Foo::bar(S); 984 Foo::bar(S);
985 <F as Foo>::bar(S); 985 <F as Foo>::bar(S);
986 F::bar(S); 986 F::bar(S);
987 Foo::bar::<u32>(S); 987 Foo::bar::<u32>(S);
988 <F as Foo>::bar::<u32>(S); 988 <F as Foo>::bar::<u32>(S);
989 989
990 foo(S); 990 foo(S);
991 foo::<u32>(S); 991 foo::<u32>(S);
992 foo::<u32, i32>(S); // we should ignore the extraneous i32 992 foo::<u32, i32>(S); // we should ignore the extraneous i32
993} 993 }
994"#, true), 994 "#,
995 @r###" 995 expect![[r#"
996 155..156 'x': impl Trait 996 155..156 'x': impl Trait
997 175..186 '{ loop {} }': T 997 175..186 '{ loop {} }': T
998 177..184 'loop {}': ! 998 177..184 'loop {}': !
999 182..184 '{}': () 999 182..184 '{}': ()
1000 199..200 'x': impl Trait 1000 199..200 'x': impl Trait
1001 219..230 '{ loop {} }': T 1001 219..230 '{ loop {} }': T
1002 221..228 'loop {}': ! 1002 221..228 'loop {}': !
1003 226..228 '{}': () 1003 226..228 '{}': ()
1004 300..509 '{ ... i32 }': () 1004 300..509 '{ ... i32 }': ()
1005 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} 1005 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown}
1006 306..317 'Foo::bar(S)': {unknown} 1006 306..317 'Foo::bar(S)': {unknown}
1007 315..316 'S': S 1007 315..316 'S': S
1008 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} 1008 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown}
1009 323..341 '<F as ...bar(S)': {unknown} 1009 323..341 '<F as ...bar(S)': {unknown}
1010 339..340 'S': S 1010 339..340 'S': S
1011 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} 1011 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown}
1012 347..356 'F::bar(S)': {unknown} 1012 347..356 'F::bar(S)': {unknown}
1013 354..355 'S': S 1013 354..355 'S': S
1014 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 1014 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32
1015 362..380 'Foo::b...32>(S)': u32 1015 362..380 'Foo::b...32>(S)': u32
1016 378..379 'S': S 1016 378..379 'S': S
1017 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 1017 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32
1018 386..411 '<F as ...32>(S)': u32 1018 386..411 '<F as ...32>(S)': u32
1019 409..410 'S': S 1019 409..410 'S': S
1020 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} 1020 418..421 'foo': fn foo<{unknown}>(S) -> {unknown}
1021 418..424 'foo(S)': {unknown} 1021 418..424 'foo(S)': {unknown}
1022 422..423 'S': S 1022 422..423 'S': S
1023 430..440 'foo::<u32>': fn foo<u32>(S) -> u32 1023 430..440 'foo::<u32>': fn foo<u32>(S) -> u32
1024 430..443 'foo::<u32>(S)': u32 1024 430..443 'foo::<u32>(S)': u32
1025 441..442 'S': S 1025 441..442 'S': S
1026 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32 1026 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32
1027 449..467 'foo::<...32>(S)': u32 1027 449..467 'foo::<...32>(S)': u32
1028 465..466 'S': S 1028 465..466 'S': S
1029 "### 1029 "#]],
1030 ); 1030 );
1031} 1031}
1032 1032
1033#[test] 1033#[test]
1034fn argument_impl_trait_type_args_2() { 1034fn argument_impl_trait_type_args_2() {
1035 assert_snapshot!( 1035 check_infer_with_mismatches(
1036 infer_with_mismatches(r#" 1036 r#"
1037trait Trait {} 1037 trait Trait {}
1038struct S; 1038 struct S;
1039impl Trait for S {} 1039 impl Trait for S {}
1040struct F<T>; 1040 struct F<T>;
1041impl<T> F<T> { 1041 impl<T> F<T> {
1042 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } 1042 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
1043} 1043 }
1044 1044
1045fn test() { 1045 fn test() {
1046 F.foo(S); 1046 F.foo(S);
1047 F::<u32>.foo(S); 1047 F::<u32>.foo(S);
1048 F::<u32>.foo::<i32>(S); 1048 F::<u32>.foo::<i32>(S);
1049 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored 1049 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
1050} 1050 }
1051"#, true), 1051 "#,
1052 @r###" 1052 expect![[r#"
1053 87..91 'self': F<T> 1053 87..91 'self': F<T>
1054 93..94 'x': impl Trait 1054 93..94 'x': impl Trait
1055 118..129 '{ loop {} }': (T, U) 1055 118..129 '{ loop {} }': (T, U)
1056 120..127 'loop {}': ! 1056 120..127 'loop {}': !
1057 125..127 '{}': () 1057 125..127 '{}': ()
1058 143..283 '{ ...ored }': () 1058 143..283 '{ ...ored }': ()
1059 149..150 'F': F<{unknown}> 1059 149..150 'F': F<{unknown}>
1060 149..157 'F.foo(S)': ({unknown}, {unknown}) 1060 149..157 'F.foo(S)': ({unknown}, {unknown})
1061 155..156 'S': S 1061 155..156 'S': S
1062 163..171 'F::<u32>': F<u32> 1062 163..171 'F::<u32>': F<u32>
1063 163..178 'F::<u32>.foo(S)': (u32, {unknown}) 1063 163..178 'F::<u32>.foo(S)': (u32, {unknown})
1064 176..177 'S': S 1064 176..177 'S': S
1065 184..192 'F::<u32>': F<u32> 1065 184..192 'F::<u32>': F<u32>
1066 184..206 'F::<u3...32>(S)': (u32, i32) 1066 184..206 'F::<u3...32>(S)': (u32, i32)
1067 204..205 'S': S 1067 204..205 'S': S
1068 212..220 'F::<u32>': F<u32> 1068 212..220 'F::<u32>': F<u32>
1069 212..239 'F::<u3...32>(S)': (u32, i32) 1069 212..239 'F::<u3...32>(S)': (u32, i32)
1070 237..238 'S': S 1070 237..238 'S': S
1071 "### 1071 "#]],
1072 ); 1072 );
1073} 1073}
1074 1074
1075#[test] 1075#[test]
1076fn argument_impl_trait_to_fn_pointer() { 1076fn argument_impl_trait_to_fn_pointer() {
1077 assert_snapshot!( 1077 check_infer_with_mismatches(
1078 infer_with_mismatches(r#" 1078 r#"
1079trait Trait {} 1079 trait Trait {}
1080fn foo(x: impl Trait) { loop {} } 1080 fn foo(x: impl Trait) { loop {} }
1081struct S; 1081 struct S;
1082impl Trait for S {} 1082 impl Trait for S {}
1083 1083
1084fn test() { 1084 fn test() {
1085 let f: fn(S) -> () = foo; 1085 let f: fn(S) -> () = foo;
1086} 1086 }
1087"#, true), 1087 "#,
1088 @r###" 1088 expect![[r#"
1089 22..23 'x': impl Trait 1089 22..23 'x': impl Trait
1090 37..48 '{ loop {} }': () 1090 37..48 '{ loop {} }': ()
1091 39..46 'loop {}': ! 1091 39..46 'loop {}': !
1092 44..46 '{}': () 1092 44..46 '{}': ()
1093 90..123 '{ ...foo; }': () 1093 90..123 '{ ...foo; }': ()
1094 100..101 'f': fn(S) 1094 100..101 'f': fn(S)
1095 117..120 'foo': fn foo(S) 1095 117..120 'foo': fn foo(S)
1096 "### 1096 "#]],
1097 ); 1097 );
1098} 1098}
1099 1099
1100#[test] 1100#[test]
1101fn impl_trait() { 1101fn impl_trait() {
1102 assert_snapshot!( 1102 check_infer(
1103 infer(r#" 1103 r#"
1104trait Trait<T> { 1104 trait Trait<T> {
1105 fn foo(&self) -> T; 1105 fn foo(&self) -> T;
1106 fn foo2(&self) -> i64; 1106 fn foo2(&self) -> i64;
1107} 1107 }
1108fn bar() -> impl Trait<u64> {} 1108 fn bar() -> impl Trait<u64> {}
1109 1109
1110fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { 1110 fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
1111 x; 1111 x;
1112 y; 1112 y;
1113 let z = bar(); 1113 let z = bar();
1114 x.foo(); 1114 x.foo();
1115 y.foo(); 1115 y.foo();
1116 z.foo(); 1116 z.foo();
1117 x.foo2(); 1117 x.foo2();
1118 y.foo2(); 1118 y.foo2();
1119 z.foo2(); 1119 z.foo2();
1120} 1120 }
1121"#), 1121 "#,
1122 @r###" 1122 expect![[r#"
1123 29..33 'self': &Self 1123 29..33 'self': &Self
1124 54..58 'self': &Self 1124 54..58 'self': &Self
1125 98..100 '{}': () 1125 98..100 '{}': ()
1126 110..111 'x': impl Trait<u64> 1126 110..111 'x': impl Trait<u64>
1127 130..131 'y': &impl Trait<u64> 1127 130..131 'y': &impl Trait<u64>
1128 151..268 '{ ...2(); }': () 1128 151..268 '{ ...2(); }': ()
1129 157..158 'x': impl Trait<u64> 1129 157..158 'x': impl Trait<u64>
1130 164..165 'y': &impl Trait<u64> 1130 164..165 'y': &impl Trait<u64>
1131 175..176 'z': impl Trait<u64> 1131 175..176 'z': impl Trait<u64>
1132 179..182 'bar': fn bar() -> impl Trait<u64> 1132 179..182 'bar': fn bar() -> impl Trait<u64>
1133 179..184 'bar()': impl Trait<u64> 1133 179..184 'bar()': impl Trait<u64>
1134 190..191 'x': impl Trait<u64> 1134 190..191 'x': impl Trait<u64>
1135 190..197 'x.foo()': u64 1135 190..197 'x.foo()': u64
1136 203..204 'y': &impl Trait<u64> 1136 203..204 'y': &impl Trait<u64>
1137 203..210 'y.foo()': u64 1137 203..210 'y.foo()': u64
1138 216..217 'z': impl Trait<u64> 1138 216..217 'z': impl Trait<u64>
1139 216..223 'z.foo()': u64 1139 216..223 'z.foo()': u64
1140 229..230 'x': impl Trait<u64> 1140 229..230 'x': impl Trait<u64>
1141 229..237 'x.foo2()': i64 1141 229..237 'x.foo2()': i64
1142 243..244 'y': &impl Trait<u64> 1142 243..244 'y': &impl Trait<u64>
1143 243..251 'y.foo2()': i64 1143 243..251 'y.foo2()': i64
1144 257..258 'z': impl Trait<u64> 1144 257..258 'z': impl Trait<u64>
1145 257..265 'z.foo2()': i64 1145 257..265 'z.foo2()': i64
1146 "### 1146 "#]],
1147 ); 1147 );
1148} 1148}
1149 1149
1150#[test] 1150#[test]
1151fn simple_return_pos_impl_trait() { 1151fn simple_return_pos_impl_trait() {
1152 mark::check!(lower_rpit); 1152 mark::check!(lower_rpit);
1153 assert_snapshot!( 1153 check_infer(
1154 infer(r#" 1154 r#"
1155trait Trait<T> { 1155 trait Trait<T> {
1156 fn foo(&self) -> T; 1156 fn foo(&self) -> T;
1157} 1157 }
1158fn bar() -> impl Trait<u64> { loop {} } 1158 fn bar() -> impl Trait<u64> { loop {} }
1159 1159
1160fn test() { 1160 fn test() {
1161 let a = bar(); 1161 let a = bar();
1162 a.foo(); 1162 a.foo();
1163} 1163 }
1164"#), 1164 "#,
1165 @r###" 1165 expect![[r#"
1166 29..33 'self': &Self 1166 29..33 'self': &Self
1167 71..82 '{ loop {} }': ! 1167 71..82 '{ loop {} }': !
1168 73..80 'loop {}': ! 1168 73..80 'loop {}': !
1169 78..80 '{}': () 1169 78..80 '{}': ()
1170 94..129 '{ ...o(); }': () 1170 94..129 '{ ...o(); }': ()
1171 104..105 'a': impl Trait<u64> 1171 104..105 'a': impl Trait<u64>
1172 108..111 'bar': fn bar() -> impl Trait<u64> 1172 108..111 'bar': fn bar() -> impl Trait<u64>
1173 108..113 'bar()': impl Trait<u64> 1173 108..113 'bar()': impl Trait<u64>
1174 119..120 'a': impl Trait<u64> 1174 119..120 'a': impl Trait<u64>
1175 119..126 'a.foo()': u64 1175 119..126 'a.foo()': u64
1176 "### 1176 "#]],
1177 ); 1177 );
1178} 1178}
1179 1179
1180#[test] 1180#[test]
1181fn more_return_pos_impl_trait() { 1181fn more_return_pos_impl_trait() {
1182 assert_snapshot!( 1182 check_infer(
1183 infer(r#" 1183 r#"
1184trait Iterator { 1184 trait Iterator {
1185 type Item; 1185 type Item;
1186 fn next(&mut self) -> Self::Item; 1186 fn next(&mut self) -> Self::Item;
1187} 1187 }
1188trait Trait<T> { 1188 trait Trait<T> {
1189 fn foo(&self) -> T; 1189 fn foo(&self) -> T;
1190} 1190 }
1191fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } 1191 fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
1192fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } 1192 fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
1193 1193
1194fn test() { 1194 fn test() {
1195 let (a, b) = bar(); 1195 let (a, b) = bar();
1196 a.next().foo(); 1196 a.next().foo();
1197 b.foo(); 1197 b.foo();
1198 let (c, d) = baz(1u128); 1198 let (c, d) = baz(1u128);
1199 c.next().foo(); 1199 c.next().foo();
1200 d.foo(); 1200 d.foo();
1201} 1201 }
1202"#), 1202 "#,
1203 @r###" 1203 expect![[r#"
1204 49..53 'self': &mut Self 1204 49..53 'self': &mut Self
1205 101..105 'self': &Self 1205 101..105 'self': &Self
1206 184..195 '{ loop {} }': ({unknown}, {unknown}) 1206 184..195 '{ loop {} }': ({unknown}, {unknown})
1207 186..193 'loop {}': ! 1207 186..193 'loop {}': !
1208 191..193 '{}': () 1208 191..193 '{}': ()
1209 206..207 't': T 1209 206..207 't': T
1210 268..279 '{ loop {} }': ({unknown}, {unknown}) 1210 268..279 '{ loop {} }': ({unknown}, {unknown})
1211 270..277 'loop {}': ! 1211 270..277 'loop {}': !
1212 275..277 '{}': () 1212 275..277 '{}': ()
1213 291..413 '{ ...o(); }': () 1213 291..413 '{ ...o(); }': ()
1214 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) 1214 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1215 302..303 'a': impl Iterator<Item = impl Trait<u32>> 1215 302..303 'a': impl Iterator<Item = impl Trait<u32>>
1216 305..306 'b': impl Trait<u64> 1216 305..306 'b': impl Trait<u64>
1217 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) 1217 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1218 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) 1218 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1219 321..322 'a': impl Iterator<Item = impl Trait<u32>> 1219 321..322 'a': impl Iterator<Item = impl Trait<u32>>
1220 321..329 'a.next()': impl Trait<u32> 1220 321..329 'a.next()': impl Trait<u32>
1221 321..335 'a.next().foo()': u32 1221 321..335 'a.next().foo()': u32
1222 341..342 'b': impl Trait<u64> 1222 341..342 'b': impl Trait<u64>
1223 341..348 'b.foo()': u64 1223 341..348 'b.foo()': u64
1224 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) 1224 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1225 359..360 'c': impl Iterator<Item = impl Trait<u128>> 1225 359..360 'c': impl Iterator<Item = impl Trait<u128>>
1226 362..363 'd': impl Trait<u128> 1226 362..363 'd': impl Trait<u128>
1227 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) 1227 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1228 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) 1228 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1229 371..376 '1u128': u128 1229 371..376 '1u128': u128
1230 383..384 'c': impl Iterator<Item = impl Trait<u128>> 1230 383..384 'c': impl Iterator<Item = impl Trait<u128>>
1231 383..391 'c.next()': impl Trait<u128> 1231 383..391 'c.next()': impl Trait<u128>
1232 383..397 'c.next().foo()': u128 1232 383..397 'c.next().foo()': u128
1233 403..404 'd': impl Trait<u128> 1233 403..404 'd': impl Trait<u128>
1234 403..410 'd.foo()': u128 1234 403..410 'd.foo()': u128
1235 "### 1235 "#]],
1236 ); 1236 );
1237} 1237}
1238 1238
1239#[test] 1239#[test]
1240fn dyn_trait() { 1240fn dyn_trait() {
1241 assert_snapshot!( 1241 check_infer(
1242 infer(r#" 1242 r#"
1243trait Trait<T> { 1243 trait Trait<T> {
1244 fn foo(&self) -> T; 1244 fn foo(&self) -> T;
1245 fn foo2(&self) -> i64; 1245 fn foo2(&self) -> i64;
1246} 1246 }
1247fn bar() -> dyn Trait<u64> {} 1247 fn bar() -> dyn Trait<u64> {}
1248 1248
1249fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { 1249 fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
1250 x; 1250 x;
1251 y; 1251 y;
1252 let z = bar(); 1252 let z = bar();
1253 x.foo(); 1253 x.foo();
1254 y.foo(); 1254 y.foo();
1255 z.foo(); 1255 z.foo();
1256 x.foo2(); 1256 x.foo2();
1257 y.foo2(); 1257 y.foo2();
1258 z.foo2(); 1258 z.foo2();
1259} 1259 }
1260"#), 1260 "#,
1261 @r###" 1261 expect![[r#"
1262 29..33 'self': &Self 1262 29..33 'self': &Self
1263 54..58 'self': &Self 1263 54..58 'self': &Self
1264 97..99 '{}': () 1264 97..99 '{}': ()
1265 109..110 'x': dyn Trait<u64> 1265 109..110 'x': dyn Trait<u64>
1266 128..129 'y': &dyn Trait<u64> 1266 128..129 'y': &dyn Trait<u64>
1267 148..265 '{ ...2(); }': () 1267 148..265 '{ ...2(); }': ()
1268 154..155 'x': dyn Trait<u64> 1268 154..155 'x': dyn Trait<u64>
1269 161..162 'y': &dyn Trait<u64> 1269 161..162 'y': &dyn Trait<u64>
1270 172..173 'z': dyn Trait<u64> 1270 172..173 'z': dyn Trait<u64>
1271 176..179 'bar': fn bar() -> dyn Trait<u64> 1271 176..179 'bar': fn bar() -> dyn Trait<u64>
1272 176..181 'bar()': dyn Trait<u64> 1272 176..181 'bar()': dyn Trait<u64>
1273 187..188 'x': dyn Trait<u64> 1273 187..188 'x': dyn Trait<u64>
1274 187..194 'x.foo()': u64 1274 187..194 'x.foo()': u64
1275 200..201 'y': &dyn Trait<u64> 1275 200..201 'y': &dyn Trait<u64>
1276 200..207 'y.foo()': u64 1276 200..207 'y.foo()': u64
1277 213..214 'z': dyn Trait<u64> 1277 213..214 'z': dyn Trait<u64>
1278 213..220 'z.foo()': u64 1278 213..220 'z.foo()': u64
1279 226..227 'x': dyn Trait<u64> 1279 226..227 'x': dyn Trait<u64>
1280 226..234 'x.foo2()': i64 1280 226..234 'x.foo2()': i64
1281 240..241 'y': &dyn Trait<u64> 1281 240..241 'y': &dyn Trait<u64>
1282 240..248 'y.foo2()': i64 1282 240..248 'y.foo2()': i64
1283 254..255 'z': dyn Trait<u64> 1283 254..255 'z': dyn Trait<u64>
1284 254..262 'z.foo2()': i64 1284 254..262 'z.foo2()': i64
1285 "### 1285 "#]],
1286 ); 1286 );
1287} 1287}
1288 1288
1289#[test] 1289#[test]
1290fn dyn_trait_in_impl() { 1290fn dyn_trait_in_impl() {
1291 assert_snapshot!( 1291 check_infer(
1292 infer(r#" 1292 r#"
1293trait Trait<T, U> { 1293 trait Trait<T, U> {
1294 fn foo(&self) -> (T, U); 1294 fn foo(&self) -> (T, U);
1295} 1295 }
1296struct S<T, U> {} 1296 struct S<T, U> {}
1297impl<T, U> S<T, U> { 1297 impl<T, U> S<T, U> {
1298 fn bar(&self) -> &dyn Trait<T, U> { loop {} } 1298 fn bar(&self) -> &dyn Trait<T, U> { loop {} }
1299} 1299 }
1300trait Trait2<T, U> { 1300 trait Trait2<T, U> {
1301 fn baz(&self) -> (T, U); 1301 fn baz(&self) -> (T, U);
1302} 1302 }
1303impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } 1303 impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
1304 1304
1305fn test(s: S<u32, i32>) { 1305 fn test(s: S<u32, i32>) {
1306 s.bar().baz(); 1306 s.bar().baz();
1307} 1307 }
1308"#), 1308 "#,
1309 @r###" 1309 expect![[r#"
1310 32..36 'self': &Self 1310 32..36 'self': &Self
1311 102..106 'self': &S<T, U> 1311 102..106 'self': &S<T, U>
1312 128..139 '{ loop {} }': &dyn Trait<T, U> 1312 128..139 '{ loop {} }': &dyn Trait<T, U>
1313 130..137 'loop {}': ! 1313 130..137 'loop {}': !
1314 135..137 '{}': () 1314 135..137 '{}': ()
1315 175..179 'self': &Self 1315 175..179 'self': &Self
1316 251..252 's': S<u32, i32> 1316 251..252 's': S<u32, i32>
1317 267..289 '{ ...z(); }': () 1317 267..289 '{ ...z(); }': ()
1318 273..274 's': S<u32, i32> 1318 273..274 's': S<u32, i32>
1319 273..280 's.bar()': &dyn Trait<u32, i32> 1319 273..280 's.bar()': &dyn Trait<u32, i32>
1320 273..286 's.bar().baz()': (u32, i32) 1320 273..286 's.bar().baz()': (u32, i32)
1321 "### 1321 "#]],
1322 ); 1322 );
1323} 1323}
1324 1324
1325#[test] 1325#[test]
1326fn dyn_trait_bare() { 1326fn dyn_trait_bare() {
1327 assert_snapshot!( 1327 check_infer(
1328 infer(r#" 1328 r#"
1329trait Trait { 1329 trait Trait {
1330 fn foo(&self) -> u64; 1330 fn foo(&self) -> u64;
1331} 1331 }
1332fn bar() -> Trait {} 1332 fn bar() -> Trait {}
1333 1333
1334fn test(x: Trait, y: &Trait) -> u64 { 1334 fn test(x: Trait, y: &Trait) -> u64 {
1335 x; 1335 x;
1336 y; 1336 y;
1337 let z = bar(); 1337 let z = bar();
1338 x.foo(); 1338 x.foo();
1339 y.foo(); 1339 y.foo();
1340 z.foo(); 1340 z.foo();
1341} 1341 }
1342"#), 1342 "#,
1343 @r###" 1343 expect![[r#"
1344 26..30 'self': &Self 1344 26..30 'self': &Self
1345 60..62 '{}': () 1345 60..62 '{}': ()
1346 72..73 'x': dyn Trait 1346 72..73 'x': dyn Trait
1347 82..83 'y': &dyn Trait 1347 82..83 'y': &dyn Trait
1348 100..175 '{ ...o(); }': () 1348 100..175 '{ ...o(); }': ()
1349 106..107 'x': dyn Trait 1349 106..107 'x': dyn Trait
1350 113..114 'y': &dyn Trait 1350 113..114 'y': &dyn Trait
1351 124..125 'z': dyn Trait 1351 124..125 'z': dyn Trait
1352 128..131 'bar': fn bar() -> dyn Trait 1352 128..131 'bar': fn bar() -> dyn Trait
1353 128..133 'bar()': dyn Trait 1353 128..133 'bar()': dyn Trait
1354 139..140 'x': dyn Trait 1354 139..140 'x': dyn Trait
1355 139..146 'x.foo()': u64 1355 139..146 'x.foo()': u64
1356 152..153 'y': &dyn Trait 1356 152..153 'y': &dyn Trait
1357 152..159 'y.foo()': u64 1357 152..159 'y.foo()': u64
1358 165..166 'z': dyn Trait 1358 165..166 'z': dyn Trait
1359 165..172 'z.foo()': u64 1359 165..172 'z.foo()': u64
1360 "### 1360 "#]],
1361 ); 1361 );
1362} 1362}
1363 1363
1364#[test] 1364#[test]
1365fn weird_bounds() { 1365fn weird_bounds() {
1366 assert_snapshot!( 1366 check_infer(
1367 infer(r#" 1367 r#"
1368trait Trait {} 1368 trait Trait {}
1369fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { 1369 fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {}
1370} 1370 "#,
1371"#), 1371 expect![[r#"
1372 @r###" 1372 23..24 'a': impl Trait + {error}
1373 23..24 'a': impl Trait + {error} 1373 50..51 'b': impl {error}
1374 50..51 'b': impl {error} 1374 69..70 'c': impl Trait
1375 69..70 'c': impl Trait 1375 86..87 'd': impl {error}
1376 86..87 'd': impl {error} 1376 107..108 'e': impl {error}
1377 107..108 'e': impl {error} 1377 123..124 'f': impl Trait + {error}
1378 123..124 'f': impl Trait + {error} 1378 147..149 '{}': ()
1379 147..150 '{ }': () 1379 "#]],
1380 "###
1381 ); 1380 );
1382} 1381}
1383 1382
@@ -1399,66 +1398,66 @@ fn test(x: (impl Trait + UnknownTrait)) {
1399 1398
1400#[test] 1399#[test]
1401fn assoc_type_bindings() { 1400fn assoc_type_bindings() {
1402 assert_snapshot!( 1401 check_infer(
1403 infer(r#" 1402 r#"
1404trait Trait { 1403 trait Trait {
1405 type Type; 1404 type Type;
1406} 1405 }
1407
1408fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
1409fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1410fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1411 1406
1412struct S<T>; 1407 fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
1413impl<T> Trait for S<T> { type Type = T; } 1408 fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1414 1409 fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1415fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { 1410
1416 get(x); 1411 struct S<T>;
1417 get2(x); 1412 impl<T> Trait for S<T> { type Type = T; }
1418 get(y); 1413
1419 get2(y); 1414 fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1420 get(set(S)); 1415 get(x);
1421 get2(set(S)); 1416 get2(x);
1422 get2(S::<str>); 1417 get(y);
1423} 1418 get2(y);
1424"#), 1419 get(set(S));
1425 @r###" 1420 get2(set(S));
1426 49..50 't': T 1421 get2(S::<str>);
1427 77..79 '{}': () 1422 }
1428 111..112 't': T 1423 "#,
1429 122..124 '{}': () 1424 expect![[r#"
1430 154..155 't': T 1425 49..50 't': T
1431 165..168 '{t}': T 1426 77..79 '{}': ()
1432 166..167 't': T 1427 111..112 't': T
1433 256..257 'x': T 1428 122..124 '{}': ()
1434 262..263 'y': impl Trait<Type = i64> 1429 154..155 't': T
1435 289..397 '{ ...r>); }': () 1430 165..168 '{t}': T
1436 295..298 'get': fn get<T>(T) -> <T as Trait>::Type 1431 166..167 't': T
1437 295..301 'get(x)': u32 1432 256..257 'x': T
1438 299..300 'x': T 1433 262..263 'y': impl Trait<Type = i64>
1439 307..311 'get2': fn get2<u32, T>(T) -> u32 1434 289..397 '{ ...r>); }': ()
1440 307..314 'get2(x)': u32 1435 295..298 'get': fn get<T>(T) -> <T as Trait>::Type
1441 312..313 'x': T 1436 295..301 'get(x)': u32
1442 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type 1437 299..300 'x': T
1443 320..326 'get(y)': i64 1438 307..311 'get2': fn get2<u32, T>(T) -> u32
1444 324..325 'y': impl Trait<Type = i64> 1439 307..314 'get2(x)': u32
1445 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 1440 312..313 'x': T
1446 332..339 'get2(y)': i64 1441 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1447 337..338 'y': impl Trait<Type = i64> 1442 320..326 'get(y)': i64
1448 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type 1443 324..325 'y': impl Trait<Type = i64>
1449 345..356 'get(set(S))': u64 1444 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64
1450 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> 1445 332..339 'get2(y)': i64
1451 349..355 'set(S)': S<u64> 1446 337..338 'y': impl Trait<Type = i64>
1452 353..354 'S': S<u64> 1447 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1453 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 1448 345..356 'get(set(S))': u64
1454 362..374 'get2(set(S))': u64 1449 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1455 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> 1450 349..355 'set(S)': S<u64>
1456 367..373 'set(S)': S<u64> 1451 353..354 'S': S<u64>
1457 371..372 'S': S<u64> 1452 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1458 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str 1453 362..374 'get2(set(S))': u64
1459 380..394 'get2(S::<str>)': str 1454 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1460 385..393 'S::<str>': S<str> 1455 367..373 'set(S)': S<u64>
1461 "### 1456 371..372 'S': S<u64>
1457 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str
1458 380..394 'get2(S::<str>)': str
1459 385..393 'S::<str>': S<str>
1460 "#]],
1462 ); 1461 );
1463} 1462}
1464 1463
@@ -1506,27 +1505,27 @@ mod iter {
1506 1505
1507#[test] 1506#[test]
1508fn projection_eq_within_chalk() { 1507fn projection_eq_within_chalk() {
1509 assert_snapshot!( 1508 check_infer(
1510 infer(r#" 1509 r#"
1511trait Trait1 { 1510 trait Trait1 {
1512 type Type; 1511 type Type;
1513} 1512 }
1514trait Trait2<T> { 1513 trait Trait2<T> {
1515 fn foo(self) -> T; 1514 fn foo(self) -> T;
1516} 1515 }
1517impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} 1516 impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
1518 1517
1519fn test<T: Trait1<Type = u32>>(x: T) { 1518 fn test<T: Trait1<Type = u32>>(x: T) {
1520 x.foo(); 1519 x.foo();
1521} 1520 }
1522"#), 1521 "#,
1523 @r###" 1522 expect![[r#"
1524 61..65 'self': Self 1523 61..65 'self': Self
1525 163..164 'x': T 1524 163..164 'x': T
1526 169..185 '{ ...o(); }': () 1525 169..185 '{ ...o(); }': ()
1527 175..176 'x': T 1526 175..176 'x': T
1528 175..182 'x.foo()': u32 1527 175..182 'x.foo()': u32
1529 "### 1528 "#]],
1530 ); 1529 );
1531} 1530}
1532 1531
@@ -1549,445 +1548,445 @@ fn test<T: foo::Trait>(x: T) {
1549 1548
1550#[test] 1549#[test]
1551fn super_trait_method_resolution() { 1550fn super_trait_method_resolution() {
1552 assert_snapshot!( 1551 check_infer(
1553 infer(r#" 1552 r#"
1554mod foo { 1553 mod foo {
1555 trait SuperTrait { 1554 trait SuperTrait {
1556 fn foo(&self) -> u32 {} 1555 fn foo(&self) -> u32 {}
1557 } 1556 }
1558} 1557 }
1559trait Trait1: foo::SuperTrait {} 1558 trait Trait1: foo::SuperTrait {}
1560trait Trait2 where Self: foo::SuperTrait {} 1559 trait Trait2 where Self: foo::SuperTrait {}
1561 1560
1562fn test<T: Trait1, U: Trait2>(x: T, y: U) { 1561 fn test<T: Trait1, U: Trait2>(x: T, y: U) {
1563 x.foo(); 1562 x.foo();
1564 y.foo(); 1563 y.foo();
1565} 1564 }
1566"#), 1565 "#,
1567 @r###" 1566 expect![[r#"
1568 49..53 'self': &Self 1567 49..53 'self': &Self
1569 62..64 '{}': () 1568 62..64 '{}': ()
1570 181..182 'x': T 1569 181..182 'x': T
1571 187..188 'y': U 1570 187..188 'y': U
1572 193..222 '{ ...o(); }': () 1571 193..222 '{ ...o(); }': ()
1573 199..200 'x': T 1572 199..200 'x': T
1574 199..206 'x.foo()': u32 1573 199..206 'x.foo()': u32
1575 212..213 'y': U 1574 212..213 'y': U
1576 212..219 'y.foo()': u32 1575 212..219 'y.foo()': u32
1577 "### 1576 "#]],
1578 ); 1577 );
1579} 1578}
1580 1579
1581#[test] 1580#[test]
1582fn super_trait_impl_trait_method_resolution() { 1581fn super_trait_impl_trait_method_resolution() {
1583 assert_snapshot!( 1582 check_infer(
1584 infer(r#" 1583 r#"
1585mod foo { 1584 mod foo {
1586 trait SuperTrait { 1585 trait SuperTrait {
1587 fn foo(&self) -> u32 {} 1586 fn foo(&self) -> u32 {}
1588 } 1587 }
1589} 1588 }
1590trait Trait1: foo::SuperTrait {} 1589 trait Trait1: foo::SuperTrait {}
1591 1590
1592fn test(x: &impl Trait1) { 1591 fn test(x: &impl Trait1) {
1593 x.foo(); 1592 x.foo();
1594} 1593 }
1595"#), 1594 "#,
1596 @r###" 1595 expect![[r#"
1597 49..53 'self': &Self 1596 49..53 'self': &Self
1598 62..64 '{}': () 1597 62..64 '{}': ()
1599 115..116 'x': &impl Trait1 1598 115..116 'x': &impl Trait1
1600 132..148 '{ ...o(); }': () 1599 132..148 '{ ...o(); }': ()
1601 138..139 'x': &impl Trait1 1600 138..139 'x': &impl Trait1
1602 138..145 'x.foo()': u32 1601 138..145 'x.foo()': u32
1603 "### 1602 "#]],
1604 ); 1603 );
1605} 1604}
1606 1605
1607#[test] 1606#[test]
1608fn super_trait_cycle() { 1607fn super_trait_cycle() {
1609 // This just needs to not crash 1608 // This just needs to not crash
1610 assert_snapshot!( 1609 check_infer(
1611 infer(r#" 1610 r#"
1612trait A: B {} 1611 trait A: B {}
1613trait B: A {} 1612 trait B: A {}
1614 1613
1615fn test<T: A>(x: T) { 1614 fn test<T: A>(x: T) {
1616 x.foo(); 1615 x.foo();
1617} 1616 }
1618"#), 1617 "#,
1619 @r###" 1618 expect![[r#"
1620 43..44 'x': T 1619 43..44 'x': T
1621 49..65 '{ ...o(); }': () 1620 49..65 '{ ...o(); }': ()
1622 55..56 'x': T 1621 55..56 'x': T
1623 55..62 'x.foo()': {unknown} 1622 55..62 'x.foo()': {unknown}
1624 "### 1623 "#]],
1625 ); 1624 );
1626} 1625}
1627 1626
1628#[test] 1627#[test]
1629fn super_trait_assoc_type_bounds() { 1628fn super_trait_assoc_type_bounds() {
1630 assert_snapshot!( 1629 check_infer(
1631 infer(r#" 1630 r#"
1632trait SuperTrait { type Type; } 1631 trait SuperTrait { type Type; }
1633trait Trait where Self: SuperTrait {} 1632 trait Trait where Self: SuperTrait {}
1634 1633
1635fn get2<U, T: Trait<Type = U>>(t: T) -> U {} 1634 fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1636fn set<T: Trait<Type = u64>>(t: T) -> T {t} 1635 fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1637 1636
1638struct S<T>; 1637 struct S<T>;
1639impl<T> SuperTrait for S<T> { type Type = T; } 1638 impl<T> SuperTrait for S<T> { type Type = T; }
1640impl<T> Trait for S<T> {} 1639 impl<T> Trait for S<T> {}
1641 1640
1642fn test() { 1641 fn test() {
1643 get2(set(S)); 1642 get2(set(S));
1644} 1643 }
1645"#), 1644 "#,
1646 @r###" 1645 expect![[r#"
1647 102..103 't': T 1646 102..103 't': T
1648 113..115 '{}': () 1647 113..115 '{}': ()
1649 145..146 't': T 1648 145..146 't': T
1650 156..159 '{t}': T 1649 156..159 '{t}': T
1651 157..158 't': T 1650 157..158 't': T
1652 258..279 '{ ...S)); }': () 1651 258..279 '{ ...S)); }': ()
1653 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 1652 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1654 264..276 'get2(set(S))': u64 1653 264..276 'get2(set(S))': u64
1655 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> 1654 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1656 269..275 'set(S)': S<u64> 1655 269..275 'set(S)': S<u64>
1657 273..274 'S': S<u64> 1656 273..274 'S': S<u64>
1658 "### 1657 "#]],
1659 ); 1658 );
1660} 1659}
1661 1660
1662#[test] 1661#[test]
1663fn fn_trait() { 1662fn fn_trait() {
1664 assert_snapshot!( 1663 check_infer(
1665 infer(r#" 1664 r#"
1666trait FnOnce<Args> { 1665 trait FnOnce<Args> {
1667 type Output; 1666 type Output;
1668 1667
1669 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; 1668 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
1670} 1669 }
1671 1670
1672fn test<F: FnOnce(u32, u64) -> u128>(f: F) { 1671 fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1673 f.call_once((1, 2)); 1672 f.call_once((1, 2));
1674} 1673 }
1675"#), 1674 "#,
1676 @r###" 1675 expect![[r#"
1677 56..60 'self': Self 1676 56..60 'self': Self
1678 62..66 'args': Args 1677 62..66 'args': Args
1679 149..150 'f': F 1678 149..150 'f': F
1680 155..183 '{ ...2)); }': () 1679 155..183 '{ ...2)); }': ()
1681 161..162 'f': F 1680 161..162 'f': F
1682 161..180 'f.call...1, 2))': u128 1681 161..180 'f.call...1, 2))': u128
1683 173..179 '(1, 2)': (u32, u64) 1682 173..179 '(1, 2)': (u32, u64)
1684 174..175 '1': u32 1683 174..175 '1': u32
1685 177..178 '2': u64 1684 177..178 '2': u64
1686 "### 1685 "#]],
1687 ); 1686 );
1688} 1687}
1689 1688
1690#[test] 1689#[test]
1691fn fn_ptr_and_item() { 1690fn fn_ptr_and_item() {
1692 assert_snapshot!( 1691 check_infer(
1693 infer(r#" 1692 r#"
1694#[lang="fn_once"] 1693 #[lang="fn_once"]
1695trait FnOnce<Args> { 1694 trait FnOnce<Args> {
1696 type Output; 1695 type Output;
1697 1696
1698 fn call_once(self, args: Args) -> Self::Output; 1697 fn call_once(self, args: Args) -> Self::Output;
1699} 1698 }
1700 1699
1701trait Foo<T> { 1700 trait Foo<T> {
1702 fn foo(&self) -> T; 1701 fn foo(&self) -> T;
1703} 1702 }
1704 1703
1705struct Bar<T>(T); 1704 struct Bar<T>(T);
1706 1705
1707impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { 1706 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1708 fn foo(&self) -> (A1, R) {} 1707 fn foo(&self) -> (A1, R) {}
1709} 1708 }
1710 1709
1711enum Opt<T> { None, Some(T) } 1710 enum Opt<T> { None, Some(T) }
1712impl<T> Opt<T> { 1711 impl<T> Opt<T> {
1713 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} 1712 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {}
1714} 1713 }
1715 1714
1716fn test() { 1715 fn test() {
1717 let bar: Bar<fn(u8) -> u32>; 1716 let bar: Bar<fn(u8) -> u32>;
1718 bar.foo(); 1717 bar.foo();
1719 1718
1720 let opt: Opt<u8>; 1719 let opt: Opt<u8>;
1721 let f: fn(u8) -> u32; 1720 let f: fn(u8) -> u32;
1722 opt.map(f); 1721 opt.map(f);
1723} 1722 }
1724"#), 1723 "#,
1725 @r###" 1724 expect![[r#"
1726 74..78 'self': Self 1725 74..78 'self': Self
1727 80..84 'args': Args 1726 80..84 'args': Args
1728 139..143 'self': &Self 1727 139..143 'self': &Self
1729 243..247 'self': &Bar<F> 1728 243..247 'self': &Bar<F>
1730 260..262 '{}': () 1729 260..262 '{}': ()
1731 346..350 'self': Opt<T> 1730 346..350 'self': Opt<T>
1732 352..353 'f': F 1731 352..353 'f': F
1733 368..370 '{}': () 1732 368..370 '{}': ()
1734 384..500 '{ ...(f); }': () 1733 384..500 '{ ...(f); }': ()
1735 394..397 'bar': Bar<fn(u8) -> u32> 1734 394..397 'bar': Bar<fn(u8) -> u32>
1736 423..426 'bar': Bar<fn(u8) -> u32> 1735 423..426 'bar': Bar<fn(u8) -> u32>
1737 423..432 'bar.foo()': (u8, u32) 1736 423..432 'bar.foo()': (u8, u32)
1738 443..446 'opt': Opt<u8> 1737 443..446 'opt': Opt<u8>
1739 465..466 'f': fn(u8) -> u32 1738 465..466 'f': fn(u8) -> u32
1740 487..490 'opt': Opt<u8> 1739 487..490 'opt': Opt<u8>
1741 487..497 'opt.map(f)': Opt<u32> 1740 487..497 'opt.map(f)': Opt<u32>
1742 495..496 'f': fn(u8) -> u32 1741 495..496 'f': fn(u8) -> u32
1743 "### 1742 "#]],
1744 ); 1743 );
1745} 1744}
1746 1745
1747#[test] 1746#[test]
1748fn fn_trait_deref_with_ty_default() { 1747fn fn_trait_deref_with_ty_default() {
1749 assert_snapshot!( 1748 check_infer(
1750 infer(r#" 1749 r#"
1751#[lang = "deref"] 1750 #[lang = "deref"]
1752trait Deref { 1751 trait Deref {
1753 type Target; 1752 type Target;
1754 1753
1755 fn deref(&self) -> &Self::Target; 1754 fn deref(&self) -> &Self::Target;
1756} 1755 }
1757 1756
1758#[lang="fn_once"] 1757 #[lang="fn_once"]
1759trait FnOnce<Args> { 1758 trait FnOnce<Args> {
1760 type Output; 1759 type Output;
1761 1760
1762 fn call_once(self, args: Args) -> Self::Output; 1761 fn call_once(self, args: Args) -> Self::Output;
1763} 1762 }
1764 1763
1765struct Foo; 1764 struct Foo;
1766 1765
1767impl Foo { 1766 impl Foo {
1768 fn foo(&self) -> usize {} 1767 fn foo(&self) -> usize {}
1769} 1768 }
1770 1769
1771struct Lazy<T, F = fn() -> T>(F); 1770 struct Lazy<T, F = fn() -> T>(F);
1772 1771
1773impl<T, F> Lazy<T, F> { 1772 impl<T, F> Lazy<T, F> {
1774 pub fn new(f: F) -> Lazy<T, F> {} 1773 pub fn new(f: F) -> Lazy<T, F> {}
1775} 1774 }
1776 1775
1777impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { 1776 impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1778 type Target = T; 1777 type Target = T;
1779} 1778 }
1780 1779
1781fn test() { 1780 fn test() {
1782 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); 1781 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
1783 let r1 = lazy1.foo(); 1782 let r1 = lazy1.foo();
1784 1783
1785 fn make_foo_fn() -> Foo {} 1784 fn make_foo_fn() -> Foo {}
1786 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; 1785 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
1787 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); 1786 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
1788 let r2 = lazy2.foo(); 1787 let r2 = lazy2.foo();
1789} 1788 }
1790"#), 1789 "#,
1791 @r###" 1790 expect![[r#"
1792 64..68 'self': &Self 1791 64..68 'self': &Self
1793 165..169 'self': Self 1792 165..169 'self': Self
1794 171..175 'args': Args 1793 171..175 'args': Args
1795 239..243 'self': &Foo 1794 239..243 'self': &Foo
1796 254..256 '{}': () 1795 254..256 '{}': ()
1797 334..335 'f': F 1796 334..335 'f': F
1798 354..356 '{}': () 1797 354..356 '{}': ()
1799 443..689 '{ ...o(); }': () 1798 443..689 '{ ...o(); }': ()
1800 453..458 'lazy1': Lazy<Foo, || -> Foo> 1799 453..458 'lazy1': Lazy<Foo, || -> Foo>
1801 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> 1800 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo>
1802 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> 1801 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo>
1803 485..491 '|| Foo': || -> Foo 1802 485..491 '|| Foo': || -> Foo
1804 488..491 'Foo': Foo 1803 488..491 'Foo': Foo
1805 502..504 'r1': usize 1804 502..504 'r1': usize
1806 507..512 'lazy1': Lazy<Foo, || -> Foo> 1805 507..512 'lazy1': Lazy<Foo, || -> Foo>
1807 507..518 'lazy1.foo()': usize 1806 507..518 'lazy1.foo()': usize
1808 560..575 'make_foo_fn_ptr': fn() -> Foo 1807 560..575 'make_foo_fn_ptr': fn() -> Foo
1809 591..602 'make_foo_fn': fn make_foo_fn() -> Foo 1808 591..602 'make_foo_fn': fn make_foo_fn() -> Foo
1810 612..617 'lazy2': Lazy<Foo, fn() -> Foo> 1809 612..617 'lazy2': Lazy<Foo, fn() -> Foo>
1811 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> 1810 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
1812 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> 1811 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
1813 644..659 'make_foo_fn_ptr': fn() -> Foo 1812 644..659 'make_foo_fn_ptr': fn() -> Foo
1814 670..672 'r2': usize 1813 670..672 'r2': usize
1815 675..680 'lazy2': Lazy<Foo, fn() -> Foo> 1814 675..680 'lazy2': Lazy<Foo, fn() -> Foo>
1816 675..686 'lazy2.foo()': usize 1815 675..686 'lazy2.foo()': usize
1817 549..551 '{}': () 1816 549..551 '{}': ()
1818 "### 1817 "#]],
1819 ); 1818 );
1820} 1819}
1821 1820
1822#[test] 1821#[test]
1823fn closure_1() { 1822fn closure_1() {
1824 assert_snapshot!( 1823 check_infer(
1825 infer(r#" 1824 r#"
1826#[lang = "fn_once"] 1825 #[lang = "fn_once"]
1827trait FnOnce<Args> { 1826 trait FnOnce<Args> {
1828 type Output; 1827 type Output;
1829} 1828 }
1830 1829
1831enum Option<T> { Some(T), None } 1830 enum Option<T> { Some(T), None }
1832impl<T> Option<T> { 1831 impl<T> Option<T> {
1833 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} 1832 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {}
1834} 1833 }
1835 1834
1836fn test() { 1835 fn test() {
1837 let x = Option::Some(1u32); 1836 let x = Option::Some(1u32);
1838 x.map(|v| v + 1); 1837 x.map(|v| v + 1);
1839 x.map(|_v| 1u64); 1838 x.map(|_v| 1u64);
1840 let y: Option<i64> = x.map(|_v| 1); 1839 let y: Option<i64> = x.map(|_v| 1);
1841} 1840 }
1842"#), 1841 "#,
1843 @r###" 1842 expect![[r#"
1844 147..151 'self': Option<T> 1843 147..151 'self': Option<T>
1845 153..154 'f': F 1844 153..154 'f': F
1846 172..174 '{}': () 1845 172..174 '{}': ()
1847 188..307 '{ ... 1); }': () 1846 188..307 '{ ... 1); }': ()
1848 198..199 'x': Option<u32> 1847 198..199 'x': Option<u32>
1849 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> 1848 202..214 'Option::Some': Some<u32>(u32) -> Option<u32>
1850 202..220 'Option...(1u32)': Option<u32> 1849 202..220 'Option...(1u32)': Option<u32>
1851 215..219 '1u32': u32 1850 215..219 '1u32': u32
1852 226..227 'x': Option<u32> 1851 226..227 'x': Option<u32>
1853 226..242 'x.map(...v + 1)': Option<u32> 1852 226..242 'x.map(...v + 1)': Option<u32>
1854 232..241 '|v| v + 1': |u32| -> u32 1853 232..241 '|v| v + 1': |u32| -> u32
1855 233..234 'v': u32 1854 233..234 'v': u32
1856 236..237 'v': u32 1855 236..237 'v': u32
1857 236..241 'v + 1': u32 1856 236..241 'v + 1': u32
1858 240..241 '1': u32 1857 240..241 '1': u32
1859 248..249 'x': Option<u32> 1858 248..249 'x': Option<u32>
1860 248..264 'x.map(... 1u64)': Option<u64> 1859 248..264 'x.map(... 1u64)': Option<u64>
1861 254..263 '|_v| 1u64': |u32| -> u64 1860 254..263 '|_v| 1u64': |u32| -> u64
1862 255..257 '_v': u32 1861 255..257 '_v': u32
1863 259..263 '1u64': u64 1862 259..263 '1u64': u64
1864 274..275 'y': Option<i64> 1863 274..275 'y': Option<i64>
1865 291..292 'x': Option<u32> 1864 291..292 'x': Option<u32>
1866 291..304 'x.map(|_v| 1)': Option<i64> 1865 291..304 'x.map(|_v| 1)': Option<i64>
1867 297..303 '|_v| 1': |u32| -> i64 1866 297..303 '|_v| 1': |u32| -> i64
1868 298..300 '_v': u32 1867 298..300 '_v': u32
1869 302..303 '1': i64 1868 302..303 '1': i64
1870 "### 1869 "#]],
1871 ); 1870 );
1872} 1871}
1873 1872
1874#[test] 1873#[test]
1875fn closure_2() { 1874fn closure_2() {
1876 assert_snapshot!( 1875 check_infer(
1877 infer(r#" 1876 r#"
1878trait FnOnce<Args> { 1877 trait FnOnce<Args> {
1879 type Output; 1878 type Output;
1880} 1879 }
1881 1880
1882fn test<F: FnOnce(u32) -> u64>(f: F) { 1881 fn test<F: FnOnce(u32) -> u64>(f: F) {
1883 f(1); 1882 f(1);
1884 let g = |v| v + 1; 1883 let g = |v| v + 1;
1885 g(1u64); 1884 g(1u64);
1886 let h = |v| 1u128 + v; 1885 let h = |v| 1u128 + v;
1887} 1886 }
1888"#), 1887 "#,
1889 @r###" 1888 expect![[r#"
1890 72..73 'f': F 1889 72..73 'f': F
1891 78..154 '{ ...+ v; }': () 1890 78..154 '{ ...+ v; }': ()
1892 84..85 'f': F 1891 84..85 'f': F
1893 84..88 'f(1)': {unknown} 1892 84..88 'f(1)': {unknown}
1894 86..87 '1': i32 1893 86..87 '1': i32
1895 98..99 'g': |u64| -> i32 1894 98..99 'g': |u64| -> i32
1896 102..111 '|v| v + 1': |u64| -> i32 1895 102..111 '|v| v + 1': |u64| -> i32
1897 103..104 'v': u64 1896 103..104 'v': u64
1898 106..107 'v': u64 1897 106..107 'v': u64
1899 106..111 'v + 1': i32 1898 106..111 'v + 1': i32
1900 110..111 '1': i32 1899 110..111 '1': i32
1901 117..118 'g': |u64| -> i32 1900 117..118 'g': |u64| -> i32
1902 117..124 'g(1u64)': i32 1901 117..124 'g(1u64)': i32
1903 119..123 '1u64': u64 1902 119..123 '1u64': u64
1904 134..135 'h': |u128| -> u128 1903 134..135 'h': |u128| -> u128
1905 138..151 '|v| 1u128 + v': |u128| -> u128 1904 138..151 '|v| 1u128 + v': |u128| -> u128
1906 139..140 'v': u128 1905 139..140 'v': u128
1907 142..147 '1u128': u128 1906 142..147 '1u128': u128
1908 142..151 '1u128 + v': u128 1907 142..151 '1u128 + v': u128
1909 150..151 'v': u128 1908 150..151 'v': u128
1910 "### 1909 "#]],
1911 ); 1910 );
1912} 1911}
1913 1912
1914#[test] 1913#[test]
1915fn closure_as_argument_inference_order() { 1914fn closure_as_argument_inference_order() {
1916 assert_snapshot!( 1915 check_infer(
1917 infer(r#" 1916 r#"
1918#[lang = "fn_once"] 1917 #[lang = "fn_once"]
1919trait FnOnce<Args> { 1918 trait FnOnce<Args> {
1920 type Output; 1919 type Output;
1921} 1920 }
1922 1921
1923fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} 1922 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {}
1924fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} 1923 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {}
1925 1924
1926struct S; 1925 struct S;
1927impl S { 1926 impl S {
1928 fn method(self) -> u64; 1927 fn method(self) -> u64;
1929 1928
1930 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} 1929 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {}
1931 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} 1930 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {}
1932} 1931 }
1933 1932
1934fn test() { 1933 fn test() {
1935 let x1 = foo1(S, |s| s.method()); 1934 let x1 = foo1(S, |s| s.method());
1936 let x2 = foo2(|s| s.method(), S); 1935 let x2 = foo2(|s| s.method(), S);
1937 let x3 = S.foo1(S, |s| s.method()); 1936 let x3 = S.foo1(S, |s| s.method());
1938 let x4 = S.foo2(|s| s.method(), S); 1937 let x4 = S.foo2(|s| s.method(), S);
1939} 1938 }
1940"#), 1939 "#,
1941 @r###" 1940 expect![[r#"
1942 94..95 'x': T 1941 94..95 'x': T
1943 100..101 'f': F 1942 100..101 'f': F
1944 111..113 '{}': () 1943 111..113 '{}': ()
1945 147..148 'f': F 1944 147..148 'f': F
1946 153..154 'x': T 1945 153..154 'x': T
1947 164..166 '{}': () 1946 164..166 '{}': ()
1948 201..205 'self': S 1947 201..205 'self': S
1949 253..257 'self': S 1948 253..257 'self': S
1950 259..260 'x': T 1949 259..260 'x': T
1951 265..266 'f': F 1950 265..266 'f': F
1952 276..278 '{}': () 1951 276..278 '{}': ()
1953 316..320 'self': S 1952 316..320 'self': S
1954 322..323 'f': F 1953 322..323 'f': F
1955 328..329 'x': T 1954 328..329 'x': T
1956 339..341 '{}': () 1955 339..341 '{}': ()
1957 355..514 '{ ... S); }': () 1956 355..514 '{ ... S); }': ()
1958 365..367 'x1': u64 1957 365..367 'x1': u64
1959 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 1958 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
1960 370..393 'foo1(S...hod())': u64 1959 370..393 'foo1(S...hod())': u64
1961 375..376 'S': S 1960 375..376 'S': S
1962 378..392 '|s| s.method()': |S| -> u64 1961 378..392 '|s| s.method()': |S| -> u64
1963 379..380 's': S 1962 379..380 's': S
1964 382..383 's': S 1963 382..383 's': S
1965 382..392 's.method()': u64 1964 382..392 's.method()': u64
1966 403..405 'x2': u64 1965 403..405 'x2': u64
1967 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 1966 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
1968 408..431 'foo2(|...(), S)': u64 1967 408..431 'foo2(|...(), S)': u64
1969 413..427 '|s| s.method()': |S| -> u64 1968 413..427 '|s| s.method()': |S| -> u64
1970 414..415 's': S 1969 414..415 's': S
1971 417..418 's': S 1970 417..418 's': S
1972 417..427 's.method()': u64 1971 417..427 's.method()': u64
1973 429..430 'S': S 1972 429..430 'S': S
1974 441..443 'x3': u64 1973 441..443 'x3': u64
1975 446..447 'S': S 1974 446..447 'S': S
1976 446..471 'S.foo1...hod())': u64 1975 446..471 'S.foo1...hod())': u64
1977 453..454 'S': S 1976 453..454 'S': S
1978 456..470 '|s| s.method()': |S| -> u64 1977 456..470 '|s| s.method()': |S| -> u64
1979 457..458 's': S 1978 457..458 's': S
1980 460..461 's': S 1979 460..461 's': S
1981 460..470 's.method()': u64 1980 460..470 's.method()': u64
1982 481..483 'x4': u64 1981 481..483 'x4': u64
1983 486..487 'S': S 1982 486..487 'S': S
1984 486..511 'S.foo2...(), S)': u64 1983 486..511 'S.foo2...(), S)': u64
1985 493..507 '|s| s.method()': |S| -> u64 1984 493..507 '|s| s.method()': |S| -> u64
1986 494..495 's': S 1985 494..495 's': S
1987 497..498 's': S 1986 497..498 's': S
1988 497..507 's.method()': u64 1987 497..507 's.method()': u64
1989 509..510 'S': S 1988 509..510 'S': S
1990 "### 1989 "#]],
1991 ); 1990 );
1992} 1991}
1993 1992
@@ -2056,43 +2055,44 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
2056 2055
2057#[test] 2056#[test]
2058fn unselected_projection_on_impl_self() { 2057fn unselected_projection_on_impl_self() {
2059 assert_snapshot!(infer( 2058 check_infer(
2060 r#" 2059 r#"
2061//- /main.rs 2060 //- /main.rs
2062trait Trait { 2061 trait Trait {
2063 type Item; 2062 type Item;
2064 2063
2065 fn f(&self, x: Self::Item); 2064 fn f(&self, x: Self::Item);
2066} 2065 }
2067 2066
2068struct S; 2067 struct S;
2069 2068
2070impl Trait for S { 2069 impl Trait for S {
2071 type Item = u32; 2070 type Item = u32;
2072 fn f(&self, x: Self::Item) { let y = x; } 2071 fn f(&self, x: Self::Item) { let y = x; }
2073} 2072 }
2074 2073
2075struct S2; 2074 struct S2;
2076 2075
2077impl Trait for S2 { 2076 impl Trait for S2 {
2078 type Item = i32; 2077 type Item = i32;
2079 fn f(&self, x: <Self>::Item) { let y = x; } 2078 fn f(&self, x: <Self>::Item) { let y = x; }
2080} 2079 }
2081"#, 2080 "#,
2082 ), @r###" 2081 expect![[r#"
2083 40..44 'self': &Self 2082 40..44 'self': &Self
2084 46..47 'x': Trait::Item<Self> 2083 46..47 'x': Trait::Item<Self>
2085 126..130 'self': &S 2084 126..130 'self': &S
2086 132..133 'x': u32 2085 132..133 'x': u32
2087 147..161 '{ let y = x; }': () 2086 147..161 '{ let y = x; }': ()
2088 153..154 'y': u32 2087 153..154 'y': u32
2089 157..158 'x': u32 2088 157..158 'x': u32
2090 228..232 'self': &S2 2089 228..232 'self': &S2
2091 234..235 'x': i32 2090 234..235 'x': i32
2092 251..265 '{ let y = x; }': () 2091 251..265 '{ let y = x; }': ()
2093 257..258 'y': i32 2092 257..258 'y': i32
2094 261..262 'x': i32 2093 261..262 'x': i32
2095 "###); 2094 "#]],
2095 );
2096} 2096}
2097 2097
2098#[test] 2098#[test]
@@ -2261,170 +2261,170 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
2261 2261
2262#[test] 2262#[test]
2263fn proc_macro_server_types() { 2263fn proc_macro_server_types() {
2264 assert_snapshot!( 2264 check_infer(
2265 infer(r#" 2265 r#"
2266macro_rules! with_api { 2266 macro_rules! with_api {
2267 ($S:ident, $self:ident, $m:ident) => { 2267 ($S:ident, $self:ident, $m:ident) => {
2268 $m! { 2268 $m! {
2269 TokenStream { 2269 TokenStream {
2270 fn new() -> $S::TokenStream; 2270 fn new() -> $S::TokenStream;
2271 }, 2271 },
2272 Group { 2272 Group {
2273 }, 2273 },
2274 } 2274 }
2275 }; 2275 };
2276} 2276 }
2277macro_rules! associated_item { 2277 macro_rules! associated_item {
2278 (type TokenStream) => 2278 (type TokenStream) =>
2279 (type TokenStream: 'static;); 2279 (type TokenStream: 'static;);
2280 (type Group) => 2280 (type Group) =>
2281 (type Group: 'static;); 2281 (type Group: 'static;);
2282 ($($item:tt)*) => ($($item)*;) 2282 ($($item:tt)*) => ($($item)*;)
2283} 2283 }
2284macro_rules! declare_server_traits { 2284 macro_rules! declare_server_traits {
2285 ($($name:ident { 2285 ($($name:ident {
2286 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* 2286 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
2287 }),* $(,)?) => { 2287 }),* $(,)?) => {
2288 pub trait Types { 2288 pub trait Types {
2289 $(associated_item!(type $name);)* 2289 $(associated_item!(type $name);)*
2290 } 2290 }
2291
2292 $(pub trait $name: Types {
2293 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2294 })*
2295
2296 pub trait Server: Types $(+ $name)* {}
2297 impl<S: Types $(+ $name)*> Server for S {}
2298 }
2299}
2300 2291
2301with_api!(Self, self_, declare_server_traits); 2292 $(pub trait $name: Types {
2302struct G {} 2293 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2303struct T {} 2294 })*
2304struct Rustc;
2305impl Types for Rustc {
2306 type TokenStream = T;
2307 type Group = G;
2308}
2309 2295
2310fn make<T>() -> T { loop {} } 2296 pub trait Server: Types $(+ $name)* {}
2311impl TokenStream for Rustc { 2297 impl<S: Types $(+ $name)*> Server for S {}
2312 fn new() -> Self::TokenStream { 2298 }
2313 let group: Self::Group = make(); 2299 }
2314 make() 2300
2315 } 2301 with_api!(Self, self_, declare_server_traits);
2316} 2302 struct G {}
2317"#), 2303 struct T {}
2318 @r###" 2304 struct Rustc;
2319 1061..1072 '{ loop {} }': T 2305 impl Types for Rustc {
2320 1063..1070 'loop {}': ! 2306 type TokenStream = T;
2321 1068..1070 '{}': () 2307 type Group = G;
2322 1136..1199 '{ ... }': T 2308 }
2323 1150..1155 'group': G 2309
2324 1171..1175 'make': fn make<G>() -> G 2310 fn make<T>() -> T { loop {} }
2325 1171..1177 'make()': G 2311 impl TokenStream for Rustc {
2326 1187..1191 'make': fn make<T>() -> T 2312 fn new() -> Self::TokenStream {
2327 1187..1193 'make()': T 2313 let group: Self::Group = make();
2328 "### 2314 make()
2315 }
2316 }
2317 "#,
2318 expect![[r#"
2319 1061..1072 '{ loop {} }': T
2320 1063..1070 'loop {}': !
2321 1068..1070 '{}': ()
2322 1136..1199 '{ ... }': T
2323 1150..1155 'group': G
2324 1171..1175 'make': fn make<G>() -> G
2325 1171..1177 'make()': G
2326 1187..1191 'make': fn make<T>() -> T
2327 1187..1193 'make()': T
2328 "#]],
2329 ); 2329 );
2330} 2330}
2331 2331
2332#[test] 2332#[test]
2333fn unify_impl_trait() { 2333fn unify_impl_trait() {
2334 assert_snapshot!( 2334 check_infer_with_mismatches(
2335 infer_with_mismatches(r#" 2335 r#"
2336trait Trait<T> {} 2336 trait Trait<T> {}
2337
2338 fn foo(x: impl Trait<u32>) { loop {} }
2339 fn bar<T>(x: impl Trait<T>) -> T { loop {} }
2340
2341 struct S<T>(T);
2342 impl<T> Trait<T> for S<T> {}
2343
2344 fn default<T>() -> T { loop {} }
2337 2345
2338fn foo(x: impl Trait<u32>) { loop {} } 2346 fn test() -> impl Trait<i32> {
2339fn bar<T>(x: impl Trait<T>) -> T { loop {} } 2347 let s1 = S(default());
2340 2348 foo(s1);
2341struct S<T>(T); 2349 let x: i32 = bar(S(default()));
2342impl<T> Trait<T> for S<T> {} 2350 S(default())
2343 2351 }
2344fn default<T>() -> T { loop {} } 2352 "#,
2345 2353 expect![[r#"
2346fn test() -> impl Trait<i32> { 2354 26..27 'x': impl Trait<u32>
2347 let s1 = S(default()); 2355 46..57 '{ loop {} }': ()
2348 foo(s1); 2356 48..55 'loop {}': !
2349 let x: i32 = bar(S(default())); 2357 53..55 '{}': ()
2350 S(default()) 2358 68..69 'x': impl Trait<T>
2351} 2359 91..102 '{ loop {} }': T
2352"#, true), 2360 93..100 'loop {}': !
2353 @r###" 2361 98..100 '{}': ()
2354 26..27 'x': impl Trait<u32> 2362 171..182 '{ loop {} }': T
2355 46..57 '{ loop {} }': () 2363 173..180 'loop {}': !
2356 48..55 'loop {}': ! 2364 178..180 '{}': ()
2357 53..55 '{}': () 2365 213..309 '{ ...t()) }': S<{unknown}>
2358 68..69 'x': impl Trait<T> 2366 223..225 's1': S<u32>
2359 91..102 '{ loop {} }': T 2367 228..229 'S': S<u32>(u32) -> S<u32>
2360 93..100 'loop {}': ! 2368 228..240 'S(default())': S<u32>
2361 98..100 '{}': () 2369 230..237 'default': fn default<u32>() -> u32
2362 171..182 '{ loop {} }': T 2370 230..239 'default()': u32
2363 173..180 'loop {}': ! 2371 246..249 'foo': fn foo(S<u32>)
2364 178..180 '{}': () 2372 246..253 'foo(s1)': ()
2365 213..309 '{ ...t()) }': S<{unknown}> 2373 250..252 's1': S<u32>
2366 223..225 's1': S<u32> 2374 263..264 'x': i32
2367 228..229 'S': S<u32>(u32) -> S<u32> 2375 272..275 'bar': fn bar<i32>(S<i32>) -> i32
2368 228..240 'S(default())': S<u32> 2376 272..289 'bar(S(...lt()))': i32
2369 230..237 'default': fn default<u32>() -> u32 2377 276..277 'S': S<i32>(i32) -> S<i32>
2370 230..239 'default()': u32 2378 276..288 'S(default())': S<i32>
2371 246..249 'foo': fn foo(S<u32>) 2379 278..285 'default': fn default<i32>() -> i32
2372 246..253 'foo(s1)': () 2380 278..287 'default()': i32
2373 250..252 's1': S<u32> 2381 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}>
2374 263..264 'x': i32 2382 295..307 'S(default())': S<{unknown}>
2375 272..275 'bar': fn bar<i32>(S<i32>) -> i32 2383 297..304 'default': fn default<{unknown}>() -> {unknown}
2376 272..289 'bar(S(...lt()))': i32 2384 297..306 'default()': {unknown}
2377 276..277 'S': S<i32>(i32) -> S<i32> 2385 "#]],
2378 276..288 'S(default())': S<i32>
2379 278..285 'default': fn default<i32>() -> i32
2380 278..287 'default()': i32
2381 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}>
2382 295..307 'S(default())': S<{unknown}>
2383 297..304 'default': fn default<{unknown}>() -> {unknown}
2384 297..306 'default()': {unknown}
2385 "###
2386 ); 2386 );
2387} 2387}
2388 2388
2389#[test] 2389#[test]
2390fn assoc_types_from_bounds() { 2390fn assoc_types_from_bounds() {
2391 assert_snapshot!( 2391 check_infer(
2392 infer(r#" 2392 r#"
2393//- /main.rs 2393 //- /main.rs
2394#[lang = "fn_once"] 2394 #[lang = "fn_once"]
2395trait FnOnce<Args> { 2395 trait FnOnce<Args> {
2396 type Output; 2396 type Output;
2397} 2397 }
2398 2398
2399trait T { 2399 trait T {
2400 type O; 2400 type O;
2401} 2401 }
2402 2402
2403impl T for () { 2403 impl T for () {
2404 type O = (); 2404 type O = ();
2405} 2405 }
2406 2406
2407fn f<X, F>(_v: F) 2407 fn f<X, F>(_v: F)
2408where 2408 where
2409 X: T, 2409 X: T,
2410 F: FnOnce(&X::O), 2410 F: FnOnce(&X::O),
2411{ } 2411 { }
2412 2412
2413fn main() { 2413 fn main() {
2414 f::<(), _>(|z| { z; }); 2414 f::<(), _>(|z| { z; });
2415} 2415 }
2416"#), 2416 "#,
2417 @r###" 2417 expect![[r#"
2418 133..135 '_v': F 2418 133..135 '_v': F
2419 178..181 '{ }': () 2419 178..181 '{ }': ()
2420 193..224 '{ ... }); }': () 2420 193..224 '{ ... }); }': ()
2421 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) 2421 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
2422 199..221 'f::<()... z; })': () 2422 199..221 'f::<()... z; })': ()
2423 210..220 '|z| { z; }': |&()| -> () 2423 210..220 '|z| { z; }': |&()| -> ()
2424 211..212 'z': &() 2424 211..212 'z': &()
2425 214..220 '{ z; }': () 2425 214..220 '{ z; }': ()
2426 216..217 'z': &() 2426 216..217 'z': &()
2427 "### 2427 "#]],
2428 ); 2428 );
2429} 2429}
2430 2430
@@ -2497,120 +2497,120 @@ fn test() {
2497 2497
2498#[test] 2498#[test]
2499fn iterator_chain() { 2499fn iterator_chain() {
2500 assert_snapshot!( 2500 check_infer(
2501 infer(r#" 2501 r#"
2502//- /main.rs 2502 //- /main.rs
2503#[lang = "fn_once"] 2503 #[lang = "fn_once"]
2504trait FnOnce<Args> { 2504 trait FnOnce<Args> {
2505 type Output; 2505 type Output;
2506} 2506 }
2507#[lang = "fn_mut"] 2507 #[lang = "fn_mut"]
2508trait FnMut<Args>: FnOnce<Args> { } 2508 trait FnMut<Args>: FnOnce<Args> { }
2509 2509
2510enum Option<T> { Some(T), None } 2510 enum Option<T> { Some(T), None }
2511use Option::*; 2511 use Option::*;
2512 2512
2513pub trait Iterator { 2513 pub trait Iterator {
2514 type Item; 2514 type Item;
2515 2515
2516 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> 2516 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
2517 where 2517 where
2518 F: FnMut(Self::Item) -> Option<B>, 2518 F: FnMut(Self::Item) -> Option<B>,
2519 { loop {} } 2519 { loop {} }
2520 2520
2521 fn for_each<F>(self, f: F) 2521 fn for_each<F>(self, f: F)
2522 where 2522 where
2523 F: FnMut(Self::Item), 2523 F: FnMut(Self::Item),
2524 { loop {} } 2524 { loop {} }
2525} 2525 }
2526 2526
2527pub trait IntoIterator { 2527 pub trait IntoIterator {
2528 type Item; 2528 type Item;
2529 type IntoIter: Iterator<Item = Self::Item>; 2529 type IntoIter: Iterator<Item = Self::Item>;
2530 fn into_iter(self) -> Self::IntoIter; 2530 fn into_iter(self) -> Self::IntoIter;
2531} 2531 }
2532 2532
2533pub struct FilterMap<I, F> { } 2533 pub struct FilterMap<I, F> { }
2534impl<B, I: Iterator, F> Iterator for FilterMap<I, F> 2534 impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
2535where 2535 where
2536 F: FnMut(I::Item) -> Option<B>, 2536 F: FnMut(I::Item) -> Option<B>,
2537{ 2537 {
2538 type Item = B; 2538 type Item = B;
2539} 2539 }
2540 2540
2541#[stable(feature = "rust1", since = "1.0.0")] 2541 #[stable(feature = "rust1", since = "1.0.0")]
2542impl<I: Iterator> IntoIterator for I { 2542 impl<I: Iterator> IntoIterator for I {
2543 type Item = I::Item; 2543 type Item = I::Item;
2544 type IntoIter = I; 2544 type IntoIter = I;
2545 2545
2546 fn into_iter(self) -> I { 2546 fn into_iter(self) -> I {
2547 self 2547 self
2548 } 2548 }
2549} 2549 }
2550 2550
2551struct Vec<T> {} 2551 struct Vec<T> {}
2552impl<T> Vec<T> { 2552 impl<T> Vec<T> {
2553 fn new() -> Self { loop {} } 2553 fn new() -> Self { loop {} }
2554} 2554 }
2555 2555
2556impl<T> IntoIterator for Vec<T> { 2556 impl<T> IntoIterator for Vec<T> {
2557 type Item = T; 2557 type Item = T;
2558 type IntoIter = IntoIter<T>; 2558 type IntoIter = IntoIter<T>;
2559} 2559 }
2560 2560
2561pub struct IntoIter<T> { } 2561 pub struct IntoIter<T> { }
2562impl<T> Iterator for IntoIter<T> { 2562 impl<T> Iterator for IntoIter<T> {
2563 type Item = T; 2563 type Item = T;
2564} 2564 }
2565 2565
2566fn main() { 2566 fn main() {
2567 Vec::<i32>::new().into_iter() 2567 Vec::<i32>::new().into_iter()
2568 .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) 2568 .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
2569 .for_each(|y| { y; }); 2569 .for_each(|y| { y; });
2570} 2570 }
2571"#), 2571 "#,
2572 @r###" 2572 expect![[r#"
2573 226..230 'self': Self 2573 226..230 'self': Self
2574 232..233 'f': F 2574 232..233 'f': F
2575 317..328 '{ loop {} }': FilterMap<Self, F> 2575 317..328 '{ loop {} }': FilterMap<Self, F>
2576 319..326 'loop {}': ! 2576 319..326 'loop {}': !
2577 324..326 '{}': () 2577 324..326 '{}': ()
2578 349..353 'self': Self 2578 349..353 'self': Self
2579 355..356 'f': F 2579 355..356 'f': F
2580 405..416 '{ loop {} }': () 2580 405..416 '{ loop {} }': ()
2581 407..414 'loop {}': ! 2581 407..414 'loop {}': !
2582 412..414 '{}': () 2582 412..414 '{}': ()
2583 525..529 'self': Self 2583 525..529 'self': Self
2584 854..858 'self': I 2584 854..858 'self': I
2585 865..885 '{ ... }': I 2585 865..885 '{ ... }': I
2586 875..879 'self': I 2586 875..879 'self': I
2587 944..955 '{ loop {} }': Vec<T> 2587 944..955 '{ loop {} }': Vec<T>
2588 946..953 'loop {}': ! 2588 946..953 'loop {}': !
2589 951..953 '{}': () 2589 951..953 '{}': ()
2590 1142..1273 '{ ... }); }': () 2590 1142..1269 '{ ... }); }': ()
2591 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> 2591 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
2592 1148..1165 'Vec::<...:new()': Vec<i32> 2592 1148..1165 'Vec::<...:new()': Vec<i32>
2593 1148..1177 'Vec::<...iter()': IntoIter<i32> 2593 1148..1177 'Vec::<...iter()': IntoIter<i32>
2594 1148..1242 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> 2594 1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
2595 1148..1270 'Vec::<... y; })': () 2595 1148..1266 'Vec::<... y; })': ()
2596 1196..1241 '|x| if...None }': |i32| -> Option<u32> 2596 1194..1239 '|x| if...None }': |i32| -> Option<u32>
2597 1197..1198 'x': i32 2597 1195..1196 'x': i32
2598 1200..1241 'if x >...None }': Option<u32> 2598 1198..1239 'if x >...None }': Option<u32>
2599 1203..1204 'x': i32 2599 1201..1202 'x': i32
2600 1203..1208 'x > 0': bool 2600 1201..1206 'x > 0': bool
2601 1207..1208 '0': i32 2601 1205..1206 '0': i32
2602 1209..1227 '{ Some...u32) }': Option<u32> 2602 1207..1225 '{ Some...u32) }': Option<u32>
2603 1211..1215 'Some': Some<u32>(u32) -> Option<u32> 2603 1209..1213 'Some': Some<u32>(u32) -> Option<u32>
2604 1211..1225 'Some(x as u32)': Option<u32> 2604 1209..1223 'Some(x as u32)': Option<u32>
2605 1216..1217 'x': i32 2605 1214..1215 'x': i32
2606 1216..1224 'x as u32': u32 2606 1214..1222 'x as u32': u32
2607 1233..1241 '{ None }': Option<u32> 2607 1231..1239 '{ None }': Option<u32>
2608 1235..1239 'None': Option<u32> 2608 1233..1237 'None': Option<u32>
2609 1259..1269 '|y| { y; }': |u32| -> () 2609 1255..1265 '|y| { y; }': |u32| -> ()
2610 1260..1261 'y': u32 2610 1256..1257 'y': u32
2611 1263..1269 '{ y; }': () 2611 1259..1265 '{ y; }': ()
2612 1265..1266 'y': u32 2612 1261..1262 'y': u32
2613 "### 2613 "#]],
2614 ); 2614 );
2615} 2615}
2616 2616
@@ -2648,176 +2648,176 @@ fn main() {
2648 2648
2649#[test] 2649#[test]
2650fn trait_object_no_coercion() { 2650fn trait_object_no_coercion() {
2651 assert_snapshot!( 2651 check_infer_with_mismatches(
2652 infer_with_mismatches(r#" 2652 r#"
2653trait Foo {} 2653 trait Foo {}
2654 2654
2655fn foo(x: &dyn Foo) {} 2655 fn foo(x: &dyn Foo) {}
2656 2656
2657fn test(x: &dyn Foo) { 2657 fn test(x: &dyn Foo) {
2658 foo(x); 2658 foo(x);
2659} 2659 }
2660"#, true), 2660 "#,
2661 @r###" 2661 expect![[r#"
2662 21..22 'x': &dyn Foo 2662 21..22 'x': &dyn Foo
2663 34..36 '{}': () 2663 34..36 '{}': ()
2664 46..47 'x': &dyn Foo 2664 46..47 'x': &dyn Foo
2665 59..74 '{ foo(x); }': () 2665 59..74 '{ foo(x); }': ()
2666 65..68 'foo': fn foo(&dyn Foo) 2666 65..68 'foo': fn foo(&dyn Foo)
2667 65..71 'foo(x)': () 2667 65..71 'foo(x)': ()
2668 69..70 'x': &dyn Foo 2668 69..70 'x': &dyn Foo
2669 "### 2669 "#]],
2670 ); 2670 );
2671} 2671}
2672 2672
2673#[test] 2673#[test]
2674fn builtin_copy() { 2674fn builtin_copy() {
2675 assert_snapshot!( 2675 check_infer_with_mismatches(
2676 infer_with_mismatches(r#" 2676 r#"
2677#[lang = "copy"] 2677 #[lang = "copy"]
2678trait Copy {} 2678 trait Copy {}
2679 2679
2680struct IsCopy; 2680 struct IsCopy;
2681impl Copy for IsCopy {} 2681 impl Copy for IsCopy {}
2682struct NotCopy; 2682 struct NotCopy;
2683 2683
2684trait Test { fn test(&self) -> bool; } 2684 trait Test { fn test(&self) -> bool; }
2685impl<T: Copy> Test for T {} 2685 impl<T: Copy> Test for T {}
2686 2686
2687fn test() { 2687 fn test() {
2688 IsCopy.test(); 2688 IsCopy.test();
2689 NotCopy.test(); 2689 NotCopy.test();
2690 (IsCopy, IsCopy).test(); 2690 (IsCopy, IsCopy).test();
2691 (IsCopy, NotCopy).test(); 2691 (IsCopy, NotCopy).test();
2692} 2692 }
2693"#, true), 2693 "#,
2694 @r###" 2694 expect![[r#"
2695 110..114 'self': &Self 2695 110..114 'self': &Self
2696 166..267 '{ ...t(); }': () 2696 166..267 '{ ...t(); }': ()
2697 172..178 'IsCopy': IsCopy 2697 172..178 'IsCopy': IsCopy
2698 172..185 'IsCopy.test()': bool 2698 172..185 'IsCopy.test()': bool
2699 191..198 'NotCopy': NotCopy 2699 191..198 'NotCopy': NotCopy
2700 191..205 'NotCopy.test()': {unknown} 2700 191..205 'NotCopy.test()': {unknown}
2701 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) 2701 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy)
2702 211..234 '(IsCop...test()': bool 2702 211..234 '(IsCop...test()': bool
2703 212..218 'IsCopy': IsCopy 2703 212..218 'IsCopy': IsCopy
2704 220..226 'IsCopy': IsCopy 2704 220..226 'IsCopy': IsCopy
2705 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) 2705 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy)
2706 240..264 '(IsCop...test()': {unknown} 2706 240..264 '(IsCop...test()': {unknown}
2707 241..247 'IsCopy': IsCopy 2707 241..247 'IsCopy': IsCopy
2708 249..256 'NotCopy': NotCopy 2708 249..256 'NotCopy': NotCopy
2709 "### 2709 "#]],
2710 ); 2710 );
2711} 2711}
2712 2712
2713#[test] 2713#[test]
2714fn builtin_fn_def_copy() { 2714fn builtin_fn_def_copy() {
2715 assert_snapshot!( 2715 check_infer_with_mismatches(
2716 infer_with_mismatches(r#" 2716 r#"
2717#[lang = "copy"] 2717 #[lang = "copy"]
2718trait Copy {} 2718 trait Copy {}
2719 2719
2720fn foo() {} 2720 fn foo() {}
2721fn bar<T: Copy>(T) -> T {} 2721 fn bar<T: Copy>(T) -> T {}
2722struct Struct(usize); 2722 struct Struct(usize);
2723enum Enum { Variant(usize) } 2723 enum Enum { Variant(usize) }
2724 2724
2725trait Test { fn test(&self) -> bool; } 2725 trait Test { fn test(&self) -> bool; }
2726impl<T: Copy> Test for T {} 2726 impl<T: Copy> Test for T {}
2727 2727
2728fn test() { 2728 fn test() {
2729 foo.test(); 2729 foo.test();
2730 bar.test(); 2730 bar.test();
2731 Struct.test(); 2731 Struct.test();
2732 Enum::Variant.test(); 2732 Enum::Variant.test();
2733} 2733 }
2734"#, true), 2734 "#,
2735 @r###" 2735 expect![[r#"
2736 41..43 '{}': () 2736 41..43 '{}': ()
2737 60..61 'T': {unknown} 2737 60..61 'T': {unknown}
2738 68..70 '{}': () 2738 68..70 '{}': ()
2739 68..70: expected T, got () 2739 68..70: expected T, got ()
2740 145..149 'self': &Self 2740 145..149 'self': &Self
2741 201..281 '{ ...t(); }': () 2741 201..281 '{ ...t(); }': ()
2742 207..210 'foo': fn foo() 2742 207..210 'foo': fn foo()
2743 207..217 'foo.test()': bool 2743 207..217 'foo.test()': bool
2744 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} 2744 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2745 223..233 'bar.test()': bool 2745 223..233 'bar.test()': bool
2746 239..245 'Struct': Struct(usize) -> Struct 2746 239..245 'Struct': Struct(usize) -> Struct
2747 239..252 'Struct.test()': bool 2747 239..252 'Struct.test()': bool
2748 258..271 'Enum::Variant': Variant(usize) -> Enum 2748 258..271 'Enum::Variant': Variant(usize) -> Enum
2749 258..278 'Enum::...test()': bool 2749 258..278 'Enum::...test()': bool
2750 "### 2750 "#]],
2751 ); 2751 );
2752} 2752}
2753 2753
2754#[test] 2754#[test]
2755fn builtin_fn_ptr_copy() { 2755fn builtin_fn_ptr_copy() {
2756 assert_snapshot!( 2756 check_infer_with_mismatches(
2757 infer_with_mismatches(r#" 2757 r#"
2758#[lang = "copy"] 2758 #[lang = "copy"]
2759trait Copy {} 2759 trait Copy {}
2760 2760
2761trait Test { fn test(&self) -> bool; } 2761 trait Test { fn test(&self) -> bool; }
2762impl<T: Copy> Test for T {} 2762 impl<T: Copy> Test for T {}
2763 2763
2764fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { 2764 fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2765 f1.test(); 2765 f1.test();
2766 f2.test(); 2766 f2.test();
2767 f3.test(); 2767 f3.test();
2768} 2768 }
2769"#, true), 2769 "#,
2770 @r###" 2770 expect![[r#"
2771 54..58 'self': &Self 2771 54..58 'self': &Self
2772 108..110 'f1': fn() 2772 108..110 'f1': fn()
2773 118..120 'f2': fn(usize) -> u8 2773 118..120 'f2': fn(usize) -> u8
2774 139..141 'f3': fn(u8, u8) -> &u8 2774 139..141 'f3': fn(u8, u8) -> &u8
2775 162..210 '{ ...t(); }': () 2775 162..210 '{ ...t(); }': ()
2776 168..170 'f1': fn() 2776 168..170 'f1': fn()
2777 168..177 'f1.test()': bool 2777 168..177 'f1.test()': bool
2778 183..185 'f2': fn(usize) -> u8 2778 183..185 'f2': fn(usize) -> u8
2779 183..192 'f2.test()': bool 2779 183..192 'f2.test()': bool
2780 198..200 'f3': fn(u8, u8) -> &u8 2780 198..200 'f3': fn(u8, u8) -> &u8
2781 198..207 'f3.test()': bool 2781 198..207 'f3.test()': bool
2782 "### 2782 "#]],
2783 ); 2783 );
2784} 2784}
2785 2785
2786#[test] 2786#[test]
2787fn builtin_sized() { 2787fn builtin_sized() {
2788 assert_snapshot!( 2788 check_infer_with_mismatches(
2789 infer_with_mismatches(r#" 2789 r#"
2790#[lang = "sized"] 2790 #[lang = "sized"]
2791trait Sized {} 2791 trait Sized {}
2792 2792
2793trait Test { fn test(&self) -> bool; } 2793 trait Test { fn test(&self) -> bool; }
2794impl<T: Sized> Test for T {} 2794 impl<T: Sized> Test for T {}
2795 2795
2796fn test() { 2796 fn test() {
2797 1u8.test(); 2797 1u8.test();
2798 (*"foo").test(); // not Sized 2798 (*"foo").test(); // not Sized
2799 (1u8, 1u8).test(); 2799 (1u8, 1u8).test();
2800 (1u8, *"foo").test(); // not Sized 2800 (1u8, *"foo").test(); // not Sized
2801} 2801 }
2802"#, true), 2802 "#,
2803 @r###" 2803 expect![[r#"
2804 56..60 'self': &Self 2804 56..60 'self': &Self
2805 113..228 '{ ...ized }': () 2805 113..228 '{ ...ized }': ()
2806 119..122 '1u8': u8 2806 119..122 '1u8': u8
2807 119..129 '1u8.test()': bool 2807 119..129 '1u8.test()': bool
2808 135..150 '(*"foo").test()': {unknown} 2808 135..150 '(*"foo").test()': {unknown}
2809 136..142 '*"foo"': str 2809 136..142 '*"foo"': str
2810 137..142 '"foo"': &str 2810 137..142 '"foo"': &str
2811 169..179 '(1u8, 1u8)': (u8, u8) 2811 169..179 '(1u8, 1u8)': (u8, u8)
2812 169..186 '(1u8, ...test()': bool 2812 169..186 '(1u8, ...test()': bool
2813 170..173 '1u8': u8 2813 170..173 '1u8': u8
2814 175..178 '1u8': u8 2814 175..178 '1u8': u8
2815 192..205 '(1u8, *"foo")': (u8, str) 2815 192..205 '(1u8, *"foo")': (u8, str)
2816 192..212 '(1u8, ...test()': {unknown} 2816 192..212 '(1u8, ...test()': {unknown}
2817 193..196 '1u8': u8 2817 193..196 '1u8': u8
2818 198..204 '*"foo"': str 2818 198..204 '*"foo"': str
2819 199..204 '"foo"': &str 2819 199..204 '"foo"': &str
2820 "### 2820 "#]],
2821 ); 2821 );
2822} 2822}
2823 2823
@@ -2867,156 +2867,150 @@ impl<A: Step> iter::Iterator for ops::Range<A> {
2867 2867
2868#[test] 2868#[test]
2869fn infer_closure_arg() { 2869fn infer_closure_arg() {
2870 assert_snapshot!( 2870 check_infer(
2871 infer( 2871 r#"
2872 r#" 2872 //- /lib.rs
2873 //- /lib.rs
2874
2875 enum Option<T> {
2876 None,
2877 Some(T)
2878 }
2879 2873
2880 fn foo() { 2874 enum Option<T> {
2881 let s = Option::None; 2875 None,
2882 let f = |x: Option<i32>| {}; 2876 Some(T)
2883 (&f)(s) 2877 }
2884 } 2878
2885 "# 2879 fn foo() {
2886 ), 2880 let s = Option::None;
2887 @r###" 2881 let f = |x: Option<i32>| {};
2888 52..126 '{ ...)(s) }': () 2882 (&f)(s)
2889 62..63 's': Option<i32> 2883 }
2890 66..78 'Option::None': Option<i32> 2884 "#,
2891 88..89 'f': |Option<i32>| -> () 2885 expect![[r#"
2892 92..111 '|x: Op...2>| {}': |Option<i32>| -> () 2886 52..126 '{ ...)(s) }': ()
2893 93..94 'x': Option<i32> 2887 62..63 's': Option<i32>
2894 109..111 '{}': () 2888 66..78 'Option::None': Option<i32>
2895 117..124 '(&f)(s)': () 2889 88..89 'f': |Option<i32>| -> ()
2896 118..120 '&f': &|Option<i32>| -> () 2890 92..111 '|x: Op...2>| {}': |Option<i32>| -> ()
2897 119..120 'f': |Option<i32>| -> () 2891 93..94 'x': Option<i32>
2898 122..123 's': Option<i32> 2892 109..111 '{}': ()
2899 "### 2893 117..124 '(&f)(s)': ()
2894 118..120 '&f': &|Option<i32>| -> ()
2895 119..120 'f': |Option<i32>| -> ()
2896 122..123 's': Option<i32>
2897 "#]],
2900 ); 2898 );
2901} 2899}
2902 2900
2903#[test] 2901#[test]
2904fn infer_fn_trait_arg() { 2902fn infer_fn_trait_arg() {
2905 assert_snapshot!( 2903 check_infer(
2906 infer( 2904 r#"
2907 r#" 2905 //- /lib.rs deps:std
2908 //- /lib.rs deps:std
2909 2906
2910 #[lang = "fn_once"] 2907 #[lang = "fn_once"]
2911 pub trait FnOnce<Args> { 2908 pub trait FnOnce<Args> {
2912 type Output; 2909 type Output;
2913 2910
2914 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; 2911 extern "rust-call" fn call_once(&self, args: Args) -> Self::Output;
2915 } 2912 }
2916 2913
2917 #[lang = "fn"] 2914 #[lang = "fn"]
2918 pub trait Fn<Args>:FnOnce<Args> { 2915 pub trait Fn<Args>:FnOnce<Args> {
2919 extern "rust-call" fn call(&self, args: Args) -> Self::Output; 2916 extern "rust-call" fn call(&self, args: Args) -> Self::Output;
2920 } 2917 }
2921 2918
2922 enum Option<T> { 2919 enum Option<T> {
2923 None, 2920 None,
2924 Some(T) 2921 Some(T)
2925 } 2922 }
2926 2923
2927 fn foo<F, T>(f: F) -> T 2924 fn foo<F, T>(f: F) -> T
2928 where 2925 where
2929 F: Fn(Option<i32>) -> T, 2926 F: Fn(Option<i32>) -> T,
2930 { 2927 {
2931 let s = None; 2928 let s = None;
2932 f(s) 2929 f(s)
2933 } 2930 }
2934 "# 2931 "#,
2935 ), 2932 expect![[r#"
2936 @r###" 2933 101..105 'self': &Self
2937 101..105 'self': &Self 2934 107..111 'args': Args
2938 107..111 'args': Args 2935 220..224 'self': &Self
2939 220..224 'self': &Self 2936 226..230 'args': Args
2940 226..230 'args': Args 2937 313..314 'f': F
2941 313..314 'f': F 2938 359..389 '{ ...f(s) }': T
2942 359..389 '{ ...f(s) }': T 2939 369..370 's': Option<i32>
2943 369..370 's': Option<i32> 2940 373..377 'None': Option<i32>
2944 373..377 'None': Option<i32> 2941 383..384 'f': F
2945 383..384 'f': F 2942 383..387 'f(s)': T
2946 383..387 'f(s)': T 2943 385..386 's': Option<i32>
2947 385..386 's': Option<i32> 2944 "#]],
2948 "###
2949 ); 2945 );
2950} 2946}
2951 2947
2952#[test] 2948#[test]
2953fn infer_box_fn_arg() { 2949fn infer_box_fn_arg() {
2954 assert_snapshot!( 2950 check_infer(
2955 infer( 2951 r#"
2956 r#" 2952 //- /lib.rs deps:std
2957 //- /lib.rs deps:std
2958 2953
2959 #[lang = "fn_once"] 2954 #[lang = "fn_once"]
2960 pub trait FnOnce<Args> { 2955 pub trait FnOnce<Args> {
2961 type Output; 2956 type Output;
2962 2957
2963 extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 2958 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
2964 } 2959 }
2965 2960
2966 #[lang = "deref"] 2961 #[lang = "deref"]
2967 pub trait Deref { 2962 pub trait Deref {
2968 type Target: ?Sized; 2963 type Target: ?Sized;
2969 2964
2970 fn deref(&self) -> &Self::Target; 2965 fn deref(&self) -> &Self::Target;
2971 } 2966 }
2972 2967
2973 #[lang = "owned_box"] 2968 #[lang = "owned_box"]
2974 pub struct Box<T: ?Sized> { 2969 pub struct Box<T: ?Sized> {
2975 inner: *mut T, 2970 inner: *mut T,
2976 } 2971 }
2977 2972
2978 impl<T: ?Sized> Deref for Box<T> { 2973 impl<T: ?Sized> Deref for Box<T> {
2979 type Target = T; 2974 type Target = T;
2980 2975
2981 fn deref(&self) -> &T { 2976 fn deref(&self) -> &T {
2982 &self.inner 2977 &self.inner
2983 }
2984 } 2978 }
2979 }
2985 2980
2986 enum Option<T> { 2981 enum Option<T> {
2987 None, 2982 None,
2988 Some(T) 2983 Some(T)
2989 } 2984 }
2990 2985
2991 fn foo() { 2986 fn foo() {
2992 let s = Option::None; 2987 let s = Option::None;
2993 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 2988 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
2994 f(&s) 2989 f(&s)
2995 } 2990 }
2996 "# 2991 "#,
2997 ), 2992 expect![[r#"
2998 @r###" 2993 100..104 'self': Self
2999 100..104 'self': Self 2994 106..110 'args': Args
3000 106..110 'args': Args 2995 214..218 'self': &Self
3001 214..218 'self': &Self 2996 384..388 'self': &Box<T>
3002 384..388 'self': &Box<T> 2997 396..423 '{ ... }': &T
3003 396..423 '{ ... }': &T 2998 406..417 '&self.inner': &*mut T
3004 406..417 '&self.inner': &*mut T 2999 407..411 'self': &Box<T>
3005 407..411 'self': &Box<T> 3000 407..417 'self.inner': *mut T
3006 407..417 'self.inner': *mut T 3001 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)>
3007 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> 3002 488..489 's': Option<i32>
3008 488..489 's': Option<i32> 3003 492..504 'Option::None': Option<i32>
3009 492..504 'Option::None': Option<i32> 3004 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>>
3010 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>> 3005 549..562 'box (|ps| {})': Box<|{unknown}| -> ()>
3011 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> 3006 554..561 '|ps| {}': |{unknown}| -> ()
3012 554..561 '|ps| {}': |{unknown}| -> () 3007 555..557 'ps': {unknown}
3013 555..557 'ps': {unknown} 3008 559..561 '{}': ()
3014 559..561 '{}': () 3009 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>>
3015 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>> 3010 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)>
3016 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> 3011 570..572 '&s': &Option<i32>
3017 570..572 '&s': &Option<i32> 3012 571..572 's': Option<i32>
3018 571..572 's': Option<i32> 3013 "#]],
3019 "###
3020 ); 3014 );
3021} 3015}
3022 3016
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index cee916c09..d0c6eea61 100644
--- a/docs/dev/architecture.md
+++ b/docs/dev/architecture.md
@@ -170,8 +170,7 @@ The innermost and most elaborate boundary is `hir`. It has a much richer
170vocabulary of types than `ide`, but the basic testing setup is the same: we 170vocabulary of types than `ide`, but the basic testing setup is the same: we
171create a database, run some queries, assert result. 171create a database, run some queries, assert result.
172 172
173For comparisons, we use [insta](https://github.com/mitsuhiko/insta/) library for 173For comparisons, we use the `expect` crate for snapshot testing.
174snapshot testing.
175 174
176To test various analysis corner cases and avoid forgetting about old tests, we 175To test various analysis corner cases and avoid forgetting about old tests, we
177use so-called marks. See the `marks` module in the `test_utils` crate for more. 176use so-called marks. See the `marks` module in the `test_utils` crate for more.