diff options
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 620 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 1150 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/patterns.rs | 1102 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 1172 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/simple.rs | 3413 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 3274 |
7 files changed, 5368 insertions, 5367 deletions
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 | ||
40 | fn setup_tracing() -> tracing::subscriber::DefaultGuard { | 40 | fn 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 @@ | |||
1 | use std::fs; | 1 | use std::fs; |
2 | 2 | ||
3 | use insta::assert_snapshot; | 3 | use expect::expect; |
4 | use test_utils::project_dir; | 4 | use test_utils::project_dir; |
5 | 5 | ||
6 | use super::{check_types, infer}; | 6 | use super::{check_infer, check_types}; |
7 | 7 | ||
8 | #[test] | 8 | #[test] |
9 | fn cfg_impl_def() { | 9 | fn cfg_impl_def() { |
@@ -46,204 +46,204 @@ impl S { | |||
46 | 46 | ||
47 | #[test] | 47 | #[test] |
48 | fn infer_macros_expanded() { | 48 | fn infer_macros_expanded() { |
49 | assert_snapshot!( | 49 | check_infer( |
50 | infer(r#" | 50 | r#" |
51 | struct Foo(Vec<i32>); | 51 | struct Foo(Vec<i32>); |
52 | 52 | ||
53 | macro_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 | ||
61 | fn 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] |
77 | fn infer_legacy_textual_scoped_macros_expanded() { | 77 | fn infer_legacy_textual_scoped_macros_expanded() { |
78 | assert_snapshot!( | 78 | check_infer( |
79 | infer(r#" | 79 | r#" |
80 | struct Foo(Vec<i32>); | 80 | struct Foo(Vec<i32>); |
81 | 81 | ||
82 | #[macro_use] | 82 | #[macro_use] |
83 | mod 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 | ||
93 | fn 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] |
112 | fn infer_path_qualified_macros_expanded() { | 112 | fn infer_path_qualified_macros_expanded() { |
113 | assert_snapshot!( | 113 | check_infer( |
114 | infer(r#" | 114 | r#" |
115 | #[macro_export] | 115 | #[macro_export] |
116 | macro_rules! foo { | 116 | macro_rules! foo { |
117 | () => { 42i32 } | 117 | () => { 42i32 } |
118 | } | 118 | } |
119 | 119 | ||
120 | mod m { | 120 | mod m { |
121 | pub use super::foo as bar; | 121 | pub use super::foo as bar; |
122 | } | 122 | } |
123 | 123 | ||
124 | fn 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] |
140 | fn expr_macro_expanded_in_various_places() { | 140 | fn expr_macro_expanded_in_various_places() { |
141 | assert_snapshot!( | 141 | check_infer( |
142 | infer(r#" | 142 | r#" |
143 | macro_rules! spam { | 143 | macro_rules! spam { |
144 | () => (1isize); | 144 | () => (1isize); |
145 | } | 145 | } |
146 | 146 | ||
147 | fn 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] |
221 | fn infer_type_value_macro_having_same_name() { | 221 | fn infer_type_value_macro_having_same_name() { |
222 | assert_snapshot!( | 222 | check_infer( |
223 | infer(r#" | 223 | r#" |
224 | #[macro_export] | 224 | #[macro_export] |
225 | macro_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 | ||
236 | foo!(); | 236 | foo!(); |
237 | 237 | ||
238 | fn 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] |
374 | fn infer_type_value_non_legacy_macro_use_as() { | 374 | fn infer_type_value_non_legacy_macro_use_as() { |
375 | assert_snapshot!( | 375 | check_infer( |
376 | infer(r#" | 376 | r#" |
377 | mod 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 | ||
384 | m::foo!(foo); | 384 | m::foo!(foo); |
385 | use foo as bar; | 385 | use foo as bar; |
386 | fn f() -> bar { 0 } | 386 | fn f() -> bar { 0 } |
387 | fn 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] |
403 | fn infer_local_macro() { | 403 | fn infer_local_macro() { |
404 | assert_snapshot!( | 404 | check_infer( |
405 | infer(r#" | 405 | r#" |
406 | fn 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] |
448 | fn infer_builtin_macros_line() { | 448 | fn infer_builtin_macros_line() { |
449 | assert_snapshot!( | 449 | check_infer( |
450 | infer(r#" | 450 | r#" |
451 | #[rustc_builtin_macro] | 451 | #[rustc_builtin_macro] |
452 | macro_rules! line {() => {}} | 452 | macro_rules! line {() => {}} |
453 | 453 | ||
454 | fn 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] |
467 | fn infer_builtin_macros_file() { | 467 | fn infer_builtin_macros_file() { |
468 | assert_snapshot!( | 468 | check_infer( |
469 | infer(r#" | 469 | r#" |
470 | #[rustc_builtin_macro] | 470 | #[rustc_builtin_macro] |
471 | macro_rules! file {() => {}} | 471 | macro_rules! file {() => {}} |
472 | 472 | ||
473 | fn 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] |
486 | fn infer_builtin_macros_column() { | 486 | fn infer_builtin_macros_column() { |
487 | assert_snapshot!( | 487 | check_infer( |
488 | infer(r#" | 488 | r#" |
489 | #[rustc_builtin_macro] | 489 | #[rustc_builtin_macro] |
490 | macro_rules! column {() => {}} | 490 | macro_rules! column {() => {}} |
491 | 491 | ||
492 | fn 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] |
505 | fn infer_builtin_macros_concat() { | 505 | fn infer_builtin_macros_concat() { |
506 | assert_snapshot!( | 506 | check_infer( |
507 | infer(r#" | 507 | r#" |
508 | #[rustc_builtin_macro] | 508 | #[rustc_builtin_macro] |
509 | macro_rules! concat {() => {}} | 509 | macro_rules! concat {() => {}} |
510 | 510 | ||
511 | fn 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 {() => {}} | |||
622 | include!("main.rs"); | 622 | include!("main.rs"); |
623 | 623 | ||
624 | fn main() { | 624 | fn 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] |
632 | fn infer_builtin_macros_concat_with_lazy() { | 632 | fn infer_builtin_macros_concat_with_lazy() { |
633 | assert_snapshot!( | 633 | check_infer( |
634 | infer(r#" | 634 | r#" |
635 | macro_rules! hello {() => {"hello"}} | 635 | macro_rules! hello {() => {"hello"}} |
636 | 636 | ||
637 | #[rustc_builtin_macro] | 637 | #[rustc_builtin_macro] |
638 | macro_rules! concat {() => {}} | 638 | macro_rules! concat {() => {}} |
639 | 639 | ||
640 | fn 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] |
653 | fn infer_builtin_macros_env() { | 653 | fn 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] |
658 | macro_rules! env {() => {}} | 658 | macro_rules! env {() => {}} |
659 | 659 | ||
660 | fn 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] |
765 | fn macro_in_arm() { | 765 | fn macro_in_arm() { |
766 | assert_snapshot!( | 766 | check_infer( |
767 | infer(r#" | 767 | r#" |
768 | macro_rules! unit { | 768 | macro_rules! unit { |
769 | () => { () }; | 769 | () => { () }; |
770 | } | 770 | } |
771 | 771 | ||
772 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer}; | 3 | use super::{check_infer, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_slice_method() { | 6 | fn infer_slice_method() { |
7 | assert_snapshot!( | 7 | check_infer( |
8 | infer(r#" | 8 | r#" |
9 | #[lang = "slice"] | 9 | #[lang = "slice"] |
10 | impl<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"] |
17 | impl<T> [T] {} | 17 | impl<T> [T] {} |
18 | 18 | ||
19 | fn 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] |
38 | fn infer_associated_method_struct() { | 38 | fn infer_associated_method_struct() { |
39 | assert_snapshot!( | 39 | check_infer( |
40 | infer(r#" | 40 | r#" |
41 | struct A { x: u32 } | 41 | struct A { x: u32 } |
42 | 42 | ||
43 | impl A { | 43 | impl A { |
44 | fn new() -> A { | 44 | fn new() -> A { |
45 | A { x: 0 } | 45 | A { x: 0 } |
46 | } | 46 | } |
47 | } | 47 | } |
48 | fn 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] |
68 | fn infer_associated_method_enum() { | 68 | fn infer_associated_method_enum() { |
69 | assert_snapshot!( | 69 | check_infer( |
70 | infer(r#" | 70 | r#" |
71 | enum A { B, C } | 71 | enum A { B, C } |
72 | 72 | ||
73 | impl 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 | } |
81 | fn 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] |
107 | fn infer_associated_method_with_modules() { | 107 | fn infer_associated_method_with_modules() { |
108 | assert_snapshot!( | 108 | check_infer( |
109 | infer(r#" | 109 | r#" |
110 | mod 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 | ||
115 | mod 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 | } |
124 | use b::c; | 124 | use b::c; |
125 | 125 | ||
126 | fn 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] |
154 | fn infer_associated_method_generics() { | 154 | fn infer_associated_method_generics() { |
155 | assert_snapshot!( | 155 | check_infer( |
156 | infer(r#" | 156 | r#" |
157 | struct Gen<T> { | 157 | struct Gen<T> { |
158 | val: T | 158 | val: T |
159 | } | 159 | } |
160 | 160 | ||
161 | impl<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 | ||
167 | fn 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] |
186 | fn infer_associated_method_generics_without_args() { | 186 | fn infer_associated_method_generics_without_args() { |
187 | assert_snapshot!( | 187 | check_infer( |
188 | infer(r#" | 188 | r#" |
189 | struct Gen<T> { | 189 | struct Gen<T> { |
190 | val: T | 190 | val: T |
191 | } | 191 | } |
192 | 192 | ||
193 | impl<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 | ||
199 | fn 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] |
216 | fn infer_associated_method_generics_2_type_params_without_args() { | 216 | fn infer_associated_method_generics_2_type_params_without_args() { |
217 | assert_snapshot!( | 217 | check_infer( |
218 | infer(r#" | 218 | r#" |
219 | struct Gen<T, U> { | 219 | struct Gen<T, U> { |
220 | val: T, | 220 | val: T, |
221 | val2: U, | 221 | val2: U, |
222 | } | 222 | } |
223 | 223 | ||
224 | impl<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 | ||
230 | fn 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] |
268 | fn infer_trait_method_simple() { | 268 | fn 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#" |
272 | trait Trait1 { | 272 | trait Trait1 { |
273 | fn method(&self) -> u32; | 273 | fn method(&self) -> u32; |
274 | } | 274 | } |
275 | struct S1; | 275 | struct S1; |
276 | impl Trait1 for S1 {} | 276 | impl Trait1 for S1 {} |
277 | trait Trait2 { | 277 | trait Trait2 { |
278 | fn method(&self) -> i128; | 278 | fn method(&self) -> i128; |
279 | } | 279 | } |
280 | struct S2; | 280 | struct S2; |
281 | impl Trait2 for S2 {} | 281 | impl Trait2 for S2 {} |
282 | fn 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] |
300 | fn infer_trait_method_scoped() { | 300 | fn 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#" |
304 | struct S; | 304 | struct S; |
305 | mod 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 | } |
311 | mod 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 | ||
318 | mod 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 | ||
326 | mod 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] |
348 | fn infer_trait_method_generic_1() { | 348 | fn 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#" |
352 | trait Trait<T> { | 352 | trait Trait<T> { |
353 | fn method(&self) -> T; | 353 | fn method(&self) -> T; |
354 | } | 354 | } |
355 | struct S; | 355 | struct S; |
356 | impl Trait<u32> for S {} | 356 | impl Trait<u32> for S {} |
357 | fn 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] |
371 | fn infer_trait_method_generic_more_params() { | 371 | fn 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#" |
375 | trait 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 | } |
379 | struct S1; | 379 | struct S1; |
380 | impl Trait<u8, u16, u32> for S1 {} | 380 | impl Trait<u8, u16, u32> for S1 {} |
381 | struct S2; | 381 | struct S2; |
382 | impl<T> Trait<i8, i16, T> for S2 {} | 382 | impl<T> Trait<i8, i16, T> for S2 {} |
383 | fn 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] |
407 | fn infer_trait_method_generic_2() { | 407 | fn 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#" |
411 | trait Trait<T> { | 411 | trait Trait<T> { |
412 | fn method(&self) -> T; | 412 | fn method(&self) -> T; |
413 | } | 413 | } |
414 | struct S<T>(T); | 414 | struct S<T>(T); |
415 | impl<U> Trait<U> for S<U> {} | 415 | impl<U> Trait<U> for S<U> {} |
416 | fn 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] |
432 | fn infer_trait_assoc_method() { | 432 | fn infer_trait_assoc_method() { |
433 | assert_snapshot!( | 433 | check_infer( |
434 | infer(r#" | 434 | r#" |
435 | trait Default { | 435 | trait Default { |
436 | fn default() -> Self; | 436 | fn default() -> Self; |
437 | } | 437 | } |
438 | struct S; | 438 | struct S; |
439 | impl Default for S {} | 439 | impl Default for S {} |
440 | fn 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] |
462 | fn infer_trait_assoc_method_generics_1() { | 462 | fn infer_trait_assoc_method_generics_1() { |
463 | assert_snapshot!( | 463 | check_infer( |
464 | infer(r#" | 464 | r#" |
465 | trait Trait<T> { | 465 | trait Trait<T> { |
466 | fn make() -> T; | 466 | fn make() -> T; |
467 | } | 467 | } |
468 | struct S; | 468 | struct S; |
469 | impl Trait<u32> for S {} | 469 | impl Trait<u32> for S {} |
470 | struct G<T>; | 470 | struct G<T>; |
471 | impl<T> Trait<T> for G<T> {} | 471 | impl<T> Trait<T> for G<T> {} |
472 | fn 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] |
494 | fn infer_trait_assoc_method_generics_2() { | 494 | fn infer_trait_assoc_method_generics_2() { |
495 | assert_snapshot!( | 495 | check_infer( |
496 | infer(r#" | 496 | r#" |
497 | trait Trait<T> { | 497 | trait Trait<T> { |
498 | fn make<U>() -> (T, U); | 498 | fn make<U>() -> (T, U); |
499 | } | 499 | } |
500 | struct S; | 500 | struct S; |
501 | impl Trait<u32> for S {} | 501 | impl Trait<u32> for S {} |
502 | struct G<T>; | 502 | struct G<T>; |
503 | impl<T> Trait<T> for G<T> {} | 503 | impl<T> Trait<T> for G<T> {} |
504 | fn 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] |
534 | fn infer_trait_assoc_method_generics_3() { | 534 | fn infer_trait_assoc_method_generics_3() { |
535 | assert_snapshot!( | 535 | check_infer( |
536 | infer(r#" | 536 | r#" |
537 | trait Trait<T> { | 537 | trait Trait<T> { |
538 | fn make() -> (Self, T); | 538 | fn make() -> (Self, T); |
539 | } | 539 | } |
540 | struct S<T>; | 540 | struct S<T>; |
541 | impl Trait<i64> for S<i32> {} | 541 | impl Trait<i64> for S<i32> {} |
542 | fn 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] |
556 | fn infer_trait_assoc_method_generics_4() { | 556 | fn infer_trait_assoc_method_generics_4() { |
557 | assert_snapshot!( | 557 | check_infer( |
558 | infer(r#" | 558 | r#" |
559 | trait Trait<T> { | 559 | trait Trait<T> { |
560 | fn make() -> (Self, T); | 560 | fn make() -> (Self, T); |
561 | } | 561 | } |
562 | struct S<T>; | 562 | struct S<T>; |
563 | impl Trait<i64> for S<u64> {} | 563 | impl Trait<i64> for S<u64> {} |
564 | impl Trait<i32> for S<u32> {} | 564 | impl Trait<i32> for S<u32> {} |
565 | fn 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] |
583 | fn infer_trait_assoc_method_generics_5() { | 583 | fn infer_trait_assoc_method_generics_5() { |
584 | assert_snapshot!( | 584 | check_infer( |
585 | infer(r#" | 585 | r#" |
586 | trait Trait<T> { | 586 | trait Trait<T> { |
587 | fn make<U>() -> (Self, T, U); | 587 | fn make<U>() -> (Self, T, U); |
588 | } | 588 | } |
589 | struct S<T>; | 589 | struct S<T>; |
590 | impl Trait<i64> for S<u64> {} | 590 | impl Trait<i64> for S<u64> {} |
591 | fn 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] |
609 | fn infer_call_trait_method_on_generic_param_1() { | 609 | fn infer_call_trait_method_on_generic_param_1() { |
610 | assert_snapshot!( | 610 | check_infer( |
611 | infer(r#" | 611 | r#" |
612 | trait Trait { | 612 | trait Trait { |
613 | fn method(&self) -> u32; | 613 | fn method(&self) -> u32; |
614 | } | 614 | } |
615 | fn 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] |
630 | fn infer_call_trait_method_on_generic_param_2() { | 630 | fn infer_call_trait_method_on_generic_param_2() { |
631 | assert_snapshot!( | 631 | check_infer( |
632 | infer(r#" | 632 | r#" |
633 | trait Trait<T> { | 633 | trait Trait<T> { |
634 | fn method(&self) -> T; | 634 | fn method(&self) -> T; |
635 | } | 635 | } |
636 | fn 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] |
651 | fn infer_with_multiple_trait_impls() { | 651 | fn infer_with_multiple_trait_impls() { |
652 | assert_snapshot!( | 652 | check_infer( |
653 | infer(r#" | 653 | r#" |
654 | trait Into<T> { | 654 | trait Into<T> { |
655 | fn into(self) -> T; | 655 | fn into(self) -> T; |
656 | } | 656 | } |
657 | struct S; | 657 | struct S; |
658 | impl Into<u32> for S {} | 658 | impl Into<u32> for S {} |
659 | impl Into<u64> for S {} | 659 | impl Into<u64> for S {} |
660 | fn 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] |
1025 | fn dyn_trait_super_trait_not_in_scope() { | 1025 | fn dyn_trait_super_trait_not_in_scope() { |
1026 | assert_snapshot!( | 1026 | check_infer( |
1027 | infer(r#" | 1027 | r#" |
1028 | mod 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 | } |
1033 | trait Trait: m::SuperTrait {} | 1033 | trait Trait: m::SuperTrait {} |
1034 | 1034 | ||
1035 | struct S; | 1035 | struct S; |
1036 | impl m::SuperTrait for S {} | 1036 | impl m::SuperTrait for S {} |
1037 | impl Trait for S {} | 1037 | impl Trait for S {} |
1038 | 1038 | ||
1039 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{infer, infer_with_mismatches}; | 4 | use super::{check_infer, check_infer_with_mismatches}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn infer_pattern() { | 7 | fn infer_pattern() { |
8 | assert_snapshot!( | 8 | check_infer( |
9 | infer(r#" | 9 | r#" |
10 | fn 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] |
86 | fn infer_literal_pattern() { | 86 | fn infer_literal_pattern() { |
87 | assert_snapshot!( | 87 | check_infer_with_mismatches( |
88 | infer_with_mismatches(r#" | 88 | r#" |
89 | fn any<T>() -> T { loop {} } | 89 | fn any<T>() -> T { loop {} } |
90 | fn 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] |
146 | fn infer_range_pattern() { | 146 | fn infer_range_pattern() { |
147 | assert_snapshot!( | 147 | check_infer_with_mismatches( |
148 | infer_with_mismatches(r#" | 148 | r#" |
149 | fn 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] |
170 | fn infer_pattern_match_ergonomics() { | 170 | fn infer_pattern_match_ergonomics() { |
171 | assert_snapshot!( | 171 | check_infer( |
172 | infer(r#" | 172 | r#" |
173 | struct A<T>(T); | 173 | struct A<T>(T); |
174 | 174 | ||
175 | fn 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] |
199 | fn infer_pattern_match_ergonomics_ref() { | 199 | fn 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#" |
203 | fn 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] |
226 | fn infer_pattern_match_slice() { | 226 | fn infer_pattern_match_slice() { |
227 | assert_snapshot!( | 227 | check_infer( |
228 | infer(r#" | 228 | r#" |
229 | fn 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] |
274 | fn infer_pattern_match_string_literal() { | 274 | fn infer_pattern_match_string_literal() { |
275 | assert_snapshot!( | 275 | check_infer_with_mismatches( |
276 | infer_with_mismatches(r#" | 276 | r#" |
277 | fn 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] |
301 | fn infer_pattern_match_or() { | 301 | fn infer_pattern_match_or() { |
302 | assert_snapshot!( | 302 | check_infer_with_mismatches( |
303 | infer_with_mismatches(r#" | 303 | r#" |
304 | fn 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] |
331 | fn infer_pattern_match_arr() { | 331 | fn infer_pattern_match_arr() { |
332 | assert_snapshot!( | 332 | check_infer( |
333 | infer(r#" | 333 | r#" |
334 | fn 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] |
372 | fn infer_adt_pattern() { | 372 | fn infer_adt_pattern() { |
373 | assert_snapshot!( | 373 | check_infer( |
374 | infer(r#" | 374 | r#" |
375 | enum E { | 375 | enum E { |
376 | A { x: usize }, | 376 | A { x: usize }, |
377 | B | 377 | B |
378 | } | 378 | } |
379 | 379 | ||
380 | struct S(u32, E); | 380 | struct S(u32, E); |
381 | 381 | ||
382 | fn 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] |
429 | fn enum_variant_through_self_in_pattern() { | 429 | fn enum_variant_through_self_in_pattern() { |
430 | assert_snapshot!( | 430 | check_infer( |
431 | infer(r#" | 431 | r#" |
432 | enum 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 | ||
438 | impl 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] |
468 | fn infer_generics_in_patterns() { | 468 | fn infer_generics_in_patterns() { |
469 | assert_snapshot!( | 469 | check_infer( |
470 | infer(r#" | 470 | r#" |
471 | struct A<T> { | 471 | struct A<T> { |
472 | x: T, | 472 | x: T, |
473 | } | 473 | } |
474 | 474 | ||
475 | enum Option<T> { | 475 | enum Option<T> { |
476 | Some(T), | 476 | Some(T), |
477 | None, | 477 | None, |
478 | } | 478 | } |
479 | 479 | ||
480 | fn 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] |
512 | fn infer_const_pattern() { | 512 | fn infer_const_pattern() { |
513 | assert_snapshot!( | 513 | check_infer_with_mismatches( |
514 | infer_with_mismatches(r#" | 514 | r#" |
515 | enum Option<T> { None } | 515 | enum Option<T> { None } |
516 | use Option::None; | 516 | use Option::None; |
517 | struct Foo; | 517 | struct Foo; |
518 | const Bar: usize = 1; | 518 | const Bar: usize = 1; |
519 | 519 | ||
520 | fn 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] |
556 | fn infer_guard() { | 556 | fn infer_guard() { |
557 | assert_snapshot!( | 557 | check_infer( |
558 | infer(r#" | 558 | r#" |
559 | struct S; | 559 | struct S; |
560 | impl S { fn foo(&self) -> bool { false } } | 560 | impl 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] |
582 | fn match_ergonomics_in_closure_params() { | 584 | fn match_ergonomics_in_closure_params() { |
583 | assert_snapshot!( | 585 | check_infer( |
584 | infer(r#" | 586 | r#" |
585 | #[lang = "fn_once"] | 587 | #[lang = "fn_once"] |
586 | trait FnOnce<Args> { | 588 | trait FnOnce<Args> { |
587 | type Output; | 589 | type Output; |
588 | } | 590 | } |
589 | 591 | ||
590 | fn 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 | ||
592 | fn 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] |
632 | fn slice_tail_pattern() { | 634 | fn slice_tail_pattern() { |
633 | assert_snapshot!( | 635 | check_infer( |
634 | infer(r#" | 636 | r#" |
635 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{check_types, infer}; | 4 | use super::{check_infer, check_types}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn bug_484() { | 7 | fn bug_484() { |
8 | assert_snapshot!( | 8 | check_infer( |
9 | infer(r#" | 9 | r#" |
10 | fn 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] |
25 | fn no_panic_on_field_of_enum() { | 25 | fn no_panic_on_field_of_enum() { |
26 | assert_snapshot!( | 26 | check_infer( |
27 | infer(r#" | 27 | r#" |
28 | enum X {} | 28 | enum X {} |
29 | 29 | ||
30 | fn 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] |
44 | fn bug_585() { | 44 | fn bug_585() { |
45 | assert_snapshot!( | 45 | check_infer( |
46 | infer(r#" | 46 | r#" |
47 | fn 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] |
69 | fn bug_651() { | 69 | fn bug_651() { |
70 | assert_snapshot!( | 70 | check_infer( |
71 | infer(r#" | 71 | r#" |
72 | fn 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() { | |||
89 | fn recursive_vars() { | 89 | fn 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#" |
94 | fn 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] |
112 | fn recursive_vars_2() { | 112 | fn recursive_vars_2() { |
113 | assert_snapshot!( | 113 | check_infer( |
114 | infer(r#" | 114 | r#" |
115 | fn 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] |
141 | fn infer_std_crash_1() { | 141 | fn 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#" |
145 | enum Maybe<T> { | 145 | enum Maybe<T> { |
146 | Real(T), | 146 | Real(T), |
147 | Fake, | 147 | Fake, |
148 | } | 148 | } |
149 | 149 | ||
150 | fn 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() { | |||
168 | fn infer_std_crash_2() { | 168 | fn 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#" |
173 | fn 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] |
190 | fn infer_std_crash_3() { | 190 | fn infer_std_crash_3() { |
191 | // taken from rustc | 191 | // taken from rustc |
192 | assert_snapshot!( | 192 | check_infer( |
193 | infer(r#" | 193 | r#" |
194 | pub 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] |
214 | fn infer_std_crash_4() { | 214 | fn infer_std_crash_4() { |
215 | // taken from rustc | 215 | // taken from rustc |
216 | assert_snapshot!( | 216 | check_infer( |
217 | infer(r#" | 217 | r#" |
218 | pub 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] |
238 | fn infer_std_crash_5() { | 238 | fn infer_std_crash_5() { |
239 | // taken from rustc | 239 | // taken from rustc |
240 | assert_snapshot!( | 240 | check_infer( |
241 | infer(r#" | 241 | r#" |
242 | fn 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] |
287 | fn infer_nested_generics_crash() { | 287 | fn 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#" |
291 | struct Canonical<V> { | 291 | struct Canonical<V> { |
292 | value: V, | 292 | value: V, |
293 | } | 293 | } |
294 | struct QueryResponse<V> { | 294 | struct QueryResponse<V> { |
295 | value: V, | 295 | value: V, |
296 | } | 296 | } |
297 | fn 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] |
312 | fn infer_paren_macro_call() { | 312 | fn infer_paren_macro_call() { |
313 | assert_snapshot!( | 313 | check_infer( |
314 | infer(r#" | 314 | r#" |
315 | macro_rules! bar { () => {0u32} } | 315 | macro_rules! bar { () => {0u32} } |
316 | fn 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] |
329 | fn bug_1030() { | 329 | fn bug_1030() { |
330 | assert_snapshot!(infer(r#" | 330 | check_infer( |
331 | struct HashSet<T, H>; | 331 | r#" |
332 | struct FxHasher; | 332 | struct HashSet<T, H>; |
333 | type FxHashSet<T> = HashSet<T, FxHasher>; | 333 | struct FxHasher; |
334 | type FxHashSet<T> = HashSet<T, FxHasher>; | ||
334 | 335 | ||
335 | impl<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 | ||
339 | pub 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] |
353 | fn issue_2669() { | 354 | fn 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] |
386 | fn issue_2705() { | 387 | fn issue_2705() { |
387 | assert_snapshot!( | 388 | check_infer( |
388 | infer(r#" | 389 | r#" |
389 | trait Trait {} | 390 | trait Trait {} |
390 | fn 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] |
481 | fn issue_3999_slice() { | 482 | fn issue_3999_slice() { |
482 | assert_snapshot!( | 483 | check_infer( |
483 | infer(r#" | 484 | r#" |
484 | fn 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]) { | |||
505 | fn issue_3999_struct() { | 506 | fn 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#" |
510 | struct Bar { | 511 | struct Bar { |
511 | a: bool, | 512 | a: bool, |
512 | } | 513 | } |
513 | fn 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] |
532 | fn issue_4235_name_conflicts() { | 533 | fn issue_4235_name_conflicts() { |
533 | assert_snapshot!( | 534 | check_infer( |
534 | infer(r#" | 535 | r#" |
535 | struct FOO {} | 536 | struct FOO {} |
536 | static FOO:FOO = FOO {}; | 537 | static FOO:FOO = FOO {}; |
537 | 538 | ||
538 | impl FOO { | 539 | impl FOO { |
539 | fn foo(&self) {} | 540 | fn foo(&self) {} |
540 | } | 541 | } |
541 | 542 | ||
542 | fn 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] |
561 | fn issue_4465_dollar_crate_at_type() { | 563 | fn issue_4465_dollar_crate_at_type() { |
562 | assert_snapshot!( | 564 | check_infer( |
563 | infer(r#" | 565 | r#" |
564 | pub struct Foo {} | 566 | pub struct Foo {} |
565 | pub fn anything<T>() -> T { | 567 | pub fn anything<T>() -> T { |
566 | loop {} | 568 | loop {} |
567 | } | 569 | } |
568 | macro_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 | } |
574 | fn 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] |
592 | fn issue_4053_diesel_where_clauses() { | 596 | fn issue_4053_diesel_where_clauses() { |
593 | assert_snapshot!( | 597 | check_infer( |
594 | infer(r#" | 598 | r#" |
595 | trait 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 | ||
600 | struct 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 | ||
604 | trait QueryFragment<DB: Backend> {} | 608 | trait QueryFragment<DB: Backend> {} |
605 | 609 | ||
606 | trait Into<T> { fn into(self) -> T; } | 610 | trait Into<T> { fn into(self) -> T; } |
607 | 611 | ||
608 | impl<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> |
610 | where | 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] |
633 | fn issue_4953() { | 637 | fn issue_4953() { |
634 | assert_snapshot!( | 638 | check_infer( |
635 | infer(r#" | 639 | r#" |
636 | pub struct Foo(pub i64); | 640 | pub struct Foo(pub i64); |
637 | impl 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#" |
650 | pub struct Foo<T>(pub T); | 654 | pub struct Foo<T>(pub T); |
651 | impl 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] |
665 | fn issue_4931() { | 669 | fn issue_4931() { |
666 | assert_snapshot!( | 670 | check_infer( |
667 | infer(r#" | 671 | r#" |
668 | trait Div<T> { | 672 | trait Div<T> { |
669 | type Output; | 673 | type Output; |
670 | } | 674 | } |
671 | 675 | ||
672 | trait CheckedDiv: Div<()> {} | 676 | trait CheckedDiv: Div<()> {} |
673 | 677 | ||
674 | trait PrimInt: CheckedDiv<Output = ()> { | 678 | trait PrimInt: CheckedDiv<Output = ()> { |
675 | fn pow(self); | 679 | fn pow(self); |
676 | } | 680 | } |
677 | 681 | ||
678 | fn 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] |
693 | fn issue_4885() { | 697 | fn issue_4885() { |
694 | assert_snapshot!( | 698 | check_infer( |
695 | infer(r#" | 699 | r#" |
696 | #[lang = "coerce_unsized"] | 700 | #[lang = "coerce_unsized"] |
697 | pub trait CoerceUnsized<T> {} | 701 | pub trait CoerceUnsized<T> {} |
698 | 702 | ||
699 | trait Future { | 703 | trait Future { |
700 | type Output; | 704 | type Output; |
701 | } | 705 | } |
702 | trait Foo<R> { | 706 | trait Foo<R> { |
703 | type Bar; | 707 | type Bar; |
704 | } | 708 | } |
705 | fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> | 709 | fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar> |
706 | where | 710 | where |
707 | K: Foo<R>, | 711 | K: Foo<R>, |
708 | { | 712 | { |
709 | bar(key) | 713 | bar(key) |
710 | } | 714 | } |
711 | fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> | 715 | fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar> |
712 | where | 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] |
730 | fn issue_4800() { | 734 | fn issue_4800() { |
731 | assert_snapshot!( | 735 | check_infer( |
732 | infer(r#" | 736 | r#" |
733 | trait Debug {} | 737 | trait Debug {} |
734 | 738 | ||
735 | struct Foo<T>; | 739 | struct Foo<T>; |
736 | 740 | ||
737 | type E1<T> = (T, T, T); | 741 | type E1<T> = (T, T, T); |
738 | type E2<T> = E1<E1<E1<(T, T, T)>>>; | 742 | type E2<T> = E1<E1<E1<(T, T, T)>>>; |
739 | 743 | ||
740 | impl Debug for Foo<E2<()>> {} | 744 | impl Debug for Foo<E2<()>> {} |
741 | 745 | ||
742 | struct Request; | 746 | struct Request; |
743 | 747 | ||
744 | pub trait Future { | 748 | pub trait Future { |
745 | type Output; | 749 | type Output; |
746 | } | 750 | } |
747 | 751 | ||
748 | pub struct PeerSet<D>; | 752 | pub struct PeerSet<D>; |
749 | 753 | ||
750 | impl<D> Service<Request> for PeerSet<D> | 754 | impl<D> Service<Request> for PeerSet<D> |
751 | where | 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 | ||
763 | pub trait Discover { | 767 | pub trait Discover { |
764 | type Key; | 768 | type Key; |
765 | } | 769 | } |
766 | 770 | ||
767 | pub 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] |
784 | fn issue_4966() { | 788 | fn issue_4966() { |
785 | assert_snapshot!( | 789 | check_infer( |
786 | infer(r#" | 790 | r#" |
787 | pub trait IntoIterator { | 791 | pub trait IntoIterator { |
788 | type Item; | 792 | type Item; |
789 | } | 793 | } |
790 | 794 | ||
791 | struct Repeat<A> { element: A } | 795 | struct Repeat<A> { element: A } |
792 | 796 | ||
793 | struct Map<F> { f: F } | 797 | struct Map<F> { f: F } |
794 | 798 | ||
795 | struct Vec<T> {} | 799 | struct Vec<T> {} |
796 | 800 | ||
797 | #[lang = "deref"] | 801 | #[lang = "deref"] |
798 | pub trait Deref { | 802 | pub trait Deref { |
799 | type Target; | 803 | type Target; |
800 | } | 804 | } |
801 | 805 | ||
802 | impl<T> Deref for Vec<T> { | 806 | impl<T> Deref for Vec<T> { |
803 | type Target = [T]; | 807 | type Target = [T]; |
804 | } | 808 | } |
805 | 809 | ||
806 | fn 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 | ||
808 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer}; | 3 | use super::{check_infer, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_box() { | 6 | fn infer_box() { |
@@ -45,43 +45,44 @@ fn test() { | |||
45 | 45 | ||
46 | #[test] | 46 | #[test] |
47 | fn self_in_struct_lit() { | 47 | fn self_in_struct_lit() { |
48 | assert_snapshot!(infer( | 48 | check_infer( |
49 | r#" | 49 | r#" |
50 | //- /main.rs | 50 | //- /main.rs |
51 | struct S<T> { x: T } | 51 | struct S<T> { x: T } |
52 | 52 | ||
53 | impl 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] |
67 | fn type_alias_in_struct_lit() { | 68 | fn type_alias_in_struct_lit() { |
68 | assert_snapshot!(infer( | 69 | check_infer( |
69 | r#" | 70 | r#" |
70 | //- /main.rs | 71 | //- /main.rs |
71 | struct S<T> { x: T } | 72 | struct S<T> { x: T } |
72 | 73 | ||
73 | type SS = S<u32>; | 74 | type SS = S<u32>; |
74 | 75 | ||
75 | fn 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] |
150 | fn infer_basics() { | 151 | fn infer_basics() { |
151 | assert_snapshot!( | 152 | check_infer( |
152 | infer(r#" | 153 | r#" |
153 | fn 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] |
182 | fn infer_let() { | 183 | fn infer_let() { |
183 | assert_snapshot!( | 184 | check_infer( |
184 | infer(r#" | 185 | r#" |
185 | fn 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] |
211 | fn infer_paths() { | 212 | fn infer_paths() { |
212 | assert_snapshot!( | 213 | check_infer( |
213 | infer(r#" | 214 | r#" |
214 | fn a() -> u32 { 1 } | 215 | fn a() -> u32 { 1 } |
215 | 216 | ||
216 | mod b { | 217 | mod b { |
217 | fn c() -> u32 { 1 } | 218 | fn c() -> u32 { 1 } |
218 | } | 219 | } |
219 | 220 | ||
220 | fn 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] |
240 | fn infer_path_type() { | 241 | fn infer_path_type() { |
241 | assert_snapshot!( | 242 | check_infer( |
242 | infer(r#" | 243 | r#" |
243 | struct S; | 244 | struct S; |
244 | 245 | ||
245 | impl S { | 246 | impl S { |
246 | fn foo() -> i32 { 1 } | 247 | fn foo() -> i32 { 1 } |
247 | } | 248 | } |
248 | 249 | ||
249 | fn 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] |
267 | fn infer_struct() { | 268 | fn infer_struct() { |
268 | assert_snapshot!( | 269 | check_infer( |
269 | infer(r#" | 270 | r#" |
270 | struct A { | 271 | struct A { |
271 | b: B, | 272 | b: B, |
272 | c: C, | 273 | c: C, |
273 | } | 274 | } |
274 | struct B; | 275 | struct B; |
275 | struct C(usize); | 276 | struct C(usize); |
276 | 277 | ||
277 | fn 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] |
307 | fn infer_enum() { | 308 | fn infer_enum() { |
308 | assert_snapshot!( | 309 | check_infer( |
309 | infer(r#" | 310 | r#" |
310 | enum E { | 311 | enum E { |
311 | V1 { field: u32 }, | 312 | V1 { field: u32 }, |
312 | V2 | 313 | V2 |
313 | } | 314 | } |
314 | fn 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] |
328 | fn infer_union() { | 329 | fn infer_union() { |
329 | assert_snapshot!( | 330 | check_infer( |
330 | infer(r#" | 331 | r#" |
331 | union MyUnion { | 332 | union MyUnion { |
332 | foo: u32, | 333 | foo: u32, |
333 | bar: f32, | 334 | bar: f32, |
334 | } | 335 | } |
335 | 336 | ||
336 | unsafe 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] |
351 | fn infer_refs() { | 352 | fn infer_refs() { |
352 | assert_snapshot!( | 353 | check_infer( |
353 | infer(r#" | 354 | r#" |
354 | fn 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] |
397 | fn infer_raw_ref() { | 398 | fn infer_raw_ref() { |
398 | assert_snapshot!( | 399 | check_infer( |
399 | infer(r#" | 400 | r#" |
400 | fn 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] |
417 | fn infer_literals() { | 418 | fn infer_literals() { |
418 | assert_snapshot!( | 419 | check_infer( |
419 | infer(r##" | 420 | r##" |
420 | fn 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] |
460 | fn infer_unary_op() { | 461 | fn infer_unary_op() { |
461 | assert_snapshot!( | 462 | check_infer( |
462 | infer(r#" | 463 | r#" |
463 | enum SomeType {} | 464 | enum SomeType {} |
464 | 465 | ||
465 | fn 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] |
530 | fn infer_backwards() { | 531 | fn infer_backwards() { |
531 | assert_snapshot!( | 532 | check_infer( |
532 | infer(r#" | 533 | r#" |
533 | fn takes_u32(x: u32) {} | 534 | fn takes_u32(x: u32) {} |
534 | 535 | ||
535 | struct S { i32_field: i32 } | 536 | struct S { i32_field: i32 } |
536 | 537 | ||
537 | fn 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] |
572 | fn infer_self() { | 573 | fn infer_self() { |
573 | assert_snapshot!( | 574 | check_infer( |
574 | infer(r#" | 575 | r#" |
575 | struct S; | 576 | struct S; |
576 | 577 | ||
577 | impl 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] |
608 | fn infer_self_as_path() { | 609 | fn infer_self_as_path() { |
609 | assert_snapshot!( | 610 | check_infer( |
610 | infer(r#" | 611 | r#" |
611 | struct S1; | 612 | struct S1; |
612 | struct S2(isize); | 613 | struct S2(isize); |
613 | enum E { | 614 | enum E { |
614 | V1, | 615 | V1, |
615 | V2(u32), | 616 | V2(u32), |
616 | } | 617 | } |
617 | 618 | ||
618 | impl S1 { | 619 | impl S1 { |
619 | fn test() { | 620 | fn test() { |
620 | Self; | 621 | Self; |
621 | } | 622 | } |
622 | } | 623 | } |
623 | impl S2 { | 624 | impl S2 { |
624 | fn test() { | 625 | fn test() { |
625 | Self(1); | 626 | Self(1); |
626 | } | 627 | } |
627 | } | 628 | } |
628 | impl 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] |
652 | fn infer_binary_op() { | 653 | fn infer_binary_op() { |
653 | assert_snapshot!( | 654 | check_infer( |
654 | infer(r#" | 655 | r#" |
655 | fn f(x: bool) -> i32 { | 656 | fn f(x: bool) -> i32 { |
656 | 0i32 | 657 | 0i32 |
657 | } | 658 | } |
658 | 659 | ||
659 | fn 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] |
731 | fn infer_shift_op() { | 732 | fn infer_shift_op() { |
732 | assert_snapshot!( | 733 | check_infer( |
733 | infer(r#" | 734 | r#" |
734 | fn 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] |
752 | fn infer_field_autoderef() { | 753 | fn infer_field_autoderef() { |
753 | assert_snapshot!( | 754 | check_infer( |
754 | infer(r#" | 755 | r#" |
755 | struct A { | 756 | struct A { |
756 | b: B, | 757 | b: B, |
757 | } | 758 | } |
758 | struct B; | 759 | struct B; |
759 | 760 | ||
760 | fn 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 | ||
773 | fn 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] |
827 | fn infer_argument_autoderef() { | 828 | fn infer_argument_autoderef() { |
828 | assert_snapshot!( | 829 | check_infer( |
829 | infer(r#" | 830 | r#" |
830 | #[lang = "deref"] | 831 | #[lang = "deref"] |
831 | pub 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 | ||
836 | struct A<T>(T); | 837 | struct A<T>(T); |
837 | 838 | ||
838 | impl<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 | ||
844 | struct B<T>(T); | 845 | struct B<T>(T); |
845 | 846 | ||
846 | impl<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 | ||
853 | fn 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] |
887 | fn infer_method_argument_autoderef() { | 888 | fn infer_method_argument_autoderef() { |
888 | assert_snapshot!( | 889 | check_infer( |
889 | infer(r#" | 890 | r#" |
890 | #[lang = "deref"] | 891 | #[lang = "deref"] |
891 | pub 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 | ||
896 | struct A<T>(*mut T); | 897 | struct A<T>(*mut T); |
897 | 898 | ||
898 | impl<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 | ||
904 | struct B<T>(T); | 905 | struct B<T>(T); |
905 | 906 | ||
906 | impl<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 | ||
913 | fn 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] |
951 | fn infer_in_elseif() { | 952 | fn infer_in_elseif() { |
952 | assert_snapshot!( | 953 | check_infer( |
953 | infer(r#" | 954 | r#" |
954 | struct Foo { field: i32 } | 955 | struct Foo { field: i32 } |
955 | fn 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] |
979 | fn infer_if_match_with_return() { | 980 | fn infer_if_match_with_return() { |
980 | assert_snapshot!( | 981 | check_infer( |
981 | infer(r#" | 982 | r#" |
982 | fn 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] |
1042 | fn infer_inherent_method() { | 1043 | fn infer_inherent_method() { |
1043 | assert_snapshot!( | 1044 | check_infer( |
1044 | infer(r#" | 1045 | r#" |
1045 | struct A; | 1046 | struct A; |
1046 | 1047 | ||
1047 | impl A { | 1048 | impl A { |
1048 | fn foo(self, x: u32) -> i32 {} | 1049 | fn foo(self, x: u32) -> i32 {} |
1049 | } | 1050 | } |
1050 | 1051 | ||
1051 | mod 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 | ||
1057 | fn 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] |
1087 | fn infer_inherent_method_str() { | 1088 | fn infer_inherent_method_str() { |
1088 | assert_snapshot!( | 1089 | check_infer( |
1089 | infer(r#" | 1090 | r#" |
1090 | #[lang = "str"] | 1091 | #[lang = "str"] |
1091 | impl str { | 1092 | impl str { |
1092 | fn foo(&self) -> i32 {} | 1093 | fn foo(&self) -> i32 {} |
1093 | } | 1094 | } |
1094 | 1095 | ||
1095 | fn 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] |
1110 | fn infer_tuple() { | 1111 | fn infer_tuple() { |
1111 | assert_snapshot!( | 1112 | check_infer( |
1112 | infer(r#" | 1113 | r#" |
1113 | fn 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] |
1155 | fn infer_array() { | 1156 | fn infer_array() { |
1156 | assert_snapshot!( | 1157 | check_infer( |
1157 | infer(r#" | 1158 | r#" |
1158 | fn 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] |
1234 | fn infer_struct_generics() { | 1235 | fn infer_struct_generics() { |
1235 | assert_snapshot!( | 1236 | check_infer( |
1236 | infer(r#" | 1237 | r#" |
1237 | struct A<T> { | 1238 | struct A<T> { |
1238 | x: T, | 1239 | x: T, |
1239 | } | 1240 | } |
1240 | 1241 | ||
1241 | fn 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] |
1270 | fn infer_tuple_struct_generics() { | 1271 | fn infer_tuple_struct_generics() { |
1271 | assert_snapshot!( | 1272 | check_infer( |
1272 | infer(r#" | 1273 | r#" |
1273 | struct A<T>(T); | 1274 | struct A<T>(T); |
1274 | enum Option<T> { Some(T), None } | 1275 | enum Option<T> { Some(T), None } |
1275 | use Option::*; | 1276 | use Option::*; |
1276 | 1277 | ||
1277 | fn 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] |
1308 | fn infer_function_generics() { | 1309 | fn infer_function_generics() { |
1309 | assert_snapshot!( | 1310 | check_infer( |
1310 | infer(r#" | 1311 | r#" |
1311 | fn id<T>(t: T) -> T { t } | 1312 | fn id<T>(t: T) -> T { t } |
1312 | 1313 | ||
1313 | fn 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] |
1339 | fn infer_impl_generics_basic() { | 1340 | fn infer_impl_generics_basic() { |
1340 | assert_snapshot!( | 1341 | check_infer( |
1341 | infer(r#" | 1342 | r#" |
1342 | struct A<T1, T2> { | 1343 | struct A<T1, T2> { |
1343 | x: T1, | 1344 | x: T1, |
1344 | y: T2, | 1345 | y: T2, |
1345 | } | 1346 | } |
1346 | impl<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 | ||
1358 | fn 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] |
1404 | fn infer_impl_generics_with_autoderef() { | 1405 | fn infer_impl_generics_with_autoderef() { |
1405 | assert_snapshot!( | 1406 | check_infer( |
1406 | infer(r#" | 1407 | r#" |
1407 | enum Option<T> { | 1408 | enum Option<T> { |
1408 | Some(T), | 1409 | Some(T), |
1409 | None, | 1410 | None, |
1410 | } | 1411 | } |
1411 | impl<T> Option<T> { | 1412 | impl<T> Option<T> { |
1412 | fn as_ref(&self) -> Option<&T> {} | 1413 | fn as_ref(&self) -> Option<&T> {} |
1413 | } | 1414 | } |
1414 | fn 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] |
1434 | fn infer_generic_chain() { | 1435 | fn infer_generic_chain() { |
1435 | assert_snapshot!( | 1436 | check_infer( |
1436 | infer(r#" | 1437 | r#" |
1437 | struct A<T> { | 1438 | struct A<T> { |
1438 | x: T, | 1439 | x: T, |
1439 | } | 1440 | } |
1440 | impl<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 | } |
1445 | fn id<T>(t: T) -> T { t } | 1446 | fn id<T>(t: T) -> T { t } |
1446 | 1447 | ||
1447 | fn 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] |
1491 | fn infer_associated_const() { | 1492 | fn infer_associated_const() { |
1492 | assert_snapshot!( | 1493 | check_infer( |
1493 | infer(r#" | 1494 | r#" |
1494 | struct Struct; | 1495 | struct Struct; |
1495 | 1496 | ||
1496 | impl Struct { | 1497 | impl Struct { |
1497 | const FOO: u32 = 1; | 1498 | const FOO: u32 = 1; |
1498 | } | 1499 | } |
1499 | 1500 | ||
1500 | enum Enum {} | 1501 | enum Enum {} |
1501 | 1502 | ||
1502 | impl Enum { | 1503 | impl Enum { |
1503 | const BAR: u32 = 2; | 1504 | const BAR: u32 = 2; |
1504 | } | 1505 | } |
1505 | 1506 | ||
1506 | trait Trait { | 1507 | trait Trait { |
1507 | const ID: u32; | 1508 | const ID: u32; |
1508 | } | 1509 | } |
1509 | 1510 | ||
1510 | struct TraitTest; | 1511 | struct TraitTest; |
1511 | 1512 | ||
1512 | impl Trait for TraitTest { | 1513 | impl Trait for TraitTest { |
1513 | const ID: u32 = 5; | 1514 | const ID: u32 = 5; |
1514 | } | 1515 | } |
1515 | 1516 | ||
1516 | fn 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] |
1538 | fn infer_type_alias() { | 1539 | fn infer_type_alias() { |
1539 | assert_snapshot!( | 1540 | check_infer( |
1540 | infer(r#" | 1541 | r#" |
1541 | struct A<X, Y> { x: X, y: Y } | 1542 | struct A<X, Y> { x: X, y: Y } |
1542 | type Foo = A<u32, i128>; | 1543 | type Foo = A<u32, i128>; |
1543 | type Bar<T> = A<T, u128>; | 1544 | type Bar<T> = A<T, u128>; |
1544 | type Baz<U, V> = A<V, U>; | 1545 | type Baz<U, V> = A<V, U>; |
1545 | fn 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] |
1576 | fn recursive_type_alias() { | 1577 | fn recursive_type_alias() { |
1577 | assert_snapshot!( | 1578 | check_infer( |
1578 | infer(r#" | 1579 | r#" |
1579 | struct A<X> {} | 1580 | struct A<X> {} |
1580 | type Foo = Foo; | 1581 | type Foo = Foo; |
1581 | type Bar = A<Bar>; | 1582 | type Bar = A<Bar>; |
1582 | fn 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] |
1592 | fn infer_type_param() { | 1593 | fn infer_type_param() { |
1593 | assert_snapshot!( | 1594 | check_infer( |
1594 | infer(r#" | 1595 | r#" |
1595 | fn id<T>(x: T) -> T { | 1596 | fn id<T>(x: T) -> T { |
1596 | x | 1597 | x |
1597 | } | 1598 | } |
1598 | 1599 | ||
1599 | fn clone<T>(x: &T) -> T { | 1600 | fn clone<T>(x: &T) -> T { |
1600 | *x | 1601 | *x |
1601 | } | 1602 | } |
1602 | 1603 | ||
1603 | fn 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] |
1636 | fn infer_const() { | 1637 | fn infer_const() { |
1637 | assert_snapshot!( | 1638 | check_infer( |
1638 | infer(r#" | 1639 | r#" |
1639 | struct Foo; | 1640 | struct Foo; |
1640 | impl Foo { const ASSOC_CONST: u32 = 0; } | 1641 | impl Foo { const ASSOC_CONST: u32 = 0; } |
1641 | const GLOBAL_CONST: u32 = 101; | 1642 | const GLOBAL_CONST: u32 = 101; |
1642 | fn 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] |
1665 | fn infer_static() { | 1666 | fn infer_static() { |
1666 | assert_snapshot!( | 1667 | check_infer( |
1667 | infer(r#" | 1668 | r#" |
1668 | static GLOBAL_STATIC: u32 = 101; | 1669 | static GLOBAL_STATIC: u32 = 101; |
1669 | static mut GLOBAL_STATIC_MUT: u32 = 101; | 1670 | static mut GLOBAL_STATIC_MUT: u32 = 101; |
1670 | fn 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] |
1779 | fn closure_return() { | 1780 | fn closure_return() { |
1780 | assert_snapshot!( | 1781 | check_infer( |
1781 | infer(r#" | 1782 | r#" |
1782 | fn 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] |
1798 | fn closure_return_unit() { | 1799 | fn closure_return_unit() { |
1799 | assert_snapshot!( | 1800 | check_infer( |
1800 | infer(r#" | 1801 | r#" |
1801 | fn 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] |
1816 | fn closure_return_inferred() { | 1817 | fn closure_return_inferred() { |
1817 | assert_snapshot!( | 1818 | check_infer( |
1818 | infer(r#" | 1819 | r#" |
1819 | fn 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] |
1834 | fn fn_pointer_return() { | 1835 | fn fn_pointer_return() { |
1835 | assert_snapshot!( | 1836 | check_infer( |
1836 | infer(r#" | 1837 | r#" |
1837 | struct Vtable { | 1838 | struct Vtable { |
1838 | method: fn(), | 1839 | method: fn(), |
1839 | } | 1840 | } |
1840 | 1841 | ||
1841 | fn 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] |
1860 | fn effects_smoke_test() { | 1861 | fn effects_smoke_test() { |
1861 | assert_snapshot!( | 1862 | check_infer( |
1862 | infer(r#" | 1863 | r#" |
1863 | fn 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] |
1893 | fn infer_generic_from_later_assignment() { | 1894 | fn infer_generic_from_later_assignment() { |
1894 | assert_snapshot!( | 1895 | check_infer( |
1895 | infer(r#" | 1896 | r#" |
1896 | enum Option<T> { Some(T), None } | 1897 | enum Option<T> { Some(T), None } |
1897 | use Option::*; | 1898 | use Option::*; |
1898 | 1899 | ||
1899 | fn 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] |
1922 | fn infer_loop_break_with_val() { | 1923 | fn infer_loop_break_with_val() { |
1923 | assert_snapshot!( | 1924 | check_infer( |
1924 | infer(r#" | 1925 | r#" |
1925 | enum Option<T> { Some(T), None } | 1926 | enum Option<T> { Some(T), None } |
1926 | use Option::*; | 1927 | use Option::*; |
1927 | 1928 | ||
1928 | fn 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] |
1957 | fn infer_loop_break_without_val() { | 1958 | fn infer_loop_break_without_val() { |
1958 | assert_snapshot!( | 1959 | check_infer( |
1959 | infer(r#" | 1960 | r#" |
1960 | enum Option<T> { Some(T), None } | 1961 | enum Option<T> { Some(T), None } |
1961 | use Option::*; | 1962 | use Option::*; |
1962 | 1963 | ||
1963 | fn 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] |
1985 | fn infer_labelled_break_with_val() { | 1986 | fn infer_labelled_break_with_val() { |
1986 | assert_snapshot!( | 1987 | check_infer( |
1987 | infer(r#" | 1988 | r#" |
1988 | fn 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] |
2039 | fn generic_default() { | 2040 | fn generic_default() { |
2040 | assert_snapshot!( | 2041 | check_infer( |
2041 | infer(r#" | 2042 | r#" |
2042 | struct Thing<T = ()> { t: T } | 2043 | struct Thing<T = ()> { t: T } |
2043 | enum OtherThing<T = ()> { | 2044 | enum OtherThing<T = ()> { |
2044 | One { t: T }, | 2045 | One { t: T }, |
2045 | Two(T), | 2046 | Two(T), |
2046 | } | 2047 | } |
2047 | 2048 | ||
2048 | fn 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] |
2096 | fn generic_default_in_struct_literal() { | 2097 | fn generic_default_in_struct_literal() { |
2097 | assert_snapshot!( | 2098 | check_infer( |
2098 | infer(r#" | 2099 | r#" |
2099 | struct Thing<T = ()> { t: T } | 2100 | struct Thing<T = ()> { t: T } |
2100 | enum OtherThing<T = ()> { | 2101 | enum OtherThing<T = ()> { |
2101 | One { t: T }, | 2102 | One { t: T }, |
2102 | Two(T), | 2103 | Two(T), |
2103 | } | 2104 | } |
2104 | 2105 | ||
2105 | fn 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] |
2147 | fn generic_default_depending_on_other_type_arg() { | 2148 | fn generic_default_depending_on_other_type_arg() { |
2148 | assert_snapshot!( | 2149 | // FIXME: the {unknown} is a bug |
2149 | infer(r#" | 2150 | check_infer( |
2150 | struct Thing<T = u128, F = fn() -> T> { t: T } | 2151 | r#" |
2151 | 2152 | struct Thing<T = u128, F = fn() -> T> { t: T } | |
2152 | fn 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] |
2172 | fn generic_default_depending_on_other_type_arg_forward() { | 2173 | fn 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 |
2175 | struct Thing<F = fn() -> T, T = u128> { t: T } | 2176 | check_infer( |
2176 | 2177 | r#" | |
2177 | fn 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 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{check_types, infer, infer_with_mismatches}; | 4 | use super::{check_infer, check_infer_with_mismatches, check_types}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn infer_await() { | 7 | fn 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 |
40 | async fn foo() -> u64 { | 40 | async fn foo() -> u64 { |
41 | 128 | 41 | 128 |
42 | } | 42 | } |
43 | 43 | ||
44 | fn test() { | 44 | fn 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 |
67 | async fn foo() -> u64 { | 67 | async fn foo() -> u64 { |
68 | 128 | 68 | 128 |
69 | } | 69 | } |
70 | 70 | ||
71 | fn test() { | 71 | fn test() { |
@@ -222,291 +222,291 @@ mod ops { | |||
222 | 222 | ||
223 | #[test] | 223 | #[test] |
224 | fn infer_from_bound_1() { | 224 | fn infer_from_bound_1() { |
225 | assert_snapshot!( | 225 | check_infer( |
226 | infer(r#" | 226 | r#" |
227 | trait Trait<T> {} | 227 | trait Trait<T> {} |
228 | struct S<T>(T); | 228 | struct S<T>(T); |
229 | impl<U> Trait<U> for S<U> {} | 229 | impl<U> Trait<U> for S<U> {} |
230 | fn foo<T: Trait<u32>>(t: T) {} | 230 | fn foo<T: Trait<u32>>(t: T) {} |
231 | fn 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] |
252 | fn infer_from_bound_2() { | 252 | fn infer_from_bound_2() { |
253 | assert_snapshot!( | 253 | check_infer( |
254 | infer(r#" | 254 | r#" |
255 | trait Trait<T> {} | 255 | trait Trait<T> {} |
256 | struct S<T>(T); | 256 | struct S<T>(T); |
257 | impl<U> Trait<U> for S<U> {} | 257 | impl<U> Trait<U> for S<U> {} |
258 | fn foo<U, T: Trait<U>>(t: T) -> U {} | 258 | fn foo<U, T: Trait<U>>(t: T) -> U {} |
259 | fn 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] |
281 | fn trait_default_method_self_bound_implements_trait() { | 281 | fn 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#" |
285 | trait 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] |
304 | fn trait_default_method_self_bound_implements_super_trait() { | 304 | fn trait_default_method_self_bound_implements_super_trait() { |
305 | assert_snapshot!( | 305 | check_infer( |
306 | infer(r#" | 306 | r#" |
307 | trait SuperTrait { | 307 | trait SuperTrait { |
308 | fn foo(&self) -> i64; | 308 | fn foo(&self) -> i64; |
309 | } | 309 | } |
310 | trait 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] |
328 | fn infer_project_associated_type() { | 328 | fn infer_project_associated_type() { |
329 | assert_snapshot!( | 329 | check_infer( |
330 | infer(r#" | 330 | r#" |
331 | trait Iterable { | 331 | trait Iterable { |
332 | type Item; | 332 | type Item; |
333 | } | 333 | } |
334 | struct S; | 334 | struct S; |
335 | impl Iterable for S { type Item = u32; } | 335 | impl Iterable for S { type Item = u32; } |
336 | fn 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] |
358 | fn infer_return_associated_type() { | 358 | fn infer_return_associated_type() { |
359 | assert_snapshot!( | 359 | check_infer( |
360 | infer(r#" | 360 | r#" |
361 | trait Iterable { | 361 | trait Iterable { |
362 | type Item; | 362 | type Item; |
363 | } | 363 | } |
364 | struct S; | 364 | struct S; |
365 | impl Iterable for S { type Item = u32; } | 365 | impl Iterable for S { type Item = u32; } |
366 | fn foo1<T: Iterable>(t: T) -> T::Item {} | 366 | fn foo1<T: Iterable>(t: T) -> T::Item {} |
367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} | 367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} |
368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} | 368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} |
369 | fn 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] |
400 | fn infer_associated_type_bound() { | 400 | fn infer_associated_type_bound() { |
401 | assert_snapshot!( | 401 | check_infer( |
402 | infer(r#" | 402 | r#" |
403 | trait Iterable { | 403 | trait Iterable { |
404 | type Item; | 404 | type Item; |
405 | } | 405 | } |
406 | fn 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] |
419 | fn infer_const_body() { | 419 | fn infer_const_body() { |
420 | assert_snapshot!( | 420 | check_infer( |
421 | infer(r#" | 421 | r#" |
422 | const A: u32 = 1 + 1; | 422 | const A: u32 = 1 + 1; |
423 | static 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] |
438 | fn tuple_struct_fields() { | 438 | fn tuple_struct_fields() { |
439 | assert_snapshot!( | 439 | check_infer( |
440 | infer(r#" | 440 | r#" |
441 | struct S(i32, u64); | 441 | struct S(i32, u64); |
442 | fn 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] |
465 | fn tuple_struct_with_fn() { | 465 | fn tuple_struct_with_fn() { |
466 | assert_snapshot!( | 466 | check_infer( |
467 | infer(r#" | 467 | r#" |
468 | struct S(fn(u32) -> u64); | 468 | struct S(fn(u32) -> u64); |
469 | fn 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] |
499 | fn indexing_arrays() { | 499 | fn 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] |
910 | fn argument_impl_trait() { | 910 | fn argument_impl_trait() { |
911 | assert_snapshot!( | 911 | check_infer_with_mismatches( |
912 | infer_with_mismatches(r#" | 912 | r#" |
913 | trait 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 | } |
917 | fn bar(x: impl Trait<u16>) {} | 917 | fn bar(x: impl Trait<u16>) {} |
918 | struct S<T>(T); | 918 | struct S<T>(T); |
919 | impl<T> Trait<T> for S<T> {} | 919 | impl<T> Trait<T> for S<T> {} |
920 | 920 | ||
921 | fn 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] |
968 | fn argument_impl_trait_type_args_1() { | 968 | fn argument_impl_trait_type_args_1() { |
969 | assert_snapshot!( | 969 | check_infer_with_mismatches( |
970 | infer_with_mismatches(r#" | 970 | r#" |
971 | trait Trait {} | 971 | trait Trait {} |
972 | trait 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 | } |
977 | fn foo<T>(x: impl Trait) -> T { loop {} } | 977 | fn foo<T>(x: impl Trait) -> T { loop {} } |
978 | struct S; | 978 | struct S; |
979 | impl Trait for S {} | 979 | impl Trait for S {} |
980 | struct F; | 980 | struct F; |
981 | impl Foo for F {} | 981 | impl Foo for F {} |
982 | 982 | ||
983 | fn 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] |
1034 | fn argument_impl_trait_type_args_2() { | 1034 | fn argument_impl_trait_type_args_2() { |
1035 | assert_snapshot!( | 1035 | check_infer_with_mismatches( |
1036 | infer_with_mismatches(r#" | 1036 | r#" |
1037 | trait Trait {} | 1037 | trait Trait {} |
1038 | struct S; | 1038 | struct S; |
1039 | impl Trait for S {} | 1039 | impl Trait for S {} |
1040 | struct F<T>; | 1040 | struct F<T>; |
1041 | impl<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 | ||
1045 | fn 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] |
1076 | fn argument_impl_trait_to_fn_pointer() { | 1076 | fn argument_impl_trait_to_fn_pointer() { |
1077 | assert_snapshot!( | 1077 | check_infer_with_mismatches( |
1078 | infer_with_mismatches(r#" | 1078 | r#" |
1079 | trait Trait {} | 1079 | trait Trait {} |
1080 | fn foo(x: impl Trait) { loop {} } | 1080 | fn foo(x: impl Trait) { loop {} } |
1081 | struct S; | 1081 | struct S; |
1082 | impl Trait for S {} | 1082 | impl Trait for S {} |
1083 | 1083 | ||
1084 | fn 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] |
1101 | fn impl_trait() { | 1101 | fn impl_trait() { |
1102 | assert_snapshot!( | 1102 | check_infer( |
1103 | infer(r#" | 1103 | r#" |
1104 | trait 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 | } |
1108 | fn bar() -> impl Trait<u64> {} | 1108 | fn bar() -> impl Trait<u64> {} |
1109 | 1109 | ||
1110 | fn 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] |
1151 | fn simple_return_pos_impl_trait() { | 1151 | fn 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#" |
1155 | trait Trait<T> { | 1155 | trait Trait<T> { |
1156 | fn foo(&self) -> T; | 1156 | fn foo(&self) -> T; |
1157 | } | 1157 | } |
1158 | fn bar() -> impl Trait<u64> { loop {} } | 1158 | fn bar() -> impl Trait<u64> { loop {} } |
1159 | 1159 | ||
1160 | fn 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] |
1181 | fn more_return_pos_impl_trait() { | 1181 | fn more_return_pos_impl_trait() { |
1182 | assert_snapshot!( | 1182 | check_infer( |
1183 | infer(r#" | 1183 | r#" |
1184 | trait 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 | } |
1188 | trait Trait<T> { | 1188 | trait Trait<T> { |
1189 | fn foo(&self) -> T; | 1189 | fn foo(&self) -> T; |
1190 | } | 1190 | } |
1191 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | 1191 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } |
1192 | fn 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 | ||
1194 | fn 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] |
1240 | fn dyn_trait() { | 1240 | fn dyn_trait() { |
1241 | assert_snapshot!( | 1241 | check_infer( |
1242 | infer(r#" | 1242 | r#" |
1243 | trait 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 | } |
1247 | fn bar() -> dyn Trait<u64> {} | 1247 | fn bar() -> dyn Trait<u64> {} |
1248 | 1248 | ||
1249 | fn 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] |
1290 | fn dyn_trait_in_impl() { | 1290 | fn dyn_trait_in_impl() { |
1291 | assert_snapshot!( | 1291 | check_infer( |
1292 | infer(r#" | 1292 | r#" |
1293 | trait Trait<T, U> { | 1293 | trait Trait<T, U> { |
1294 | fn foo(&self) -> (T, U); | 1294 | fn foo(&self) -> (T, U); |
1295 | } | 1295 | } |
1296 | struct S<T, U> {} | 1296 | struct S<T, U> {} |
1297 | impl<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 | } |
1300 | trait Trait2<T, U> { | 1300 | trait Trait2<T, U> { |
1301 | fn baz(&self) -> (T, U); | 1301 | fn baz(&self) -> (T, U); |
1302 | } | 1302 | } |
1303 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } | 1303 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } |
1304 | 1304 | ||
1305 | fn 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] |
1326 | fn dyn_trait_bare() { | 1326 | fn dyn_trait_bare() { |
1327 | assert_snapshot!( | 1327 | check_infer( |
1328 | infer(r#" | 1328 | r#" |
1329 | trait Trait { | 1329 | trait Trait { |
1330 | fn foo(&self) -> u64; | 1330 | fn foo(&self) -> u64; |
1331 | } | 1331 | } |
1332 | fn bar() -> Trait {} | 1332 | fn bar() -> Trait {} |
1333 | 1333 | ||
1334 | fn 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] |
1365 | fn weird_bounds() { | 1365 | fn weird_bounds() { |
1366 | assert_snapshot!( | 1366 | check_infer( |
1367 | infer(r#" | 1367 | r#" |
1368 | trait Trait {} | 1368 | trait Trait {} |
1369 | fn 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] |
1401 | fn assoc_type_bindings() { | 1400 | fn assoc_type_bindings() { |
1402 | assert_snapshot!( | 1401 | check_infer( |
1403 | infer(r#" | 1402 | r#" |
1404 | trait Trait { | 1403 | trait Trait { |
1405 | type Type; | 1404 | type Type; |
1406 | } | 1405 | } |
1407 | |||
1408 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} | ||
1409 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | ||
1410 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | ||
1411 | 1406 | ||
1412 | struct S<T>; | 1407 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} |
1413 | impl<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} | |
1415 | fn 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] |
1508 | fn projection_eq_within_chalk() { | 1507 | fn projection_eq_within_chalk() { |
1509 | assert_snapshot!( | 1508 | check_infer( |
1510 | infer(r#" | 1509 | r#" |
1511 | trait Trait1 { | 1510 | trait Trait1 { |
1512 | type Type; | 1511 | type Type; |
1513 | } | 1512 | } |
1514 | trait Trait2<T> { | 1513 | trait Trait2<T> { |
1515 | fn foo(self) -> T; | 1514 | fn foo(self) -> T; |
1516 | } | 1515 | } |
1517 | impl<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 | ||
1519 | fn 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] |
1551 | fn super_trait_method_resolution() { | 1550 | fn super_trait_method_resolution() { |
1552 | assert_snapshot!( | 1551 | check_infer( |
1553 | infer(r#" | 1552 | r#" |
1554 | mod foo { | 1553 | mod foo { |
1555 | trait SuperTrait { | 1554 | trait SuperTrait { |
1556 | fn foo(&self) -> u32 {} | 1555 | fn foo(&self) -> u32 {} |
1557 | } | 1556 | } |
1558 | } | 1557 | } |
1559 | trait Trait1: foo::SuperTrait {} | 1558 | trait Trait1: foo::SuperTrait {} |
1560 | trait Trait2 where Self: foo::SuperTrait {} | 1559 | trait Trait2 where Self: foo::SuperTrait {} |
1561 | 1560 | ||
1562 | fn 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] |
1582 | fn super_trait_impl_trait_method_resolution() { | 1581 | fn super_trait_impl_trait_method_resolution() { |
1583 | assert_snapshot!( | 1582 | check_infer( |
1584 | infer(r#" | 1583 | r#" |
1585 | mod foo { | 1584 | mod foo { |
1586 | trait SuperTrait { | 1585 | trait SuperTrait { |
1587 | fn foo(&self) -> u32 {} | 1586 | fn foo(&self) -> u32 {} |
1588 | } | 1587 | } |
1589 | } | 1588 | } |
1590 | trait Trait1: foo::SuperTrait {} | 1589 | trait Trait1: foo::SuperTrait {} |
1591 | 1590 | ||
1592 | fn 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] |
1608 | fn super_trait_cycle() { | 1607 | fn 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#" |
1612 | trait A: B {} | 1611 | trait A: B {} |
1613 | trait B: A {} | 1612 | trait B: A {} |
1614 | 1613 | ||
1615 | fn 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] |
1629 | fn super_trait_assoc_type_bounds() { | 1628 | fn super_trait_assoc_type_bounds() { |
1630 | assert_snapshot!( | 1629 | check_infer( |
1631 | infer(r#" | 1630 | r#" |
1632 | trait SuperTrait { type Type; } | 1631 | trait SuperTrait { type Type; } |
1633 | trait Trait where Self: SuperTrait {} | 1632 | trait Trait where Self: SuperTrait {} |
1634 | 1633 | ||
1635 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | 1634 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} |
1636 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | 1635 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} |
1637 | 1636 | ||
1638 | struct S<T>; | 1637 | struct S<T>; |
1639 | impl<T> SuperTrait for S<T> { type Type = T; } | 1638 | impl<T> SuperTrait for S<T> { type Type = T; } |
1640 | impl<T> Trait for S<T> {} | 1639 | impl<T> Trait for S<T> {} |
1641 | 1640 | ||
1642 | fn 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] |
1663 | fn fn_trait() { | 1662 | fn fn_trait() { |
1664 | assert_snapshot!( | 1663 | check_infer( |
1665 | infer(r#" | 1664 | r#" |
1666 | trait 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 | ||
1672 | fn 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] |
1691 | fn fn_ptr_and_item() { | 1690 | fn fn_ptr_and_item() { |
1692 | assert_snapshot!( | 1691 | check_infer( |
1693 | infer(r#" | 1692 | r#" |
1694 | #[lang="fn_once"] | 1693 | #[lang="fn_once"] |
1695 | trait 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 | ||
1701 | trait Foo<T> { | 1700 | trait Foo<T> { |
1702 | fn foo(&self) -> T; | 1701 | fn foo(&self) -> T; |
1703 | } | 1702 | } |
1704 | 1703 | ||
1705 | struct Bar<T>(T); | 1704 | struct Bar<T>(T); |
1706 | 1705 | ||
1707 | impl<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 | ||
1711 | enum Opt<T> { None, Some(T) } | 1710 | enum Opt<T> { None, Some(T) } |
1712 | impl<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 | ||
1716 | fn 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] |
1748 | fn fn_trait_deref_with_ty_default() { | 1747 | fn fn_trait_deref_with_ty_default() { |
1749 | assert_snapshot!( | 1748 | check_infer( |
1750 | infer(r#" | 1749 | r#" |
1751 | #[lang = "deref"] | 1750 | #[lang = "deref"] |
1752 | trait 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"] |
1759 | trait 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 | ||
1765 | struct Foo; | 1764 | struct Foo; |
1766 | 1765 | ||
1767 | impl Foo { | 1766 | impl Foo { |
1768 | fn foo(&self) -> usize {} | 1767 | fn foo(&self) -> usize {} |
1769 | } | 1768 | } |
1770 | 1769 | ||
1771 | struct Lazy<T, F = fn() -> T>(F); | 1770 | struct Lazy<T, F = fn() -> T>(F); |
1772 | 1771 | ||
1773 | impl<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 | ||
1777 | impl<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 | ||
1781 | fn 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] |
1823 | fn closure_1() { | 1822 | fn closure_1() { |
1824 | assert_snapshot!( | 1823 | check_infer( |
1825 | infer(r#" | 1824 | r#" |
1826 | #[lang = "fn_once"] | 1825 | #[lang = "fn_once"] |
1827 | trait FnOnce<Args> { | 1826 | trait FnOnce<Args> { |
1828 | type Output; | 1827 | type Output; |
1829 | } | 1828 | } |
1830 | 1829 | ||
1831 | enum Option<T> { Some(T), None } | 1830 | enum Option<T> { Some(T), None } |
1832 | impl<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 | ||
1836 | fn 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] |
1875 | fn closure_2() { | 1874 | fn closure_2() { |
1876 | assert_snapshot!( | 1875 | check_infer( |
1877 | infer(r#" | 1876 | r#" |
1878 | trait FnOnce<Args> { | 1877 | trait FnOnce<Args> { |
1879 | type Output; | 1878 | type Output; |
1880 | } | 1879 | } |
1881 | 1880 | ||
1882 | fn 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] |
1915 | fn closure_as_argument_inference_order() { | 1914 | fn closure_as_argument_inference_order() { |
1916 | assert_snapshot!( | 1915 | check_infer( |
1917 | infer(r#" | 1916 | r#" |
1918 | #[lang = "fn_once"] | 1917 | #[lang = "fn_once"] |
1919 | trait FnOnce<Args> { | 1918 | trait FnOnce<Args> { |
1920 | type Output; | 1919 | type Output; |
1921 | } | 1920 | } |
1922 | 1921 | ||
1923 | fn 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 {} |
1924 | fn 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 | ||
1926 | struct S; | 1925 | struct S; |
1927 | impl 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 | ||
1934 | fn 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] |
2058 | fn unselected_projection_on_impl_self() { | 2057 | fn unselected_projection_on_impl_self() { |
2059 | assert_snapshot!(infer( | 2058 | check_infer( |
2060 | r#" | 2059 | r#" |
2061 | //- /main.rs | 2060 | //- /main.rs |
2062 | trait 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 | ||
2068 | struct S; | 2067 | struct S; |
2069 | 2068 | ||
2070 | impl 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 | ||
2075 | struct S2; | 2074 | struct S2; |
2076 | 2075 | ||
2077 | impl 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] |
2263 | fn proc_macro_server_types() { | 2263 | fn proc_macro_server_types() { |
2264 | assert_snapshot!( | 2264 | check_infer( |
2265 | infer(r#" | 2265 | r#" |
2266 | macro_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 | } |
2277 | macro_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 | } |
2284 | macro_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 | ||
2301 | with_api!(Self, self_, declare_server_traits); | 2292 | $(pub trait $name: Types { |
2302 | struct G {} | 2293 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* |
2303 | struct T {} | 2294 | })* |
2304 | struct Rustc; | ||
2305 | impl Types for Rustc { | ||
2306 | type TokenStream = T; | ||
2307 | type Group = G; | ||
2308 | } | ||
2309 | 2295 | ||
2310 | fn make<T>() -> T { loop {} } | 2296 | pub trait Server: Types $(+ $name)* {} |
2311 | impl 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] |
2333 | fn unify_impl_trait() { | 2333 | fn unify_impl_trait() { |
2334 | assert_snapshot!( | 2334 | check_infer_with_mismatches( |
2335 | infer_with_mismatches(r#" | 2335 | r#" |
2336 | trait 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 | ||
2338 | fn foo(x: impl Trait<u32>) { loop {} } | 2346 | fn test() -> impl Trait<i32> { |
2339 | fn bar<T>(x: impl Trait<T>) -> T { loop {} } | 2347 | let s1 = S(default()); |
2340 | 2348 | foo(s1); | |
2341 | struct S<T>(T); | 2349 | let x: i32 = bar(S(default())); |
2342 | impl<T> Trait<T> for S<T> {} | 2350 | S(default()) |
2343 | 2351 | } | |
2344 | fn default<T>() -> T { loop {} } | 2352 | "#, |
2345 | 2353 | expect![[r#" | |
2346 | fn 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] |
2390 | fn assoc_types_from_bounds() { | 2390 | fn 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"] |
2395 | trait FnOnce<Args> { | 2395 | trait FnOnce<Args> { |
2396 | type Output; | 2396 | type Output; |
2397 | } | 2397 | } |
2398 | 2398 | ||
2399 | trait T { | 2399 | trait T { |
2400 | type O; | 2400 | type O; |
2401 | } | 2401 | } |
2402 | 2402 | ||
2403 | impl T for () { | 2403 | impl T for () { |
2404 | type O = (); | 2404 | type O = (); |
2405 | } | 2405 | } |
2406 | 2406 | ||
2407 | fn f<X, F>(_v: F) | 2407 | fn f<X, F>(_v: F) |
2408 | where | 2408 | where |
2409 | X: T, | 2409 | X: T, |
2410 | F: FnOnce(&X::O), | 2410 | F: FnOnce(&X::O), |
2411 | { } | 2411 | { } |
2412 | 2412 | ||
2413 | fn 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] |
2499 | fn iterator_chain() { | 2499 | fn 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"] |
2504 | trait FnOnce<Args> { | 2504 | trait FnOnce<Args> { |
2505 | type Output; | 2505 | type Output; |
2506 | } | 2506 | } |
2507 | #[lang = "fn_mut"] | 2507 | #[lang = "fn_mut"] |
2508 | trait FnMut<Args>: FnOnce<Args> { } | 2508 | trait FnMut<Args>: FnOnce<Args> { } |
2509 | 2509 | ||
2510 | enum Option<T> { Some(T), None } | 2510 | enum Option<T> { Some(T), None } |
2511 | use Option::*; | 2511 | use Option::*; |
2512 | 2512 | ||
2513 | pub 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 | ||
2527 | pub 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 | ||
2533 | pub struct FilterMap<I, F> { } | 2533 | pub struct FilterMap<I, F> { } |
2534 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> | 2534 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> |
2535 | where | 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")] |
2542 | impl<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 | ||
2551 | struct Vec<T> {} | 2551 | struct Vec<T> {} |
2552 | impl<T> Vec<T> { | 2552 | impl<T> Vec<T> { |
2553 | fn new() -> Self { loop {} } | 2553 | fn new() -> Self { loop {} } |
2554 | } | 2554 | } |
2555 | 2555 | ||
2556 | impl<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 | ||
2561 | pub struct IntoIter<T> { } | 2561 | pub struct IntoIter<T> { } |
2562 | impl<T> Iterator for IntoIter<T> { | 2562 | impl<T> Iterator for IntoIter<T> { |
2563 | type Item = T; | 2563 | type Item = T; |
2564 | } | 2564 | } |
2565 | 2565 | ||
2566 | fn 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] |
2650 | fn trait_object_no_coercion() { | 2650 | fn trait_object_no_coercion() { |
2651 | assert_snapshot!( | 2651 | check_infer_with_mismatches( |
2652 | infer_with_mismatches(r#" | 2652 | r#" |
2653 | trait Foo {} | 2653 | trait Foo {} |
2654 | 2654 | ||
2655 | fn foo(x: &dyn Foo) {} | 2655 | fn foo(x: &dyn Foo) {} |
2656 | 2656 | ||
2657 | fn 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] |
2674 | fn builtin_copy() { | 2674 | fn builtin_copy() { |
2675 | assert_snapshot!( | 2675 | check_infer_with_mismatches( |
2676 | infer_with_mismatches(r#" | 2676 | r#" |
2677 | #[lang = "copy"] | 2677 | #[lang = "copy"] |
2678 | trait Copy {} | 2678 | trait Copy {} |
2679 | 2679 | ||
2680 | struct IsCopy; | 2680 | struct IsCopy; |
2681 | impl Copy for IsCopy {} | 2681 | impl Copy for IsCopy {} |
2682 | struct NotCopy; | 2682 | struct NotCopy; |
2683 | 2683 | ||
2684 | trait Test { fn test(&self) -> bool; } | 2684 | trait Test { fn test(&self) -> bool; } |
2685 | impl<T: Copy> Test for T {} | 2685 | impl<T: Copy> Test for T {} |
2686 | 2686 | ||
2687 | fn 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] |
2714 | fn builtin_fn_def_copy() { | 2714 | fn 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"] |
2718 | trait Copy {} | 2718 | trait Copy {} |
2719 | 2719 | ||
2720 | fn foo() {} | 2720 | fn foo() {} |
2721 | fn bar<T: Copy>(T) -> T {} | 2721 | fn bar<T: Copy>(T) -> T {} |
2722 | struct Struct(usize); | 2722 | struct Struct(usize); |
2723 | enum Enum { Variant(usize) } | 2723 | enum Enum { Variant(usize) } |
2724 | 2724 | ||
2725 | trait Test { fn test(&self) -> bool; } | 2725 | trait Test { fn test(&self) -> bool; } |
2726 | impl<T: Copy> Test for T {} | 2726 | impl<T: Copy> Test for T {} |
2727 | 2727 | ||
2728 | fn 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] |
2755 | fn builtin_fn_ptr_copy() { | 2755 | fn 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"] |
2759 | trait Copy {} | 2759 | trait Copy {} |
2760 | 2760 | ||
2761 | trait Test { fn test(&self) -> bool; } | 2761 | trait Test { fn test(&self) -> bool; } |
2762 | impl<T: Copy> Test for T {} | 2762 | impl<T: Copy> Test for T {} |
2763 | 2763 | ||
2764 | fn 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] |
2787 | fn builtin_sized() { | 2787 | fn builtin_sized() { |
2788 | assert_snapshot!( | 2788 | check_infer_with_mismatches( |
2789 | infer_with_mismatches(r#" | 2789 | r#" |
2790 | #[lang = "sized"] | 2790 | #[lang = "sized"] |
2791 | trait Sized {} | 2791 | trait Sized {} |
2792 | 2792 | ||
2793 | trait Test { fn test(&self) -> bool; } | 2793 | trait Test { fn test(&self) -> bool; } |
2794 | impl<T: Sized> Test for T {} | 2794 | impl<T: Sized> Test for T {} |
2795 | 2795 | ||
2796 | fn 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] |
2869 | fn infer_closure_arg() { | 2869 | fn 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] |
2904 | fn infer_fn_trait_arg() { | 2902 | fn 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] |
2953 | fn infer_box_fn_arg() { | 2949 | fn 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 | ||