diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/tests/method_resolution.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_ty/src/tests/method_resolution.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 1005 |
1 files changed, 1005 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs new file mode 100644 index 000000000..ce9a06fde --- /dev/null +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -0,0 +1,1005 @@ | |||
1 | use super::{infer, type_at, type_at_pos}; | ||
2 | use crate::test_db::TestDB; | ||
3 | use insta::assert_snapshot; | ||
4 | use ra_db::fixture::WithFixture; | ||
5 | |||
6 | #[test] | ||
7 | fn infer_slice_method() { | ||
8 | assert_snapshot!( | ||
9 | infer(r#" | ||
10 | #[lang = "slice"] | ||
11 | impl<T> [T] { | ||
12 | fn foo(&self) -> T { | ||
13 | loop {} | ||
14 | } | ||
15 | } | ||
16 | |||
17 | #[lang = "slice_alloc"] | ||
18 | impl<T> [T] {} | ||
19 | |||
20 | fn test() { | ||
21 | <[_]>::foo(b"foo"); | ||
22 | } | ||
23 | "#), | ||
24 | @r###" | ||
25 | [45; 49) 'self': &[T] | ||
26 | [56; 79) '{ ... }': T | ||
27 | [66; 73) 'loop {}': ! | ||
28 | [71; 73) '{}': () | ||
29 | [133; 160) '{ ...o"); }': () | ||
30 | [139; 149) '<[_]>::foo': fn foo<u8>(&[T]) -> T | ||
31 | [139; 157) '<[_]>:..."foo")': u8 | ||
32 | [150; 156) 'b"foo"': &[u8] | ||
33 | "### | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | #[test] | ||
38 | fn infer_associated_method_struct() { | ||
39 | assert_snapshot!( | ||
40 | infer(r#" | ||
41 | struct A { x: u32 } | ||
42 | |||
43 | impl A { | ||
44 | fn new() -> A { | ||
45 | A { x: 0 } | ||
46 | } | ||
47 | } | ||
48 | fn test() { | ||
49 | let a = A::new(); | ||
50 | a.x; | ||
51 | } | ||
52 | "#), | ||
53 | @r###" | ||
54 | [49; 75) '{ ... }': A | ||
55 | [59; 69) 'A { x: 0 }': A | ||
56 | [66; 67) '0': u32 | ||
57 | [88; 122) '{ ...a.x; }': () | ||
58 | [98; 99) 'a': A | ||
59 | [102; 108) 'A::new': fn new() -> A | ||
60 | [102; 110) 'A::new()': A | ||
61 | [116; 117) 'a': A | ||
62 | [116; 119) 'a.x': u32 | ||
63 | "### | ||
64 | ); | ||
65 | } | ||
66 | |||
67 | #[test] | ||
68 | fn infer_associated_method_enum() { | ||
69 | assert_snapshot!( | ||
70 | infer(r#" | ||
71 | enum A { B, C } | ||
72 | |||
73 | impl A { | ||
74 | pub fn b() -> A { | ||
75 | A::B | ||
76 | } | ||
77 | pub fn c() -> A { | ||
78 | A::C | ||
79 | } | ||
80 | } | ||
81 | fn test() { | ||
82 | let a = A::b(); | ||
83 | a; | ||
84 | let c = A::c(); | ||
85 | c; | ||
86 | } | ||
87 | "#), | ||
88 | @r###" | ||
89 | [47; 67) '{ ... }': A | ||
90 | [57; 61) 'A::B': A | ||
91 | [88; 108) '{ ... }': A | ||
92 | [98; 102) 'A::C': A | ||
93 | [121; 178) '{ ... c; }': () | ||
94 | [131; 132) 'a': A | ||
95 | [135; 139) 'A::b': fn b() -> A | ||
96 | [135; 141) 'A::b()': A | ||
97 | [147; 148) 'a': A | ||
98 | [158; 159) 'c': A | ||
99 | [162; 166) 'A::c': fn c() -> A | ||
100 | [162; 168) 'A::c()': A | ||
101 | [174; 175) 'c': A | ||
102 | "### | ||
103 | ); | ||
104 | } | ||
105 | |||
106 | #[test] | ||
107 | fn infer_associated_method_with_modules() { | ||
108 | assert_snapshot!( | ||
109 | infer(r#" | ||
110 | mod a { | ||
111 | struct A; | ||
112 | impl A { pub fn thing() -> A { A {} }} | ||
113 | } | ||
114 | |||
115 | mod b { | ||
116 | struct B; | ||
117 | impl B { pub fn thing() -> u32 { 99 }} | ||
118 | |||
119 | mod c { | ||
120 | struct C; | ||
121 | impl C { pub fn thing() -> C { C {} }} | ||
122 | } | ||
123 | } | ||
124 | use b::c; | ||
125 | |||
126 | fn test() { | ||
127 | let x = a::A::thing(); | ||
128 | let y = b::B::thing(); | ||
129 | let z = c::C::thing(); | ||
130 | } | ||
131 | "#), | ||
132 | @r###" | ||
133 | [56; 64) '{ A {} }': A | ||
134 | [58; 62) 'A {}': A | ||
135 | [126; 132) '{ 99 }': u32 | ||
136 | [128; 130) '99': u32 | ||
137 | [202; 210) '{ C {} }': C | ||
138 | [204; 208) 'C {}': C | ||
139 | [241; 325) '{ ...g(); }': () | ||
140 | [251; 252) 'x': A | ||
141 | [255; 266) 'a::A::thing': fn thing() -> A | ||
142 | [255; 268) 'a::A::thing()': A | ||
143 | [278; 279) 'y': u32 | ||
144 | [282; 293) 'b::B::thing': fn thing() -> u32 | ||
145 | [282; 295) 'b::B::thing()': u32 | ||
146 | [305; 306) 'z': C | ||
147 | [309; 320) 'c::C::thing': fn thing() -> C | ||
148 | [309; 322) 'c::C::thing()': C | ||
149 | "### | ||
150 | ); | ||
151 | } | ||
152 | |||
153 | #[test] | ||
154 | fn infer_associated_method_generics() { | ||
155 | assert_snapshot!( | ||
156 | infer(r#" | ||
157 | struct Gen<T> { | ||
158 | val: T | ||
159 | } | ||
160 | |||
161 | impl<T> Gen<T> { | ||
162 | pub fn make(val: T) -> Gen<T> { | ||
163 | Gen { val } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | fn test() { | ||
168 | let a = Gen::make(0u32); | ||
169 | } | ||
170 | "#), | ||
171 | @r###" | ||
172 | [64; 67) 'val': T | ||
173 | [82; 109) '{ ... }': Gen<T> | ||
174 | [92; 103) 'Gen { val }': Gen<T> | ||
175 | [98; 101) 'val': T | ||
176 | [123; 155) '{ ...32); }': () | ||
177 | [133; 134) 'a': Gen<u32> | ||
178 | [137; 146) 'Gen::make': fn make<u32>(T) -> Gen<T> | ||
179 | [137; 152) 'Gen::make(0u32)': Gen<u32> | ||
180 | [147; 151) '0u32': u32 | ||
181 | "### | ||
182 | ); | ||
183 | } | ||
184 | |||
185 | #[test] | ||
186 | fn infer_associated_method_generics_with_default_param() { | ||
187 | assert_snapshot!( | ||
188 | infer(r#" | ||
189 | struct Gen<T=u32> { | ||
190 | val: T | ||
191 | } | ||
192 | |||
193 | impl<T> Gen<T> { | ||
194 | pub fn make() -> Gen<T> { | ||
195 | loop { } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | fn test() { | ||
200 | let a = Gen::make(); | ||
201 | } | ||
202 | "#), | ||
203 | @r###" | ||
204 | [80; 104) '{ ... }': Gen<T> | ||
205 | [90; 98) 'loop { }': ! | ||
206 | [95; 98) '{ }': () | ||
207 | [118; 146) '{ ...e(); }': () | ||
208 | [128; 129) 'a': Gen<u32> | ||
209 | [132; 141) 'Gen::make': fn make<u32>() -> Gen<T> | ||
210 | [132; 143) 'Gen::make()': Gen<u32> | ||
211 | "### | ||
212 | ); | ||
213 | } | ||
214 | |||
215 | #[test] | ||
216 | fn infer_associated_method_generics_with_default_tuple_param() { | ||
217 | let t = type_at( | ||
218 | r#" | ||
219 | //- /main.rs | ||
220 | struct Gen<T=()> { | ||
221 | val: T | ||
222 | } | ||
223 | |||
224 | impl<T> Gen<T> { | ||
225 | pub fn make() -> Gen<T> { | ||
226 | loop { } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | fn test() { | ||
231 | let a = Gen::make(); | ||
232 | a.val<|>; | ||
233 | } | ||
234 | "#, | ||
235 | ); | ||
236 | assert_eq!(t, "()"); | ||
237 | } | ||
238 | |||
239 | #[test] | ||
240 | fn infer_associated_method_generics_without_args() { | ||
241 | assert_snapshot!( | ||
242 | infer(r#" | ||
243 | struct Gen<T> { | ||
244 | val: T | ||
245 | } | ||
246 | |||
247 | impl<T> Gen<T> { | ||
248 | pub fn make() -> Gen<T> { | ||
249 | loop { } | ||
250 | } | ||
251 | } | ||
252 | |||
253 | fn test() { | ||
254 | let a = Gen::<u32>::make(); | ||
255 | } | ||
256 | "#), | ||
257 | @r###" | ||
258 | [76; 100) '{ ... }': Gen<T> | ||
259 | [86; 94) 'loop { }': ! | ||
260 | [91; 94) '{ }': () | ||
261 | [114; 149) '{ ...e(); }': () | ||
262 | [124; 125) 'a': Gen<u32> | ||
263 | [128; 144) 'Gen::<...::make': fn make<u32>() -> Gen<T> | ||
264 | [128; 146) 'Gen::<...make()': Gen<u32> | ||
265 | "### | ||
266 | ); | ||
267 | } | ||
268 | |||
269 | #[test] | ||
270 | fn infer_associated_method_generics_2_type_params_without_args() { | ||
271 | assert_snapshot!( | ||
272 | infer(r#" | ||
273 | struct Gen<T, U> { | ||
274 | val: T, | ||
275 | val2: U, | ||
276 | } | ||
277 | |||
278 | impl<T> Gen<u32, T> { | ||
279 | pub fn make() -> Gen<u32,T> { | ||
280 | loop { } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | fn test() { | ||
285 | let a = Gen::<u32, u64>::make(); | ||
286 | } | ||
287 | "#), | ||
288 | @r###" | ||
289 | [102; 126) '{ ... }': Gen<u32, T> | ||
290 | [112; 120) 'loop { }': ! | ||
291 | [117; 120) '{ }': () | ||
292 | [140; 180) '{ ...e(); }': () | ||
293 | [150; 151) 'a': Gen<u32, u64> | ||
294 | [154; 175) 'Gen::<...::make': fn make<u64>() -> Gen<u32, T> | ||
295 | [154; 177) 'Gen::<...make()': Gen<u32, u64> | ||
296 | "### | ||
297 | ); | ||
298 | } | ||
299 | |||
300 | #[test] | ||
301 | fn cross_crate_associated_method_call() { | ||
302 | let (db, pos) = TestDB::with_position( | ||
303 | r#" | ||
304 | //- /main.rs crate:main deps:other_crate | ||
305 | fn test() { | ||
306 | let x = other_crate::foo::S::thing(); | ||
307 | x<|>; | ||
308 | } | ||
309 | |||
310 | //- /lib.rs crate:other_crate | ||
311 | mod foo { | ||
312 | struct S; | ||
313 | impl S { | ||
314 | fn thing() -> i128 {} | ||
315 | } | ||
316 | } | ||
317 | "#, | ||
318 | ); | ||
319 | assert_eq!("i128", type_at_pos(&db, pos)); | ||
320 | } | ||
321 | |||
322 | #[test] | ||
323 | fn infer_trait_method_simple() { | ||
324 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
325 | assert_snapshot!( | ||
326 | infer(r#" | ||
327 | trait Trait1 { | ||
328 | fn method(&self) -> u32; | ||
329 | } | ||
330 | struct S1; | ||
331 | impl Trait1 for S1 {} | ||
332 | trait Trait2 { | ||
333 | fn method(&self) -> i128; | ||
334 | } | ||
335 | struct S2; | ||
336 | impl Trait2 for S2 {} | ||
337 | fn test() { | ||
338 | S1.method(); // -> u32 | ||
339 | S2.method(); // -> i128 | ||
340 | } | ||
341 | "#), | ||
342 | @r###" | ||
343 | [31; 35) 'self': &Self | ||
344 | [110; 114) 'self': &Self | ||
345 | [170; 228) '{ ...i128 }': () | ||
346 | [176; 178) 'S1': S1 | ||
347 | [176; 187) 'S1.method()': u32 | ||
348 | [203; 205) 'S2': S2 | ||
349 | [203; 214) 'S2.method()': i128 | ||
350 | "### | ||
351 | ); | ||
352 | } | ||
353 | |||
354 | #[test] | ||
355 | fn infer_trait_method_scoped() { | ||
356 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
357 | assert_snapshot!( | ||
358 | infer(r#" | ||
359 | struct S; | ||
360 | mod foo { | ||
361 | pub trait Trait1 { | ||
362 | fn method(&self) -> u32; | ||
363 | } | ||
364 | impl Trait1 for super::S {} | ||
365 | } | ||
366 | mod bar { | ||
367 | pub trait Trait2 { | ||
368 | fn method(&self) -> i128; | ||
369 | } | ||
370 | impl Trait2 for super::S {} | ||
371 | } | ||
372 | |||
373 | mod foo_test { | ||
374 | use super::S; | ||
375 | use super::foo::Trait1; | ||
376 | fn test() { | ||
377 | S.method(); // -> u32 | ||
378 | } | ||
379 | } | ||
380 | |||
381 | mod bar_test { | ||
382 | use super::S; | ||
383 | use super::bar::Trait2; | ||
384 | fn test() { | ||
385 | S.method(); // -> i128 | ||
386 | } | ||
387 | } | ||
388 | "#), | ||
389 | @r###" | ||
390 | [63; 67) 'self': &Self | ||
391 | [169; 173) 'self': &Self | ||
392 | [300; 337) '{ ... }': () | ||
393 | [310; 311) 'S': S | ||
394 | [310; 320) 'S.method()': u32 | ||
395 | [416; 454) '{ ... }': () | ||
396 | [426; 427) 'S': S | ||
397 | [426; 436) 'S.method()': i128 | ||
398 | "### | ||
399 | ); | ||
400 | } | ||
401 | |||
402 | #[test] | ||
403 | fn infer_trait_method_generic_1() { | ||
404 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
405 | assert_snapshot!( | ||
406 | infer(r#" | ||
407 | trait Trait<T> { | ||
408 | fn method(&self) -> T; | ||
409 | } | ||
410 | struct S; | ||
411 | impl Trait<u32> for S {} | ||
412 | fn test() { | ||
413 | S.method(); | ||
414 | } | ||
415 | "#), | ||
416 | @r###" | ||
417 | [33; 37) 'self': &Self | ||
418 | [92; 111) '{ ...d(); }': () | ||
419 | [98; 99) 'S': S | ||
420 | [98; 108) 'S.method()': u32 | ||
421 | "### | ||
422 | ); | ||
423 | } | ||
424 | |||
425 | #[test] | ||
426 | fn infer_trait_method_generic_more_params() { | ||
427 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
428 | assert_snapshot!( | ||
429 | infer(r#" | ||
430 | trait Trait<T1, T2, T3> { | ||
431 | fn method1(&self) -> (T1, T2, T3); | ||
432 | fn method2(&self) -> (T3, T2, T1); | ||
433 | } | ||
434 | struct S1; | ||
435 | impl Trait<u8, u16, u32> for S1 {} | ||
436 | struct S2; | ||
437 | impl<T> Trait<i8, i16, T> for S2 {} | ||
438 | fn test() { | ||
439 | S1.method1(); // u8, u16, u32 | ||
440 | S1.method2(); // u32, u16, u8 | ||
441 | S2.method1(); // i8, i16, {unknown} | ||
442 | S2.method2(); // {unknown}, i16, i8 | ||
443 | } | ||
444 | "#), | ||
445 | @r###" | ||
446 | [43; 47) 'self': &Self | ||
447 | [82; 86) 'self': &Self | ||
448 | [210; 361) '{ ..., i8 }': () | ||
449 | [216; 218) 'S1': S1 | ||
450 | [216; 228) 'S1.method1()': (u8, u16, u32) | ||
451 | [250; 252) 'S1': S1 | ||
452 | [250; 262) 'S1.method2()': (u32, u16, u8) | ||
453 | [284; 286) 'S2': S2 | ||
454 | [284; 296) 'S2.method1()': (i8, i16, {unknown}) | ||
455 | [324; 326) 'S2': S2 | ||
456 | [324; 336) 'S2.method2()': ({unknown}, i16, i8) | ||
457 | "### | ||
458 | ); | ||
459 | } | ||
460 | |||
461 | #[test] | ||
462 | fn infer_trait_method_generic_2() { | ||
463 | // the trait implementation is intentionally incomplete -- it shouldn't matter | ||
464 | assert_snapshot!( | ||
465 | infer(r#" | ||
466 | trait Trait<T> { | ||
467 | fn method(&self) -> T; | ||
468 | } | ||
469 | struct S<T>(T); | ||
470 | impl<U> Trait<U> for S<U> {} | ||
471 | fn test() { | ||
472 | S(1u32).method(); | ||
473 | } | ||
474 | "#), | ||
475 | @r###" | ||
476 | [33; 37) 'self': &Self | ||
477 | [102; 127) '{ ...d(); }': () | ||
478 | [108; 109) 'S': S<u32>(T) -> S<T> | ||
479 | [108; 115) 'S(1u32)': S<u32> | ||
480 | [108; 124) 'S(1u32...thod()': u32 | ||
481 | [110; 114) '1u32': u32 | ||
482 | "### | ||
483 | ); | ||
484 | } | ||
485 | |||
486 | #[test] | ||
487 | fn infer_trait_assoc_method() { | ||
488 | assert_snapshot!( | ||
489 | infer(r#" | ||
490 | trait Default { | ||
491 | fn default() -> Self; | ||
492 | } | ||
493 | struct S; | ||
494 | impl Default for S {} | ||
495 | fn test() { | ||
496 | let s1: S = Default::default(); | ||
497 | let s2 = S::default(); | ||
498 | let s3 = <S as Default>::default(); | ||
499 | } | ||
500 | "#), | ||
501 | @r###" | ||
502 | [87; 193) '{ ...t(); }': () | ||
503 | [97; 99) 's1': S | ||
504 | [105; 121) 'Defaul...efault': fn default<S>() -> Self | ||
505 | [105; 123) 'Defaul...ault()': S | ||
506 | [133; 135) 's2': S | ||
507 | [138; 148) 'S::default': fn default<S>() -> Self | ||
508 | [138; 150) 'S::default()': S | ||
509 | [160; 162) 's3': S | ||
510 | [165; 188) '<S as ...efault': fn default<S>() -> Self | ||
511 | [165; 190) '<S as ...ault()': S | ||
512 | "### | ||
513 | ); | ||
514 | } | ||
515 | |||
516 | #[test] | ||
517 | fn infer_trait_assoc_method_generics_1() { | ||
518 | assert_snapshot!( | ||
519 | infer(r#" | ||
520 | trait Trait<T> { | ||
521 | fn make() -> T; | ||
522 | } | ||
523 | struct S; | ||
524 | impl Trait<u32> for S {} | ||
525 | struct G<T>; | ||
526 | impl<T> Trait<T> for G<T> {} | ||
527 | fn test() { | ||
528 | let a = S::make(); | ||
529 | let b = G::<u64>::make(); | ||
530 | let c: f64 = G::make(); | ||
531 | } | ||
532 | "#), | ||
533 | @r###" | ||
534 | [127; 211) '{ ...e(); }': () | ||
535 | [137; 138) 'a': u32 | ||
536 | [141; 148) 'S::make': fn make<S, u32>() -> T | ||
537 | [141; 150) 'S::make()': u32 | ||
538 | [160; 161) 'b': u64 | ||
539 | [164; 178) 'G::<u64>::make': fn make<G<u64>, u64>() -> T | ||
540 | [164; 180) 'G::<u6...make()': u64 | ||
541 | [190; 191) 'c': f64 | ||
542 | [199; 206) 'G::make': fn make<G<f64>, f64>() -> T | ||
543 | [199; 208) 'G::make()': f64 | ||
544 | "### | ||
545 | ); | ||
546 | } | ||
547 | |||
548 | #[test] | ||
549 | fn infer_trait_assoc_method_generics_2() { | ||
550 | assert_snapshot!( | ||
551 | infer(r#" | ||
552 | trait Trait<T> { | ||
553 | fn make<U>() -> (T, U); | ||
554 | } | ||
555 | struct S; | ||
556 | impl Trait<u32> for S {} | ||
557 | struct G<T>; | ||
558 | impl<T> Trait<T> for G<T> {} | ||
559 | fn test() { | ||
560 | let a = S::make::<i64>(); | ||
561 | let b: (_, i64) = S::make(); | ||
562 | let c = G::<u32>::make::<i64>(); | ||
563 | let d: (u32, _) = G::make::<i64>(); | ||
564 | let e: (u32, i64) = G::make(); | ||
565 | } | ||
566 | "#), | ||
567 | @r###" | ||
568 | [135; 313) '{ ...e(); }': () | ||
569 | [145; 146) 'a': (u32, i64) | ||
570 | [149; 163) 'S::make::<i64>': fn make<S, u32, i64>() -> (T, U) | ||
571 | [149; 165) 'S::mak...i64>()': (u32, i64) | ||
572 | [175; 176) 'b': (u32, i64) | ||
573 | [189; 196) 'S::make': fn make<S, u32, i64>() -> (T, U) | ||
574 | [189; 198) 'S::make()': (u32, i64) | ||
575 | [208; 209) 'c': (u32, i64) | ||
576 | [212; 233) 'G::<u3...:<i64>': fn make<G<u32>, u32, i64>() -> (T, U) | ||
577 | [212; 235) 'G::<u3...i64>()': (u32, i64) | ||
578 | [245; 246) 'd': (u32, i64) | ||
579 | [259; 273) 'G::make::<i64>': fn make<G<u32>, u32, i64>() -> (T, U) | ||
580 | [259; 275) 'G::mak...i64>()': (u32, i64) | ||
581 | [285; 286) 'e': (u32, i64) | ||
582 | [301; 308) 'G::make': fn make<G<u32>, u32, i64>() -> (T, U) | ||
583 | [301; 310) 'G::make()': (u32, i64) | ||
584 | "### | ||
585 | ); | ||
586 | } | ||
587 | |||
588 | #[test] | ||
589 | fn infer_trait_assoc_method_generics_3() { | ||
590 | assert_snapshot!( | ||
591 | infer(r#" | ||
592 | trait Trait<T> { | ||
593 | fn make() -> (Self, T); | ||
594 | } | ||
595 | struct S<T>; | ||
596 | impl Trait<i64> for S<i32> {} | ||
597 | fn test() { | ||
598 | let a = S::make(); | ||
599 | } | ||
600 | "#), | ||
601 | @r###" | ||
602 | [101; 127) '{ ...e(); }': () | ||
603 | [111; 112) 'a': (S<i32>, i64) | ||
604 | [115; 122) 'S::make': fn make<S<i32>, i64>() -> (Self, T) | ||
605 | [115; 124) 'S::make()': (S<i32>, i64) | ||
606 | "### | ||
607 | ); | ||
608 | } | ||
609 | |||
610 | #[test] | ||
611 | fn infer_trait_assoc_method_generics_4() { | ||
612 | assert_snapshot!( | ||
613 | infer(r#" | ||
614 | trait Trait<T> { | ||
615 | fn make() -> (Self, T); | ||
616 | } | ||
617 | struct S<T>; | ||
618 | impl Trait<i64> for S<u64> {} | ||
619 | impl Trait<i32> for S<u32> {} | ||
620 | fn test() { | ||
621 | let a: (S<u64>, _) = S::make(); | ||
622 | let b: (_, i32) = S::make(); | ||
623 | } | ||
624 | "#), | ||
625 | @r###" | ||
626 | [131; 203) '{ ...e(); }': () | ||
627 | [141; 142) 'a': (S<u64>, i64) | ||
628 | [158; 165) 'S::make': fn make<S<u64>, i64>() -> (Self, T) | ||
629 | [158; 167) 'S::make()': (S<u64>, i64) | ||
630 | [177; 178) 'b': (S<u32>, i32) | ||
631 | [191; 198) 'S::make': fn make<S<u32>, i32>() -> (Self, T) | ||
632 | [191; 200) 'S::make()': (S<u32>, i32) | ||
633 | "### | ||
634 | ); | ||
635 | } | ||
636 | |||
637 | #[test] | ||
638 | fn infer_trait_assoc_method_generics_5() { | ||
639 | assert_snapshot!( | ||
640 | infer(r#" | ||
641 | trait Trait<T> { | ||
642 | fn make<U>() -> (Self, T, U); | ||
643 | } | ||
644 | struct S<T>; | ||
645 | impl Trait<i64> for S<u64> {} | ||
646 | fn test() { | ||
647 | let a = <S as Trait<i64>>::make::<u8>(); | ||
648 | let b: (S<u64>, _, _) = Trait::<i64>::make::<u8>(); | ||
649 | } | ||
650 | "#), | ||
651 | @r###" | ||
652 | [107; 211) '{ ...>(); }': () | ||
653 | [117; 118) 'a': (S<u64>, i64, u8) | ||
654 | [121; 150) '<S as ...::<u8>': fn make<S<u64>, i64, u8>() -> (Self, T, U) | ||
655 | [121; 152) '<S as ...<u8>()': (S<u64>, i64, u8) | ||
656 | [162; 163) 'b': (S<u64>, i64, u8) | ||
657 | [182; 206) 'Trait:...::<u8>': fn make<S<u64>, i64, u8>() -> (Self, T, U) | ||
658 | [182; 208) 'Trait:...<u8>()': (S<u64>, i64, u8) | ||
659 | "### | ||
660 | ); | ||
661 | } | ||
662 | |||
663 | #[test] | ||
664 | fn infer_call_trait_method_on_generic_param_1() { | ||
665 | assert_snapshot!( | ||
666 | infer(r#" | ||
667 | trait Trait { | ||
668 | fn method(&self) -> u32; | ||
669 | } | ||
670 | fn test<T: Trait>(t: T) { | ||
671 | t.method(); | ||
672 | } | ||
673 | "#), | ||
674 | @r###" | ||
675 | [30; 34) 'self': &Self | ||
676 | [64; 65) 't': T | ||
677 | [70; 89) '{ ...d(); }': () | ||
678 | [76; 77) 't': T | ||
679 | [76; 86) 't.method()': u32 | ||
680 | "### | ||
681 | ); | ||
682 | } | ||
683 | |||
684 | #[test] | ||
685 | fn infer_call_trait_method_on_generic_param_2() { | ||
686 | assert_snapshot!( | ||
687 | infer(r#" | ||
688 | trait Trait<T> { | ||
689 | fn method(&self) -> T; | ||
690 | } | ||
691 | fn test<U, T: Trait<U>>(t: T) { | ||
692 | t.method(); | ||
693 | } | ||
694 | "#), | ||
695 | @r###" | ||
696 | [33; 37) 'self': &Self | ||
697 | [71; 72) 't': T | ||
698 | [77; 96) '{ ...d(); }': () | ||
699 | [83; 84) 't': T | ||
700 | [83; 93) 't.method()': [missing name] | ||
701 | "### | ||
702 | ); | ||
703 | } | ||
704 | |||
705 | #[test] | ||
706 | fn infer_with_multiple_trait_impls() { | ||
707 | assert_snapshot!( | ||
708 | infer(r#" | ||
709 | trait Into<T> { | ||
710 | fn into(self) -> T; | ||
711 | } | ||
712 | struct S; | ||
713 | impl Into<u32> for S {} | ||
714 | impl Into<u64> for S {} | ||
715 | fn test() { | ||
716 | let x: u32 = S.into(); | ||
717 | let y: u64 = S.into(); | ||
718 | let z = Into::<u64>::into(S); | ||
719 | } | ||
720 | "#), | ||
721 | @r###" | ||
722 | [29; 33) 'self': Self | ||
723 | [111; 202) '{ ...(S); }': () | ||
724 | [121; 122) 'x': u32 | ||
725 | [130; 131) 'S': S | ||
726 | [130; 138) 'S.into()': u32 | ||
727 | [148; 149) 'y': u64 | ||
728 | [157; 158) 'S': S | ||
729 | [157; 165) 'S.into()': u64 | ||
730 | [175; 176) 'z': u64 | ||
731 | [179; 196) 'Into::...::into': fn into<S, u64>(Self) -> T | ||
732 | [179; 199) 'Into::...nto(S)': u64 | ||
733 | [197; 198) 'S': S | ||
734 | "### | ||
735 | ); | ||
736 | } | ||
737 | |||
738 | #[test] | ||
739 | fn method_resolution_unify_impl_self_type() { | ||
740 | let t = type_at( | ||
741 | r#" | ||
742 | //- /main.rs | ||
743 | struct S<T>; | ||
744 | impl S<u32> { fn foo(&self) -> u8 {} } | ||
745 | impl S<i32> { fn foo(&self) -> i8 {} } | ||
746 | fn test() { (S::<u32>.foo(), S::<i32>.foo())<|>; } | ||
747 | "#, | ||
748 | ); | ||
749 | assert_eq!(t, "(u8, i8)"); | ||
750 | } | ||
751 | |||
752 | #[test] | ||
753 | fn method_resolution_trait_before_autoref() { | ||
754 | let t = type_at( | ||
755 | r#" | ||
756 | //- /main.rs | ||
757 | trait Trait { fn foo(self) -> u128; } | ||
758 | struct S; | ||
759 | impl S { fn foo(&self) -> i8 { 0 } } | ||
760 | impl Trait for S { fn foo(self) -> u128 { 0 } } | ||
761 | fn test() { S.foo()<|>; } | ||
762 | "#, | ||
763 | ); | ||
764 | assert_eq!(t, "u128"); | ||
765 | } | ||
766 | |||
767 | #[test] | ||
768 | fn method_resolution_by_value_before_autoref() { | ||
769 | let t = type_at( | ||
770 | r#" | ||
771 | //- /main.rs | ||
772 | trait Clone { fn clone(&self) -> Self; } | ||
773 | struct S; | ||
774 | impl Clone for S {} | ||
775 | impl Clone for &S {} | ||
776 | fn test() { (S.clone(), (&S).clone(), (&&S).clone())<|>; } | ||
777 | "#, | ||
778 | ); | ||
779 | assert_eq!(t, "(S, S, &S)"); | ||
780 | } | ||
781 | |||
782 | #[test] | ||
783 | fn method_resolution_trait_before_autoderef() { | ||
784 | let t = type_at( | ||
785 | r#" | ||
786 | //- /main.rs | ||
787 | trait Trait { fn foo(self) -> u128; } | ||
788 | struct S; | ||
789 | impl S { fn foo(self) -> i8 { 0 } } | ||
790 | impl Trait for &S { fn foo(self) -> u128 { 0 } } | ||
791 | fn test() { (&S).foo()<|>; } | ||
792 | "#, | ||
793 | ); | ||
794 | assert_eq!(t, "u128"); | ||
795 | } | ||
796 | |||
797 | #[test] | ||
798 | fn method_resolution_impl_before_trait() { | ||
799 | let t = type_at( | ||
800 | r#" | ||
801 | //- /main.rs | ||
802 | trait Trait { fn foo(self) -> u128; } | ||
803 | struct S; | ||
804 | impl S { fn foo(self) -> i8 { 0 } } | ||
805 | impl Trait for S { fn foo(self) -> u128 { 0 } } | ||
806 | fn test() { S.foo()<|>; } | ||
807 | "#, | ||
808 | ); | ||
809 | assert_eq!(t, "i8"); | ||
810 | } | ||
811 | |||
812 | #[test] | ||
813 | fn method_resolution_impl_ref_before_trait() { | ||
814 | let t = type_at( | ||
815 | r#" | ||
816 | //- /main.rs | ||
817 | trait Trait { fn foo(self) -> u128; } | ||
818 | struct S; | ||
819 | impl S { fn foo(&self) -> i8 { 0 } } | ||
820 | impl Trait for &S { fn foo(self) -> u128 { 0 } } | ||
821 | fn test() { S.foo()<|>; } | ||
822 | "#, | ||
823 | ); | ||
824 | assert_eq!(t, "i8"); | ||
825 | } | ||
826 | |||
827 | #[test] | ||
828 | fn method_resolution_trait_autoderef() { | ||
829 | let t = type_at( | ||
830 | r#" | ||
831 | //- /main.rs | ||
832 | trait Trait { fn foo(self) -> u128; } | ||
833 | struct S; | ||
834 | impl Trait for S { fn foo(self) -> u128 { 0 } } | ||
835 | fn test() { (&S).foo()<|>; } | ||
836 | "#, | ||
837 | ); | ||
838 | assert_eq!(t, "u128"); | ||
839 | } | ||
840 | |||
841 | #[test] | ||
842 | fn method_resolution_trait_from_prelude() { | ||
843 | let (db, pos) = TestDB::with_position( | ||
844 | r#" | ||
845 | //- /main.rs crate:main deps:other_crate | ||
846 | struct S; | ||
847 | impl Clone for S {} | ||
848 | |||
849 | fn test() { | ||
850 | S.clone()<|>; | ||
851 | } | ||
852 | |||
853 | //- /lib.rs crate:other_crate | ||
854 | #[prelude_import] use foo::*; | ||
855 | |||
856 | mod foo { | ||
857 | trait Clone { | ||
858 | fn clone(&self) -> Self; | ||
859 | } | ||
860 | } | ||
861 | "#, | ||
862 | ); | ||
863 | assert_eq!("S", type_at_pos(&db, pos)); | ||
864 | } | ||
865 | |||
866 | #[test] | ||
867 | fn method_resolution_where_clause_for_unknown_trait() { | ||
868 | // The blanket impl currently applies because we ignore the unresolved where clause | ||
869 | let t = type_at( | ||
870 | r#" | ||
871 | //- /main.rs | ||
872 | trait Trait { fn foo(self) -> u128; } | ||
873 | struct S; | ||
874 | impl<T> Trait for T where T: UnknownTrait {} | ||
875 | fn test() { (&S).foo()<|>; } | ||
876 | "#, | ||
877 | ); | ||
878 | assert_eq!(t, "u128"); | ||
879 | } | ||
880 | |||
881 | #[test] | ||
882 | fn method_resolution_where_clause_not_met() { | ||
883 | // The blanket impl shouldn't apply because we can't prove S: Clone | ||
884 | let t = type_at( | ||
885 | r#" | ||
886 | //- /main.rs | ||
887 | trait Clone {} | ||
888 | trait Trait { fn foo(self) -> u128; } | ||
889 | struct S; | ||
890 | impl<T> Trait for T where T: Clone {} | ||
891 | fn test() { (&S).foo()<|>; } | ||
892 | "#, | ||
893 | ); | ||
894 | // This is also to make sure that we don't resolve to the foo method just | ||
895 | // because that's the only method named foo we can find, which would make | ||
896 | // the below tests not work | ||
897 | assert_eq!(t, "{unknown}"); | ||
898 | } | ||
899 | |||
900 | #[test] | ||
901 | fn method_resolution_where_clause_inline_not_met() { | ||
902 | // The blanket impl shouldn't apply because we can't prove S: Clone | ||
903 | let t = type_at( | ||
904 | r#" | ||
905 | //- /main.rs | ||
906 | trait Clone {} | ||
907 | trait Trait { fn foo(self) -> u128; } | ||
908 | struct S; | ||
909 | impl<T: Clone> Trait for T {} | ||
910 | fn test() { (&S).foo()<|>; } | ||
911 | "#, | ||
912 | ); | ||
913 | assert_eq!(t, "{unknown}"); | ||
914 | } | ||
915 | |||
916 | #[test] | ||
917 | fn method_resolution_where_clause_1() { | ||
918 | let t = type_at( | ||
919 | r#" | ||
920 | //- /main.rs | ||
921 | trait Clone {} | ||
922 | trait Trait { fn foo(self) -> u128; } | ||
923 | struct S; | ||
924 | impl Clone for S {} | ||
925 | impl<T> Trait for T where T: Clone {} | ||
926 | fn test() { S.foo()<|>; } | ||
927 | "#, | ||
928 | ); | ||
929 | assert_eq!(t, "u128"); | ||
930 | } | ||
931 | |||
932 | #[test] | ||
933 | fn method_resolution_where_clause_2() { | ||
934 | let t = type_at( | ||
935 | r#" | ||
936 | //- /main.rs | ||
937 | trait Into<T> { fn into(self) -> T; } | ||
938 | trait From<T> { fn from(other: T) -> Self; } | ||
939 | struct S1; | ||
940 | struct S2; | ||
941 | impl From<S2> for S1 {} | ||
942 | impl<T, U> Into<U> for T where U: From<T> {} | ||
943 | fn test() { S2.into()<|>; } | ||
944 | "#, | ||
945 | ); | ||
946 | assert_eq!(t, "{unknown}"); | ||
947 | } | ||
948 | |||
949 | #[test] | ||
950 | fn method_resolution_where_clause_inline() { | ||
951 | let t = type_at( | ||
952 | r#" | ||
953 | //- /main.rs | ||
954 | trait Into<T> { fn into(self) -> T; } | ||
955 | trait From<T> { fn from(other: T) -> Self; } | ||
956 | struct S1; | ||
957 | struct S2; | ||
958 | impl From<S2> for S1 {} | ||
959 | impl<T, U: From<T>> Into<U> for T {} | ||
960 | fn test() { S2.into()<|>; } | ||
961 | "#, | ||
962 | ); | ||
963 | assert_eq!(t, "{unknown}"); | ||
964 | } | ||
965 | |||
966 | #[test] | ||
967 | fn method_resolution_encountering_fn_type() { | ||
968 | type_at( | ||
969 | r#" | ||
970 | //- /main.rs | ||
971 | fn foo() {} | ||
972 | trait FnOnce { fn call(self); } | ||
973 | fn test() { foo.call()<|>; } | ||
974 | "#, | ||
975 | ); | ||
976 | } | ||
977 | |||
978 | #[test] | ||
979 | fn method_resolution_slow() { | ||
980 | // this can get quite slow if we set the solver size limit too high | ||
981 | let t = type_at( | ||
982 | r#" | ||
983 | //- /main.rs | ||
984 | trait SendX {} | ||
985 | |||
986 | struct S1; impl SendX for S1 {} | ||
987 | struct S2; impl SendX for S2 {} | ||
988 | struct U1; | ||
989 | |||
990 | trait Trait { fn method(self); } | ||
991 | |||
992 | struct X1<A, B> {} | ||
993 | impl<A, B> SendX for X1<A, B> where A: SendX, B: SendX {} | ||
994 | |||
995 | struct S<B, C> {} | ||
996 | |||
997 | trait FnX {} | ||
998 | |||
999 | impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {} | ||
1000 | |||
1001 | fn test() { (S {}).method()<|>; } | ||
1002 | "#, | ||
1003 | ); | ||
1004 | assert_eq!(t, "()"); | ||
1005 | } | ||