aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests/method_resolution.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
committerSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
commitb21d9337d9200e2cfdc90b386591c72c302dc03e (patch)
treef81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_ty/src/tests/method_resolution.rs
parent18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff)
parentce07a2daa9e53aa86a769f8641b14c2878444fbc (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.rs1005
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 @@
1use super::{infer, type_at, type_at_pos};
2use crate::test_db::TestDB;
3use insta::assert_snapshot;
4use ra_db::fixture::WithFixture;
5
6#[test]
7fn infer_slice_method() {
8 assert_snapshot!(
9 infer(r#"
10#[lang = "slice"]
11impl<T> [T] {
12 fn foo(&self) -> T {
13 loop {}
14 }
15}
16
17#[lang = "slice_alloc"]
18impl<T> [T] {}
19
20fn 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]
38fn infer_associated_method_struct() {
39 assert_snapshot!(
40 infer(r#"
41struct A { x: u32 }
42
43impl A {
44 fn new() -> A {
45 A { x: 0 }
46 }
47}
48fn 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]
68fn infer_associated_method_enum() {
69 assert_snapshot!(
70 infer(r#"
71enum A { B, C }
72
73impl A {
74 pub fn b() -> A {
75 A::B
76 }
77 pub fn c() -> A {
78 A::C
79 }
80}
81fn 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]
107fn infer_associated_method_with_modules() {
108 assert_snapshot!(
109 infer(r#"
110mod a {
111 struct A;
112 impl A { pub fn thing() -> A { A {} }}
113}
114
115mod 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}
124use b::c;
125
126fn 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]
154fn infer_associated_method_generics() {
155 assert_snapshot!(
156 infer(r#"
157struct Gen<T> {
158 val: T
159}
160
161impl<T> Gen<T> {
162 pub fn make(val: T) -> Gen<T> {
163 Gen { val }
164 }
165}
166
167fn 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]
186fn infer_associated_method_generics_with_default_param() {
187 assert_snapshot!(
188 infer(r#"
189struct Gen<T=u32> {
190 val: T
191}
192
193impl<T> Gen<T> {
194 pub fn make() -> Gen<T> {
195 loop { }
196 }
197}
198
199fn 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]
216fn infer_associated_method_generics_with_default_tuple_param() {
217 let t = type_at(
218 r#"
219//- /main.rs
220struct Gen<T=()> {
221 val: T
222}
223
224impl<T> Gen<T> {
225 pub fn make() -> Gen<T> {
226 loop { }
227 }
228}
229
230fn test() {
231 let a = Gen::make();
232 a.val<|>;
233}
234"#,
235 );
236 assert_eq!(t, "()");
237}
238
239#[test]
240fn infer_associated_method_generics_without_args() {
241 assert_snapshot!(
242 infer(r#"
243struct Gen<T> {
244 val: T
245}
246
247impl<T> Gen<T> {
248 pub fn make() -> Gen<T> {
249 loop { }
250 }
251}
252
253fn 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]
270fn infer_associated_method_generics_2_type_params_without_args() {
271 assert_snapshot!(
272 infer(r#"
273struct Gen<T, U> {
274 val: T,
275 val2: U,
276}
277
278impl<T> Gen<u32, T> {
279 pub fn make() -> Gen<u32,T> {
280 loop { }
281 }
282}
283
284fn 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]
301fn cross_crate_associated_method_call() {
302 let (db, pos) = TestDB::with_position(
303 r#"
304//- /main.rs crate:main deps:other_crate
305fn test() {
306 let x = other_crate::foo::S::thing();
307 x<|>;
308}
309
310//- /lib.rs crate:other_crate
311mod 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]
323fn infer_trait_method_simple() {
324 // the trait implementation is intentionally incomplete -- it shouldn't matter
325 assert_snapshot!(
326 infer(r#"
327trait Trait1 {
328 fn method(&self) -> u32;
329}
330struct S1;
331impl Trait1 for S1 {}
332trait Trait2 {
333 fn method(&self) -> i128;
334}
335struct S2;
336impl Trait2 for S2 {}
337fn 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]
355fn infer_trait_method_scoped() {
356 // the trait implementation is intentionally incomplete -- it shouldn't matter
357 assert_snapshot!(
358 infer(r#"
359struct S;
360mod foo {
361 pub trait Trait1 {
362 fn method(&self) -> u32;
363 }
364 impl Trait1 for super::S {}
365}
366mod bar {
367 pub trait Trait2 {
368 fn method(&self) -> i128;
369 }
370 impl Trait2 for super::S {}
371}
372
373mod foo_test {
374 use super::S;
375 use super::foo::Trait1;
376 fn test() {
377 S.method(); // -> u32
378 }
379}
380
381mod 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]
403fn infer_trait_method_generic_1() {
404 // the trait implementation is intentionally incomplete -- it shouldn't matter
405 assert_snapshot!(
406 infer(r#"
407trait Trait<T> {
408 fn method(&self) -> T;
409}
410struct S;
411impl Trait<u32> for S {}
412fn 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]
426fn infer_trait_method_generic_more_params() {
427 // the trait implementation is intentionally incomplete -- it shouldn't matter
428 assert_snapshot!(
429 infer(r#"
430trait Trait<T1, T2, T3> {
431 fn method1(&self) -> (T1, T2, T3);
432 fn method2(&self) -> (T3, T2, T1);
433}
434struct S1;
435impl Trait<u8, u16, u32> for S1 {}
436struct S2;
437impl<T> Trait<i8, i16, T> for S2 {}
438fn 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]
462fn infer_trait_method_generic_2() {
463 // the trait implementation is intentionally incomplete -- it shouldn't matter
464 assert_snapshot!(
465 infer(r#"
466trait Trait<T> {
467 fn method(&self) -> T;
468}
469struct S<T>(T);
470impl<U> Trait<U> for S<U> {}
471fn 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]
487fn infer_trait_assoc_method() {
488 assert_snapshot!(
489 infer(r#"
490trait Default {
491 fn default() -> Self;
492}
493struct S;
494impl Default for S {}
495fn 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]
517fn infer_trait_assoc_method_generics_1() {
518 assert_snapshot!(
519 infer(r#"
520trait Trait<T> {
521 fn make() -> T;
522}
523struct S;
524impl Trait<u32> for S {}
525struct G<T>;
526impl<T> Trait<T> for G<T> {}
527fn 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]
549fn infer_trait_assoc_method_generics_2() {
550 assert_snapshot!(
551 infer(r#"
552trait Trait<T> {
553 fn make<U>() -> (T, U);
554}
555struct S;
556impl Trait<u32> for S {}
557struct G<T>;
558impl<T> Trait<T> for G<T> {}
559fn 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]
589fn infer_trait_assoc_method_generics_3() {
590 assert_snapshot!(
591 infer(r#"
592trait Trait<T> {
593 fn make() -> (Self, T);
594}
595struct S<T>;
596impl Trait<i64> for S<i32> {}
597fn 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]
611fn infer_trait_assoc_method_generics_4() {
612 assert_snapshot!(
613 infer(r#"
614trait Trait<T> {
615 fn make() -> (Self, T);
616}
617struct S<T>;
618impl Trait<i64> for S<u64> {}
619impl Trait<i32> for S<u32> {}
620fn 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]
638fn infer_trait_assoc_method_generics_5() {
639 assert_snapshot!(
640 infer(r#"
641trait Trait<T> {
642 fn make<U>() -> (Self, T, U);
643}
644struct S<T>;
645impl Trait<i64> for S<u64> {}
646fn 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]
664fn infer_call_trait_method_on_generic_param_1() {
665 assert_snapshot!(
666 infer(r#"
667trait Trait {
668 fn method(&self) -> u32;
669}
670fn 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]
685fn infer_call_trait_method_on_generic_param_2() {
686 assert_snapshot!(
687 infer(r#"
688trait Trait<T> {
689 fn method(&self) -> T;
690}
691fn 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]
706fn infer_with_multiple_trait_impls() {
707 assert_snapshot!(
708 infer(r#"
709trait Into<T> {
710 fn into(self) -> T;
711}
712struct S;
713impl Into<u32> for S {}
714impl Into<u64> for S {}
715fn 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]
739fn method_resolution_unify_impl_self_type() {
740 let t = type_at(
741 r#"
742//- /main.rs
743struct S<T>;
744impl S<u32> { fn foo(&self) -> u8 {} }
745impl S<i32> { fn foo(&self) -> i8 {} }
746fn test() { (S::<u32>.foo(), S::<i32>.foo())<|>; }
747"#,
748 );
749 assert_eq!(t, "(u8, i8)");
750}
751
752#[test]
753fn method_resolution_trait_before_autoref() {
754 let t = type_at(
755 r#"
756//- /main.rs
757trait Trait { fn foo(self) -> u128; }
758struct S;
759impl S { fn foo(&self) -> i8 { 0 } }
760impl Trait for S { fn foo(self) -> u128 { 0 } }
761fn test() { S.foo()<|>; }
762"#,
763 );
764 assert_eq!(t, "u128");
765}
766
767#[test]
768fn method_resolution_by_value_before_autoref() {
769 let t = type_at(
770 r#"
771//- /main.rs
772trait Clone { fn clone(&self) -> Self; }
773struct S;
774impl Clone for S {}
775impl Clone for &S {}
776fn test() { (S.clone(), (&S).clone(), (&&S).clone())<|>; }
777"#,
778 );
779 assert_eq!(t, "(S, S, &S)");
780}
781
782#[test]
783fn method_resolution_trait_before_autoderef() {
784 let t = type_at(
785 r#"
786//- /main.rs
787trait Trait { fn foo(self) -> u128; }
788struct S;
789impl S { fn foo(self) -> i8 { 0 } }
790impl Trait for &S { fn foo(self) -> u128 { 0 } }
791fn test() { (&S).foo()<|>; }
792"#,
793 );
794 assert_eq!(t, "u128");
795}
796
797#[test]
798fn method_resolution_impl_before_trait() {
799 let t = type_at(
800 r#"
801//- /main.rs
802trait Trait { fn foo(self) -> u128; }
803struct S;
804impl S { fn foo(self) -> i8 { 0 } }
805impl Trait for S { fn foo(self) -> u128 { 0 } }
806fn test() { S.foo()<|>; }
807"#,
808 );
809 assert_eq!(t, "i8");
810}
811
812#[test]
813fn method_resolution_impl_ref_before_trait() {
814 let t = type_at(
815 r#"
816//- /main.rs
817trait Trait { fn foo(self) -> u128; }
818struct S;
819impl S { fn foo(&self) -> i8 { 0 } }
820impl Trait for &S { fn foo(self) -> u128 { 0 } }
821fn test() { S.foo()<|>; }
822"#,
823 );
824 assert_eq!(t, "i8");
825}
826
827#[test]
828fn method_resolution_trait_autoderef() {
829 let t = type_at(
830 r#"
831//- /main.rs
832trait Trait { fn foo(self) -> u128; }
833struct S;
834impl Trait for S { fn foo(self) -> u128 { 0 } }
835fn test() { (&S).foo()<|>; }
836"#,
837 );
838 assert_eq!(t, "u128");
839}
840
841#[test]
842fn method_resolution_trait_from_prelude() {
843 let (db, pos) = TestDB::with_position(
844 r#"
845//- /main.rs crate:main deps:other_crate
846struct S;
847impl Clone for S {}
848
849fn test() {
850 S.clone()<|>;
851}
852
853//- /lib.rs crate:other_crate
854#[prelude_import] use foo::*;
855
856mod 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]
867fn 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
872trait Trait { fn foo(self) -> u128; }
873struct S;
874impl<T> Trait for T where T: UnknownTrait {}
875fn test() { (&S).foo()<|>; }
876"#,
877 );
878 assert_eq!(t, "u128");
879}
880
881#[test]
882fn 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
887trait Clone {}
888trait Trait { fn foo(self) -> u128; }
889struct S;
890impl<T> Trait for T where T: Clone {}
891fn 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]
901fn 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
906trait Clone {}
907trait Trait { fn foo(self) -> u128; }
908struct S;
909impl<T: Clone> Trait for T {}
910fn test() { (&S).foo()<|>; }
911"#,
912 );
913 assert_eq!(t, "{unknown}");
914}
915
916#[test]
917fn method_resolution_where_clause_1() {
918 let t = type_at(
919 r#"
920//- /main.rs
921trait Clone {}
922trait Trait { fn foo(self) -> u128; }
923struct S;
924impl Clone for S {}
925impl<T> Trait for T where T: Clone {}
926fn test() { S.foo()<|>; }
927"#,
928 );
929 assert_eq!(t, "u128");
930}
931
932#[test]
933fn method_resolution_where_clause_2() {
934 let t = type_at(
935 r#"
936//- /main.rs
937trait Into<T> { fn into(self) -> T; }
938trait From<T> { fn from(other: T) -> Self; }
939struct S1;
940struct S2;
941impl From<S2> for S1 {}
942impl<T, U> Into<U> for T where U: From<T> {}
943fn test() { S2.into()<|>; }
944"#,
945 );
946 assert_eq!(t, "{unknown}");
947}
948
949#[test]
950fn method_resolution_where_clause_inline() {
951 let t = type_at(
952 r#"
953//- /main.rs
954trait Into<T> { fn into(self) -> T; }
955trait From<T> { fn from(other: T) -> Self; }
956struct S1;
957struct S2;
958impl From<S2> for S1 {}
959impl<T, U: From<T>> Into<U> for T {}
960fn test() { S2.into()<|>; }
961"#,
962 );
963 assert_eq!(t, "{unknown}");
964}
965
966#[test]
967fn method_resolution_encountering_fn_type() {
968 type_at(
969 r#"
970//- /main.rs
971fn foo() {}
972trait FnOnce { fn call(self); }
973fn test() { foo.call()<|>; }
974"#,
975 );
976}
977
978#[test]
979fn 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
984trait SendX {}
985
986struct S1; impl SendX for S1 {}
987struct S2; impl SendX for S2 {}
988struct U1;
989
990trait Trait { fn method(self); }
991
992struct X1<A, B> {}
993impl<A, B> SendX for X1<A, B> where A: SendX, B: SendX {}
994
995struct S<B, C> {}
996
997trait FnX {}
998
999impl<B, C> Trait for S<B, C> where C: FnX, B: SendX {}
1000
1001fn test() { (S {}).method()<|>; }
1002"#,
1003 );
1004 assert_eq!(t, "()");
1005}