]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/hir-ty/src/tests/traits.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / hir-ty / src / tests / traits.rs
CommitLineData
064997fb
FG
1use cov_mark::check;
2use expect_test::expect;
3
4use super::{check, check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
5
6#[test]
7fn infer_await() {
8 check_types(
9 r#"
10//- minicore: future
11struct IntFuture;
12
13impl core::future::Future for IntFuture {
14 type Output = u64;
15}
16
17fn test() {
18 let r = IntFuture;
19 let v = r.await;
20 v;
21} //^ u64
22"#,
23 );
24}
25
26#[test]
27fn infer_async() {
28 check_types(
29 r#"
30//- minicore: future
31async fn foo() -> u64 { 128 }
32
33fn test() {
34 let r = foo();
35 let v = r.await;
36 v;
37} //^ u64
38"#,
39 );
40}
41
42#[test]
43fn infer_desugar_async() {
44 check_types(
45 r#"
46//- minicore: future, sized
47async fn foo() -> u64 { 128 }
48
49fn test() {
50 let r = foo();
51 r;
52} //^ impl Future<Output = u64>
53"#,
54 );
55}
56
57#[test]
58fn infer_async_block() {
59 check_types(
60 r#"
61//- minicore: future, option
62async fn test() {
63 let a = async { 42 };
64 a;
65// ^ impl Future<Output = i32>
66 let x = a.await;
67 x;
68// ^ i32
69 let b = async {}.await;
70 b;
71// ^ ()
72 let c = async {
73 let y = None;
74 y
75 // ^ Option<u64>
76 };
77 let _: Option<u64> = c.await;
78 c;
79// ^ impl Future<Output = Option<u64>>
80}
81"#,
82 );
83}
84
85#[test]
86fn auto_sized_async_block() {
87 check_no_mismatches(
88 r#"
89//- minicore: future, sized
90
91use core::future::Future;
92struct MyFut<Fut>(Fut);
93
94impl<Fut> Future for MyFut<Fut>
95where Fut: Future
96{
97 type Output = Fut::Output;
98}
99async fn reproduction() -> usize {
100 let f = async {999usize};
101 MyFut(f).await
102}
103 "#,
104 );
105 check_no_mismatches(
106 r#"
107//- minicore: future
108//#11815
109#[lang = "sized"]
110pub trait Sized {}
111
112#[lang = "unsize"]
113pub trait Unsize<T: ?Sized> {}
114
115#[lang = "coerce_unsized"]
116pub trait CoerceUnsized<T> {}
117
118pub unsafe trait Allocator {}
119
120pub struct Global;
121unsafe impl Allocator for Global {}
122
123#[lang = "owned_box"]
124#[fundamental]
125pub struct Box<T: ?Sized, A: Allocator = Global>;
126
127impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
128
129fn send() -> Box<dyn Future<Output = ()> + Send + 'static>{
130 box async move {}
131}
132
133fn not_send() -> Box<dyn Future<Output = ()> + 'static> {
134 box async move {}
135}
136 "#,
137 );
138}
139
f2b60f7d
FG
140#[test]
141fn into_future_trait() {
142 check_types(
143 r#"
144//- minicore: future
145struct Futurable;
146impl core::future::IntoFuture for Futurable {
147 type Output = u64;
148 type IntoFuture = IntFuture;
149}
150
151struct IntFuture;
152impl core::future::Future for IntFuture {
153 type Output = u64;
154}
155
156fn test() {
157 let r = Futurable;
158 let v = r.await;
159 v;
160} //^ u64
161"#,
162 );
163}
164
064997fb
FG
165#[test]
166fn infer_try() {
167 check_types(
168 r#"
169//- /main.rs crate:main deps:core
170fn test() {
171 let r: Result<i32, u64> = Result::Ok(1);
172 let v = r?;
173 v;
174} //^ i32
175
176//- /core.rs crate:core
177pub mod ops {
178 pub trait Try {
179 type Ok;
180 type Error;
181 }
182}
183
184pub mod result {
185 pub enum Result<O, E> {
186 Ok(O),
187 Err(E)
188 }
189
190 impl<O, E> crate::ops::Try for Result<O, E> {
191 type Ok = O;
192 type Error = E;
193 }
194}
195
196pub mod prelude {
197 pub mod rust_2018 {
198 pub use crate::{result::*, ops::*};
199 }
200}
201"#,
202 );
203}
204
205#[test]
206fn infer_try_trait_v2() {
207 check_types(
208 r#"
209//- /main.rs crate:main deps:core
210fn test() {
211 let r: Result<i32, u64> = Result::Ok(1);
212 let v = r?;
213 v;
214} //^ i32
215
216//- /core.rs crate:core
217mod ops {
218 mod try_trait {
219 pub trait Try: FromResidual {
220 type Output;
221 type Residual;
222 }
223 pub trait FromResidual<R = <Self as Try>::Residual> {}
224 }
225
226 pub use self::try_trait::FromResidual;
227 pub use self::try_trait::Try;
228}
229
230mod convert {
231 pub trait From<T> {}
232 impl<T> From<T> for T {}
233}
234
235pub mod result {
236 use crate::convert::From;
237 use crate::ops::{Try, FromResidual};
238
239 pub enum Infallible {}
240 pub enum Result<O, E> {
241 Ok(O),
242 Err(E)
243 }
244
245 impl<O, E> Try for Result<O, E> {
246 type Output = O;
247 type Error = Result<Infallible, E>;
248 }
249
250 impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {}
251}
252
253pub mod prelude {
254 pub mod rust_2018 {
255 pub use crate::result::*;
256 }
257}
258"#,
259 );
260}
261
262#[test]
263fn infer_for_loop() {
264 check_types(
265 r#"
266//- /main.rs crate:main deps:core,alloc
267#![no_std]
268use alloc::collections::Vec;
269
270fn test() {
271 let v = Vec::new();
272 v.push("foo");
273 for x in v {
274 x;
275 } //^ &str
276}
277
278//- /core.rs crate:core
279pub mod iter {
280 pub trait IntoIterator {
281 type Item;
2b03887a
FG
282 type IntoIter: Iterator<Item = Self::Item>;
283 }
284 pub trait Iterator {
285 type Item;
064997fb
FG
286 }
287}
288pub mod prelude {
289 pub mod rust_2018 {
290 pub use crate::iter::*;
291 }
292}
293
294//- /alloc.rs crate:alloc deps:core
295#![no_std]
296pub mod collections {
297 pub struct Vec<T> {}
298 impl<T> Vec<T> {
299 pub fn new() -> Self { Vec {} }
300 pub fn push(&mut self, t: T) { }
301 }
302
303 impl<T> IntoIterator for Vec<T> {
2b03887a
FG
304 type Item = T;
305 type IntoIter = IntoIter<T>;
306 }
307
308 struct IntoIter<T> {}
309 impl<T> Iterator for IntoIter<T> {
310 type Item = T;
064997fb
FG
311 }
312}
313"#,
314 );
315}
316
317#[test]
318fn infer_ops_neg() {
319 check_types(
320 r#"
321//- /main.rs crate:main deps:std
322struct Bar;
323struct Foo;
324
325impl std::ops::Neg for Bar {
326 type Output = Foo;
327}
328
329fn test() {
330 let a = Bar;
331 let b = -a;
332 b;
333} //^ Foo
334
335//- /std.rs crate:std
336#[prelude_import] use ops::*;
337mod ops {
338 #[lang = "neg"]
339 pub trait Neg {
340 type Output;
341 }
342}
343"#,
344 );
345}
346
347#[test]
348fn infer_ops_not() {
349 check_types(
350 r#"
351//- /main.rs crate:main deps:std
352struct Bar;
353struct Foo;
354
355impl std::ops::Not for Bar {
356 type Output = Foo;
357}
358
359fn test() {
360 let a = Bar;
361 let b = !a;
362 b;
363} //^ Foo
364
365//- /std.rs crate:std
366#[prelude_import] use ops::*;
367mod ops {
368 #[lang = "not"]
369 pub trait Not {
370 type Output;
371 }
372}
373"#,
374 );
375}
376
377#[test]
378fn infer_from_bound_1() {
379 check_types(
380 r#"
381trait Trait<T> {}
382struct S<T>(T);
383impl<U> Trait<U> for S<U> {}
384fn foo<T: Trait<u32>>(t: T) {}
385fn test() {
386 let s = S(unknown);
387 // ^^^^^^^ u32
388 foo(s);
389}"#,
390 );
391}
392
393#[test]
394fn infer_from_bound_2() {
395 check_types(
396 r#"
397trait Trait<T> {}
398struct S<T>(T);
399impl<U> Trait<U> for S<U> {}
400fn foo<U, T: Trait<U>>(t: T) -> U { loop {} }
401fn test() {
402 let s = S(unknown);
403 // ^^^^^^^ u32
404 let x: u32 = foo(s);
405}"#,
406 );
407}
408
409#[test]
410fn trait_default_method_self_bound_implements_trait() {
411 cov_mark::check!(trait_self_implements_self);
412 check(
413 r#"
414trait Trait {
415 fn foo(&self) -> i64;
416 fn bar(&self) -> () {
417 self.foo();
418 // ^^^^^^^^^^ type: i64
419 }
420}"#,
421 );
422}
423
424#[test]
425fn trait_default_method_self_bound_implements_super_trait() {
426 check(
427 r#"
428trait SuperTrait {
429 fn foo(&self) -> i64;
430}
431trait Trait: SuperTrait {
432 fn bar(&self) -> () {
433 self.foo();
434 // ^^^^^^^^^^ type: i64
435 }
436}"#,
437 );
438}
439
440#[test]
441fn infer_project_associated_type() {
442 check_types(
443 r#"
444trait Iterable {
445 type Item;
446}
447struct S;
448impl Iterable for S { type Item = u32; }
449fn test<T: Iterable>() {
450 let x: <S as Iterable>::Item = 1;
451 // ^ u32
452 let y: <T as Iterable>::Item = u;
453 // ^ Iterable::Item<T>
454 let z: T::Item = u;
455 // ^ Iterable::Item<T>
456 let a: <T>::Item = u;
457 // ^ Iterable::Item<T>
458}"#,
459 );
460}
461
462#[test]
463fn infer_return_associated_type() {
464 check_types(
465 r#"
466trait Iterable {
467 type Item;
468}
469struct S;
470impl Iterable for S { type Item = u32; }
471fn foo1<T: Iterable>(t: T) -> T::Item { loop {} }
472fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item { loop {} }
473fn foo3<T: Iterable>(t: T) -> <T>::Item { loop {} }
474fn test() {
475 foo1(S);
476 // ^^^^^^^ u32
477 foo2(S);
478 // ^^^^^^^ u32
479 foo3(S);
480 // ^^^^^^^ u32
481}"#,
482 );
483}
484
485#[test]
486fn associated_type_shorthand_from_method_bound() {
487 check_types(
488 r#"
489trait Iterable {
490 type Item;
491}
492struct S<T>;
493impl<T> S<T> {
494 fn foo(self) -> T::Item where T: Iterable { loop {} }
495}
496fn test<T: Iterable>() {
497 let s: S<T>;
498 s.foo();
499 // ^^^^^^^ Iterable::Item<T>
500}"#,
501 );
502}
503
504#[test]
505fn associated_type_shorthand_from_self_issue_12484() {
506 check_types(
507 r#"
508trait Bar {
509 type A;
510}
511trait Foo {
512 type A;
513 fn test(a: Self::A, _: impl Bar) {
514 a;
515 //^ Foo::A<Self>
516 }
517}"#,
518 );
519}
520
521#[test]
522fn infer_associated_type_bound() {
523 check_types(
524 r#"
525trait Iterable {
526 type Item;
527}
528fn test<T: Iterable<Item=u32>>() {
529 let y: T::Item = unknown;
530 // ^^^^^^^ u32
531}"#,
532 );
533}
534
535#[test]
536fn infer_const_body() {
537 // FIXME make check_types work with other bodies
538 check_infer(
539 r#"
540const A: u32 = 1 + 1;
541static B: u64 = { let x = 1; x };
542"#,
543 expect![[r#"
544 15..16 '1': u32
545 15..20 '1 + 1': u32
546 19..20 '1': u32
547 38..54 '{ let ...1; x }': u64
548 44..45 'x': u64
549 48..49 '1': u64
550 51..52 'x': u64
551 "#]],
552 );
553}
554
555#[test]
556fn tuple_struct_fields() {
557 check_infer(
558 r#"
559struct S(i32, u64);
560fn test() -> u64 {
561 let a = S(4, 6);
562 let b = a.0;
563 a.1
564}"#,
565 expect![[r#"
566 37..86 '{ ... a.1 }': u64
567 47..48 'a': S
568 51..52 'S': S(i32, u64) -> S
569 51..58 'S(4, 6)': S
570 53..54 '4': i32
571 56..57 '6': u64
572 68..69 'b': i32
573 72..73 'a': S
574 72..75 'a.0': i32
575 81..82 'a': S
576 81..84 'a.1': u64
577 "#]],
578 );
579}
580
581#[test]
582fn tuple_struct_with_fn() {
583 check_infer(
584 r#"
585struct S(fn(u32) -> u64);
586fn test() -> u64 {
587 let a = S(|i| 2*i);
588 let b = a.0(4);
589 a.0(2)
590}"#,
591 expect![[r#"
592 43..101 '{ ...0(2) }': u64
593 53..54 'a': S
594 57..58 'S': S(fn(u32) -> u64) -> S
595 57..67 'S(|i| 2*i)': S
596 59..66 '|i| 2*i': |u32| -> u64
597 60..61 'i': u32
598 63..64 '2': u32
599 63..66 '2*i': u32
600 65..66 'i': u32
601 77..78 'b': u64
602 81..82 'a': S
603 81..84 'a.0': fn(u32) -> u64
604 81..87 'a.0(4)': u64
605 85..86 '4': u32
606 93..94 'a': S
607 93..96 'a.0': fn(u32) -> u64
608 93..99 'a.0(2)': u64
609 97..98 '2': u32
610 "#]],
611 );
612}
613
614#[test]
615fn indexing_arrays() {
616 check_infer(
617 "fn main() { &mut [9][2]; }",
618 expect![[r#"
619 10..26 '{ &mut...[2]; }': ()
620 12..23 '&mut [9][2]': &mut {unknown}
621 17..20 '[9]': [i32; 1]
622 17..23 '[9][2]': {unknown}
623 18..19 '9': i32
624 21..22 '2': i32
625 "#]],
626 )
627}
628
629#[test]
630fn infer_ops_index() {
631 check_types(
632 r#"
633//- minicore: index
634struct Bar;
635struct Foo;
636
637impl core::ops::Index<u32> for Bar {
638 type Output = Foo;
639}
640
641fn test() {
642 let a = Bar;
643 let b = a[1u32];
644 b;
645} //^ Foo
646"#,
647 );
648}
649
650#[test]
651fn infer_ops_index_field() {
652 check_types(
653 r#"
654//- minicore: index
655struct Bar;
656struct Foo {
657 field: u32;
658}
659
660impl core::ops::Index<u32> for Bar {
661 type Output = Foo;
662}
663
664fn test() {
665 let a = Bar;
666 let b = a[1u32].field;
667 b;
668} //^ u32
669"#,
670 );
671}
672
673#[test]
674fn infer_ops_index_field_autoderef() {
675 check_types(
676 r#"
677//- minicore: index
678struct Bar;
679struct Foo {
680 field: u32;
681}
682
683impl core::ops::Index<u32> for Bar {
684 type Output = Foo;
685}
686
687fn test() {
688 let a = Bar;
689 let b = (&a[1u32]).field;
690 b;
691} //^ u32
692"#,
693 );
694}
695
696#[test]
697fn infer_ops_index_int() {
698 check_types(
699 r#"
700//- minicore: index
701struct Bar;
702struct Foo;
703
704impl core::ops::Index<u32> for Bar {
705 type Output = Foo;
706}
707
708struct Range;
709impl core::ops::Index<Range> for Bar {
710 type Output = Bar;
711}
712
713fn test() {
714 let a = Bar;
715 let b = a[1];
716 b;
717 //^ Foo
718}
719"#,
720 );
721}
722
723#[test]
724fn infer_ops_index_autoderef() {
725 check_types(
726 r#"
727//- minicore: index, slice
728fn test() {
729 let a = &[1u32, 2, 3];
730 let b = a[1];
731 b;
732} //^ u32
733"#,
734 );
735}
736
737#[test]
738fn deref_trait() {
739 check_types(
740 r#"
741//- minicore: deref
742struct Arc<T: ?Sized>;
743impl<T: ?Sized> core::ops::Deref for Arc<T> {
744 type Target = T;
745}
746
747struct S;
748impl S {
749 fn foo(&self) -> u128 { 0 }
750}
751
752fn test(s: Arc<S>) {
753 (*s, s.foo());
754} //^^^^^^^^^^^^^ (S, u128)
755"#,
756 );
757}
758
759#[test]
760fn deref_trait_with_inference_var() {
761 check_types(
762 r#"
763//- minicore: deref
764struct Arc<T: ?Sized>;
765fn new_arc<T: ?Sized>() -> Arc<T> { Arc }
766impl<T: ?Sized> core::ops::Deref for Arc<T> {
767 type Target = T;
768}
769
770struct S;
771fn foo(a: Arc<S>) {}
772
773fn test() {
774 let a = new_arc();
775 let b = *a;
776 //^^ S
777 foo(a);
778}
779"#,
780 );
781}
782
783#[test]
784fn deref_trait_infinite_recursion() {
785 check_types(
786 r#"
787//- minicore: deref
788struct S;
789
790impl core::ops::Deref for S {
791 type Target = S;
792}
793
794fn test(s: S) {
795 s.foo();
796} //^^^^^^^ {unknown}
797"#,
798 );
799}
800
801#[test]
802fn deref_trait_with_question_mark_size() {
803 check_types(
804 r#"
805//- minicore: deref
806struct Arc<T: ?Sized>;
807impl<T: ?Sized> core::ops::Deref for Arc<T> {
808 type Target = T;
809}
810
811struct S;
812impl S {
813 fn foo(&self) -> u128 { 0 }
814}
815
816fn test(s: Arc<S>) {
817 (*s, s.foo());
818} //^^^^^^^^^^^^^ (S, u128)
819"#,
820 );
821}
822
823#[test]
824fn deref_trait_with_implicit_sized_requirement_on_inference_var() {
825 check_types(
826 r#"
827//- minicore: deref
828struct Foo<T>;
829impl<T> core::ops::Deref for Foo<T> {
830 type Target = ();
831}
832fn test() {
833 let foo = Foo;
834 *foo;
835 //^^^^ ()
836 let _: Foo<u8> = foo;
837}
838"#,
839 )
840}
841
842#[test]
843fn obligation_from_function_clause() {
844 check_types(
845 r#"
846struct S;
847
848trait Trait<T> {}
849impl Trait<u32> for S {}
850
851fn foo<T: Trait<U>, U>(t: T) -> U { loop {} }
852
853fn test(s: S) {
854 foo(s);
855} //^^^^^^ u32
856"#,
857 );
858}
859
860#[test]
861fn obligation_from_method_clause() {
862 check_types(
863 r#"
864//- /main.rs
865struct S;
866
867trait Trait<T> {}
868impl Trait<isize> for S {}
869
870struct O;
871impl O {
872 fn foo<T: Trait<U>, U>(&self, t: T) -> U { loop {} }
873}
874
875fn test() {
876 O.foo(S);
877} //^^^^^^^^ isize
878"#,
879 );
880}
881
882#[test]
883fn obligation_from_self_method_clause() {
884 check_types(
885 r#"
886struct S;
887
888trait Trait<T> {}
889impl Trait<i64> for S {}
890
891impl S {
892 fn foo<U>(&self) -> U where Self: Trait<U> { loop {} }
893}
894
895fn test() {
896 S.foo();
897} //^^^^^^^ i64
898"#,
899 );
900}
901
902#[test]
903fn obligation_from_impl_clause() {
904 check_types(
905 r#"
906struct S;
907
908trait Trait<T> {}
909impl Trait<&str> for S {}
910
911struct O<T>;
912impl<U, T: Trait<U>> O<T> {
913 fn foo(&self) -> U { loop {} }
914}
915
916fn test(o: O<S>) {
917 o.foo();
918} //^^^^^^^ &str
919"#,
920 );
921}
922
923#[test]
924fn generic_param_env_1() {
925 check_types(
926 r#"
927trait Clone {}
928trait Trait { fn foo(self) -> u128; }
929struct S;
930impl Clone for S {}
931impl<T> Trait for T where T: Clone {}
932fn test<T: Clone>(t: T) { t.foo(); }
933 //^^^^^^^ u128
934"#,
935 );
936}
937
938#[test]
939fn generic_param_env_1_not_met() {
940 check_types(
941 r#"
942//- /main.rs
943trait Clone {}
944trait Trait { fn foo(self) -> u128; }
945struct S;
946impl Clone for S {}
947impl<T> Trait for T where T: Clone {}
948fn test<T>(t: T) { t.foo(); }
949 //^^^^^^^ {unknown}
950"#,
951 );
952}
953
954#[test]
955fn generic_param_env_2() {
956 check_types(
957 r#"
958trait Trait { fn foo(self) -> u128; }
959struct S;
960impl Trait for S {}
961fn test<T: Trait>(t: T) { t.foo(); }
962 //^^^^^^^ u128
963"#,
964 );
965}
966
967#[test]
968fn generic_param_env_2_not_met() {
969 check_types(
970 r#"
971trait Trait { fn foo(self) -> u128; }
972struct S;
973impl Trait for S {}
974fn test<T>(t: T) { t.foo(); }
975 //^^^^^^^ {unknown}
976"#,
977 );
978}
979
980#[test]
981fn generic_param_env_deref() {
982 check_types(
983 r#"
984//- minicore: deref
985trait Trait {}
986impl<T> core::ops::Deref for T where T: Trait {
987 type Target = i128;
988}
989fn test<T: Trait>(t: T) { *t; }
990 //^^ i128
991"#,
992 );
993}
994
995#[test]
996fn associated_type_placeholder() {
997 // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types].
998 check_types(
999 r#"
1000pub trait ApplyL {
1001 type Out;
1002}
1003
1004pub struct RefMutL<T>;
1005
1006impl<T> ApplyL for RefMutL<T> {
1007 type Out = <T as ApplyL>::Out;
1008}
1009
1010fn test<T: ApplyL>() {
1011 let y: <RefMutL<T> as ApplyL>::Out = no_matter;
1012 y;
1013} //^ ApplyL::Out<T>
1014"#,
1015 );
1016}
1017
1018#[test]
1019fn associated_type_placeholder_2() {
1020 check_types(
1021 r#"
1022pub trait ApplyL {
1023 type Out;
1024}
1025fn foo<T: ApplyL>(t: T) -> <T as ApplyL>::Out;
1026
1027fn test<T: ApplyL>(t: T) {
1028 let y = foo(t);
1029 y;
1030} //^ ApplyL::Out<T>
1031"#,
1032 );
1033}
1034
1035#[test]
1036fn argument_impl_trait() {
1037 check_infer_with_mismatches(
1038 r#"
1039//- minicore: sized
1040trait Trait<T> {
1041 fn foo(&self) -> T;
1042 fn foo2(&self) -> i64;
1043}
1044fn bar(x: impl Trait<u16>) {}
1045struct S<T>(T);
1046impl<T> Trait<T> for S<T> {}
1047
1048fn test(x: impl Trait<u64>, y: &impl Trait<u32>) {
1049 x;
1050 y;
1051 let z = S(1);
1052 bar(z);
1053 x.foo();
1054 y.foo();
1055 z.foo();
1056 x.foo2();
1057 y.foo2();
1058 z.foo2();
1059}"#,
1060 expect![[r#"
1061 29..33 'self': &Self
1062 54..58 'self': &Self
1063 77..78 'x': impl Trait<u16>
1064 97..99 '{}': ()
1065 154..155 'x': impl Trait<u64>
1066 174..175 'y': &impl Trait<u32>
1067 195..323 '{ ...2(); }': ()
1068 201..202 'x': impl Trait<u64>
1069 208..209 'y': &impl Trait<u32>
1070 219..220 'z': S<u16>
1071 223..224 'S': S<u16>(u16) -> S<u16>
1072 223..227 'S(1)': S<u16>
1073 225..226 '1': u16
1074 233..236 'bar': fn bar(S<u16>)
1075 233..239 'bar(z)': ()
1076 237..238 'z': S<u16>
1077 245..246 'x': impl Trait<u64>
1078 245..252 'x.foo()': u64
1079 258..259 'y': &impl Trait<u32>
1080 258..265 'y.foo()': u32
1081 271..272 'z': S<u16>
1082 271..278 'z.foo()': u16
1083 284..285 'x': impl Trait<u64>
1084 284..292 'x.foo2()': i64
1085 298..299 'y': &impl Trait<u32>
1086 298..306 'y.foo2()': i64
1087 312..313 'z': S<u16>
1088 312..320 'z.foo2()': i64
1089 "#]],
1090 );
1091}
1092
1093#[test]
1094fn argument_impl_trait_type_args_1() {
1095 check_infer_with_mismatches(
1096 r#"
1097//- minicore: sized
1098trait Trait {}
1099trait Foo {
1100 // this function has an implicit Self param, an explicit type param,
1101 // and an implicit impl Trait param!
1102 fn bar<T>(x: impl Trait) -> T { loop {} }
1103}
1104fn foo<T>(x: impl Trait) -> T { loop {} }
1105struct S;
1106impl Trait for S {}
1107struct F;
1108impl Foo for F {}
1109
1110fn test() {
1111 Foo::bar(S);
1112 <F as Foo>::bar(S);
1113 F::bar(S);
1114 Foo::bar::<u32>(S);
1115 <F as Foo>::bar::<u32>(S);
1116
1117 foo(S);
1118 foo::<u32>(S);
1119 foo::<u32, i32>(S); // we should ignore the extraneous i32
1120}"#,
1121 expect![[r#"
1122 155..156 'x': impl Trait
1123 175..186 '{ loop {} }': T
1124 177..184 'loop {}': !
1125 182..184 '{}': ()
1126 199..200 'x': impl Trait
1127 219..230 '{ loop {} }': T
1128 221..228 'loop {}': !
1129 226..228 '{}': ()
1130 300..509 '{ ... i32 }': ()
1131 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown}
1132 306..317 'Foo::bar(S)': {unknown}
1133 315..316 'S': S
1134 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown}
1135 323..341 '<F as ...bar(S)': {unknown}
1136 339..340 'S': S
1137 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown}
1138 347..356 'F::bar(S)': {unknown}
1139 354..355 'S': S
1140 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32
1141 362..380 'Foo::b...32>(S)': u32
1142 378..379 'S': S
1143 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32
1144 386..411 '<F as ...32>(S)': u32
1145 409..410 'S': S
1146 418..421 'foo': fn foo<{unknown}>(S) -> {unknown}
1147 418..424 'foo(S)': {unknown}
1148 422..423 'S': S
1149 430..440 'foo::<u32>': fn foo<u32>(S) -> u32
1150 430..443 'foo::<u32>(S)': u32
1151 441..442 'S': S
1152 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32
1153 449..467 'foo::<...32>(S)': u32
1154 465..466 'S': S
1155 "#]],
1156 );
1157}
1158
1159#[test]
1160fn argument_impl_trait_type_args_2() {
1161 check_infer_with_mismatches(
1162 r#"
1163//- minicore: sized
1164trait Trait {}
1165struct S;
1166impl Trait for S {}
1167struct F<T>;
1168impl<T> F<T> {
1169 fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} }
1170}
1171
1172fn test() {
1173 F.foo(S);
1174 F::<u32>.foo(S);
1175 F::<u32>.foo::<i32>(S);
1176 F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored
1177}"#,
1178 expect![[r#"
1179 87..91 'self': F<T>
1180 93..94 'x': impl Trait
1181 118..129 '{ loop {} }': (T, U)
1182 120..127 'loop {}': !
1183 125..127 '{}': ()
1184 143..283 '{ ...ored }': ()
1185 149..150 'F': F<{unknown}>
1186 149..157 'F.foo(S)': ({unknown}, {unknown})
1187 155..156 'S': S
1188 163..171 'F::<u32>': F<u32>
1189 163..178 'F::<u32>.foo(S)': (u32, {unknown})
1190 176..177 'S': S
1191 184..192 'F::<u32>': F<u32>
1192 184..206 'F::<u3...32>(S)': (u32, i32)
1193 204..205 'S': S
1194 212..220 'F::<u32>': F<u32>
1195 212..239 'F::<u3...32>(S)': (u32, i32)
1196 237..238 'S': S
1197 "#]],
1198 );
1199}
1200
1201#[test]
1202fn argument_impl_trait_to_fn_pointer() {
1203 check_infer_with_mismatches(
1204 r#"
1205//- minicore: sized
1206trait Trait {}
1207fn foo(x: impl Trait) { loop {} }
1208struct S;
1209impl Trait for S {}
1210
1211fn test() {
1212 let f: fn(S) -> () = foo;
1213}"#,
1214 expect![[r#"
1215 22..23 'x': impl Trait
1216 37..48 '{ loop {} }': ()
1217 39..46 'loop {}': !
1218 44..46 '{}': ()
1219 90..123 '{ ...foo; }': ()
1220 100..101 'f': fn(S)
1221 117..120 'foo': fn foo(S)
1222 "#]],
1223 );
1224}
1225
1226#[test]
1227fn impl_trait() {
1228 check_infer(
1229 r#"
1230//- minicore: sized
1231trait Trait<T> {
1232 fn foo(&self) -> T;
1233 fn foo2(&self) -> i64;
1234}
1235fn bar() -> impl Trait<u64> {}
1236
1237fn test(x: impl Trait<u64>, y: &impl Trait<u64>) {
1238 x;
1239 y;
1240 let z = bar();
1241 x.foo();
1242 y.foo();
1243 z.foo();
1244 x.foo2();
1245 y.foo2();
1246 z.foo2();
1247}"#,
1248 expect![[r#"
1249 29..33 'self': &Self
1250 54..58 'self': &Self
1251 98..100 '{}': ()
1252 110..111 'x': impl Trait<u64>
1253 130..131 'y': &impl Trait<u64>
1254 151..268 '{ ...2(); }': ()
1255 157..158 'x': impl Trait<u64>
1256 164..165 'y': &impl Trait<u64>
1257 175..176 'z': impl Trait<u64>
1258 179..182 'bar': fn bar() -> impl Trait<u64>
1259 179..184 'bar()': impl Trait<u64>
1260 190..191 'x': impl Trait<u64>
1261 190..197 'x.foo()': u64
1262 203..204 'y': &impl Trait<u64>
1263 203..210 'y.foo()': u64
1264 216..217 'z': impl Trait<u64>
1265 216..223 'z.foo()': u64
1266 229..230 'x': impl Trait<u64>
1267 229..237 'x.foo2()': i64
1268 243..244 'y': &impl Trait<u64>
1269 243..251 'y.foo2()': i64
1270 257..258 'z': impl Trait<u64>
1271 257..265 'z.foo2()': i64
1272 "#]],
1273 );
1274}
1275
1276#[test]
1277fn simple_return_pos_impl_trait() {
1278 cov_mark::check!(lower_rpit);
1279 check_infer(
1280 r#"
1281//- minicore: sized
1282trait Trait<T> {
1283 fn foo(&self) -> T;
1284}
1285fn bar() -> impl Trait<u64> { loop {} }
1286
1287fn test() {
1288 let a = bar();
1289 a.foo();
1290}"#,
1291 expect![[r#"
1292 29..33 'self': &Self
1293 71..82 '{ loop {} }': !
1294 73..80 'loop {}': !
1295 78..80 '{}': ()
1296 94..129 '{ ...o(); }': ()
1297 104..105 'a': impl Trait<u64>
1298 108..111 'bar': fn bar() -> impl Trait<u64>
1299 108..113 'bar()': impl Trait<u64>
1300 119..120 'a': impl Trait<u64>
1301 119..126 'a.foo()': u64
1302 "#]],
1303 );
1304}
1305
1306#[test]
1307fn more_return_pos_impl_trait() {
1308 check_infer(
1309 r#"
1310//- minicore: sized
1311trait Iterator {
1312 type Item;
1313 fn next(&mut self) -> Self::Item;
1314}
1315trait Trait<T> {
1316 fn foo(&self) -> T;
1317}
1318fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} }
1319fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} }
1320
1321fn test() {
1322 let (a, b) = bar();
1323 a.next().foo();
1324 b.foo();
1325 let (c, d) = baz(1u128);
1326 c.next().foo();
1327 d.foo();
1328}"#,
1329 expect![[r#"
1330 49..53 'self': &mut Self
1331 101..105 'self': &Self
1332 184..195 '{ loop {} }': ({unknown}, {unknown})
1333 186..193 'loop {}': !
1334 191..193 '{}': ()
1335 206..207 't': T
1336 268..279 '{ loop {} }': ({unknown}, {unknown})
1337 270..277 'loop {}': !
1338 275..277 '{}': ()
1339 291..413 '{ ...o(); }': ()
1340 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1341 302..303 'a': impl Iterator<Item = impl Trait<u32>>
1342 305..306 'b': impl Trait<u64>
1343 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1344 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>)
1345 321..322 'a': impl Iterator<Item = impl Trait<u32>>
1346 321..329 'a.next()': impl Trait<u32>
1347 321..335 'a.next().foo()': u32
1348 341..342 'b': impl Trait<u64>
1349 341..348 'b.foo()': u64
1350 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1351 359..360 'c': impl Iterator<Item = impl Trait<u128>>
1352 362..363 'd': impl Trait<u128>
1353 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1354 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>)
1355 371..376 '1u128': u128
1356 383..384 'c': impl Iterator<Item = impl Trait<u128>>
1357 383..391 'c.next()': impl Trait<u128>
1358 383..397 'c.next().foo()': u128
1359 403..404 'd': impl Trait<u128>
1360 403..410 'd.foo()': u128
1361 "#]],
1362 );
1363}
1364
1365#[test]
1366fn infer_from_return_pos_impl_trait() {
1367 check_infer_with_mismatches(
1368 r#"
1369//- minicore: fn, sized
1370trait Trait<T> {}
1371struct Bar<T>(T);
1372impl<T> Trait<T> for Bar<T> {}
1373fn foo<const C: u8, T>() -> (impl FnOnce(&str, T), impl Trait<u8>) {
1374 (|input, t| {}, Bar(C))
1375}
1376"#,
1377 expect![[r#"
1378 134..165 '{ ...(C)) }': (|&str, T| -> (), Bar<u8>)
1379 140..163 '(|inpu...ar(C))': (|&str, T| -> (), Bar<u8>)
1380 141..154 '|input, t| {}': |&str, T| -> ()
1381 142..147 'input': &str
1382 149..150 't': T
1383 152..154 '{}': ()
1384 156..159 'Bar': Bar<u8>(u8) -> Bar<u8>
1385 156..162 'Bar(C)': Bar<u8>
1386 160..161 'C': u8
1387 "#]],
1388 );
1389}
1390
f25598a0
FG
1391#[test]
1392fn return_pos_impl_trait_in_projection() {
1393 // Note that the unused type param `X` is significant; see #13307.
1394 check_no_mismatches(
1395 r#"
1396//- minicore: sized
1397trait Future { type Output; }
1398impl Future for () { type Output = i32; }
1399type Foo<F> = (<F as Future>::Output, F);
1400fn foo<X>() -> Foo<impl Future<Output = ()>> {
1401 (0, ())
1402}
1403"#,
1404 )
1405}
1406
064997fb
FG
1407#[test]
1408fn dyn_trait() {
1409 check_infer(
1410 r#"
1411//- minicore: sized
1412trait Trait<T> {
1413 fn foo(&self) -> T;
1414 fn foo2(&self) -> i64;
1415}
1416fn bar() -> dyn Trait<u64> {}
1417
1418fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
1419 x;
1420 y;
1421 let z = bar();
1422 x.foo();
1423 y.foo();
1424 z.foo();
1425 x.foo2();
1426 y.foo2();
1427 z.foo2();
1428}"#,
1429 expect![[r#"
1430 29..33 'self': &Self
1431 54..58 'self': &Self
1432 97..99 '{}': dyn Trait<u64>
1433 109..110 'x': dyn Trait<u64>
1434 128..129 'y': &dyn Trait<u64>
1435 148..265 '{ ...2(); }': ()
1436 154..155 'x': dyn Trait<u64>
1437 161..162 'y': &dyn Trait<u64>
1438 172..173 'z': dyn Trait<u64>
1439 176..179 'bar': fn bar() -> dyn Trait<u64>
1440 176..181 'bar()': dyn Trait<u64>
1441 187..188 'x': dyn Trait<u64>
1442 187..194 'x.foo()': u64
1443 200..201 'y': &dyn Trait<u64>
1444 200..207 'y.foo()': u64
1445 213..214 'z': dyn Trait<u64>
1446 213..220 'z.foo()': u64
1447 226..227 'x': dyn Trait<u64>
1448 226..234 'x.foo2()': i64
1449 240..241 'y': &dyn Trait<u64>
1450 240..248 'y.foo2()': i64
1451 254..255 'z': dyn Trait<u64>
1452 254..262 'z.foo2()': i64
1453 "#]],
1454 );
1455}
1456
1457#[test]
1458fn dyn_trait_in_impl() {
1459 check_infer(
1460 r#"
1461//- minicore: sized
1462trait Trait<T, U> {
1463 fn foo(&self) -> (T, U);
1464}
1465struct S<T, U> {}
1466impl<T, U> S<T, U> {
1467 fn bar(&self) -> &dyn Trait<T, U> { loop {} }
1468}
1469trait Trait2<T, U> {
1470 fn baz(&self) -> (T, U);
1471}
1472impl<T, U> Trait2<T, U> for dyn Trait<T, U> { }
1473
1474fn test(s: S<u32, i32>) {
1475 s.bar().baz();
1476}"#,
1477 expect![[r#"
1478 32..36 'self': &Self
1479 102..106 'self': &S<T, U>
1480 128..139 '{ loop {} }': &dyn Trait<T, U>
1481 130..137 'loop {}': !
1482 135..137 '{}': ()
1483 175..179 'self': &Self
1484 251..252 's': S<u32, i32>
1485 267..289 '{ ...z(); }': ()
1486 273..274 's': S<u32, i32>
1487 273..280 's.bar()': &dyn Trait<u32, i32>
1488 273..286 's.bar().baz()': (u32, i32)
1489 "#]],
1490 );
1491}
1492
1493#[test]
1494fn dyn_trait_bare() {
1495 check_infer(
1496 r#"
1497//- minicore: sized
1498trait Trait {
1499 fn foo(&self) -> u64;
1500}
1501fn bar() -> Trait {}
1502
1503fn test(x: Trait, y: &Trait) -> u64 {
1504 x;
1505 y;
1506 let z = bar();
1507 x.foo();
1508 y.foo();
1509 z.foo();
1510}"#,
1511 expect![[r#"
1512 26..30 'self': &Self
1513 60..62 '{}': dyn Trait
1514 72..73 'x': dyn Trait
1515 82..83 'y': &dyn Trait
1516 100..175 '{ ...o(); }': u64
1517 106..107 'x': dyn Trait
1518 113..114 'y': &dyn Trait
1519 124..125 'z': dyn Trait
1520 128..131 'bar': fn bar() -> dyn Trait
1521 128..133 'bar()': dyn Trait
1522 139..140 'x': dyn Trait
1523 139..146 'x.foo()': u64
1524 152..153 'y': &dyn Trait
1525 152..159 'y.foo()': u64
1526 165..166 'z': dyn Trait
1527 165..172 'z.foo()': u64
1528 "#]],
1529 );
f2b60f7d
FG
1530
1531 check_infer_with_mismatches(
1532 r#"
1533//- minicore: fn, coerce_unsized
1534struct S;
1535impl S {
1536 fn foo(&self) {}
1537}
1538fn f(_: &Fn(S)) {}
1539fn main() {
1540 f(&|number| number.foo());
1541}
1542 "#,
1543 expect![[r#"
1544 31..35 'self': &S
1545 37..39 '{}': ()
1546 47..48 '_': &dyn Fn(S)
1547 58..60 '{}': ()
1548 71..105 '{ ...()); }': ()
1549 77..78 'f': fn f(&dyn Fn(S))
1550 77..102 'f(&|nu...foo())': ()
1551 79..101 '&|numb....foo()': &|S| -> ()
1552 80..101 '|numbe....foo()': |S| -> ()
1553 81..87 'number': S
1554 89..95 'number': S
1555 89..101 'number.foo()': ()
1556 "#]],
1557 )
064997fb
FG
1558}
1559
1560#[test]
1561fn weird_bounds() {
1562 check_infer(
1563 r#"
1564//- minicore: sized
1565trait Trait {}
1566fn test(
1567 a: impl Trait + 'lifetime,
1568 b: impl 'lifetime,
1569 c: impl (Trait),
1570 d: impl ('lifetime),
1571 e: impl ?Sized,
1572 f: impl Trait + ?Sized
1573) {}
1574"#,
1575 expect![[r#"
1576 28..29 'a': impl Trait
1577 59..60 'b': impl Sized
1578 82..83 'c': impl Trait
1579 103..104 'd': impl Sized
1580 128..129 'e': impl ?Sized
1581 148..149 'f': impl Trait + ?Sized
1582 173..175 '{}': ()
1583 "#]],
1584 );
1585}
1586
1587#[test]
1588fn error_bound_chalk() {
1589 check_types(
1590 r#"
1591trait Trait {
1592 fn foo(&self) -> u32 { 0 }
1593}
1594
1595fn test(x: (impl Trait + UnknownTrait)) {
1596 x.foo();
1597} //^^^^^^^ u32
1598"#,
1599 );
1600}
1601
1602#[test]
1603fn assoc_type_bindings() {
1604 check_infer(
1605 r#"
1606//- minicore: sized
1607trait Trait {
1608 type Type;
1609}
1610
1611fn get<T: Trait>(t: T) -> <T as Trait>::Type {}
1612fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1613fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1614
1615struct S<T>;
1616impl<T> Trait for S<T> { type Type = T; }
1617
1618fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1619 get(x);
1620 get2(x);
1621 get(y);
1622 get2(y);
1623 get(set(S));
1624 get2(set(S));
1625 get2(S::<str>);
1626}"#,
1627 expect![[r#"
1628 49..50 't': T
1629 77..79 '{}': Trait::Type<T>
1630 111..112 't': T
1631 122..124 '{}': U
1632 154..155 't': T
1633 165..168 '{t}': T
1634 166..167 't': T
1635 256..257 'x': T
1636 262..263 'y': impl Trait<Type = i64>
1637 289..397 '{ ...r>); }': ()
1638 295..298 'get': fn get<T>(T) -> <T as Trait>::Type
1639 295..301 'get(x)': u32
1640 299..300 'x': T
1641 307..311 'get2': fn get2<u32, T>(T) -> u32
1642 307..314 'get2(x)': u32
1643 312..313 'x': T
1644 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1645 320..326 'get(y)': i64
1646 324..325 'y': impl Trait<Type = i64>
1647 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64
1648 332..339 'get2(y)': i64
1649 337..338 'y': impl Trait<Type = i64>
1650 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1651 345..356 'get(set(S))': u64
1652 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1653 349..355 'set(S)': S<u64>
1654 353..354 'S': S<u64>
1655 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1656 362..374 'get2(set(S))': u64
1657 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1658 367..373 'set(S)': S<u64>
1659 371..372 'S': S<u64>
1660 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str
1661 380..394 'get2(S::<str>)': str
1662 385..393 'S::<str>': S<str>
1663 "#]],
1664 );
1665}
1666
1667#[test]
1668fn impl_trait_assoc_binding_projection_bug() {
1669 check_types(
1670 r#"
1671//- minicore: iterator
1672pub trait Language {
1673 type Kind;
1674}
1675pub enum RustLanguage {}
1676impl Language for RustLanguage {
1677 type Kind = SyntaxKind;
1678}
1679struct SyntaxNode<L> {}
1680fn foo() -> impl Iterator<Item = SyntaxNode<RustLanguage>> {}
1681
1682trait Clone {
1683 fn clone(&self) -> Self;
1684}
1685
1686fn api_walkthrough() {
1687 for node in foo() {
1688 node.clone();
1689 } //^^^^^^^^^^^^ {unknown}
1690}
1691"#,
1692 );
1693}
1694
1695#[test]
1696fn projection_eq_within_chalk() {
1697 check_infer(
1698 r#"
1699trait Trait1 {
1700 type Type;
1701}
1702trait Trait2<T> {
1703 fn foo(self) -> T;
1704}
1705impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
1706
1707fn test<T: Trait1<Type = u32>>(x: T) {
1708 x.foo();
1709}"#,
1710 expect![[r#"
1711 61..65 'self': Self
1712 163..164 'x': T
1713 169..185 '{ ...o(); }': ()
1714 175..176 'x': T
1715 175..182 'x.foo()': u32
1716 "#]],
1717 );
1718}
1719
1720#[test]
1721fn where_clause_trait_in_scope_for_method_resolution() {
1722 check_types(
1723 r#"
1724mod foo {
487cf647 1725 pub trait Trait {
064997fb
FG
1726 fn foo(&self) -> u32 { 0 }
1727 }
1728}
1729
1730fn test<T: foo::Trait>(x: T) {
1731 x.foo();
1732} //^^^^^^^ u32
1733"#,
1734 );
1735}
1736
1737#[test]
1738fn super_trait_method_resolution() {
1739 check_infer(
1740 r#"
1741mod foo {
487cf647 1742 pub trait SuperTrait {
064997fb
FG
1743 fn foo(&self) -> u32 {}
1744 }
1745}
1746trait Trait1: foo::SuperTrait {}
1747trait Trait2 where Self: foo::SuperTrait {}
1748
1749fn test<T: Trait1, U: Trait2>(x: T, y: U) {
1750 x.foo();
1751 y.foo();
1752}"#,
1753 expect![[r#"
487cf647
FG
1754 53..57 'self': &Self
1755 66..68 '{}': u32
1756 185..186 'x': T
1757 191..192 'y': U
1758 197..226 '{ ...o(); }': ()
1759 203..204 'x': T
1760 203..210 'x.foo()': u32
1761 216..217 'y': U
1762 216..223 'y.foo()': u32
064997fb
FG
1763 "#]],
1764 );
1765}
1766
1767#[test]
1768fn super_trait_impl_trait_method_resolution() {
1769 check_infer(
1770 r#"
1771//- minicore: sized
1772mod foo {
487cf647 1773 pub trait SuperTrait {
064997fb
FG
1774 fn foo(&self) -> u32 {}
1775 }
1776}
1777trait Trait1: foo::SuperTrait {}
1778
1779fn test(x: &impl Trait1) {
1780 x.foo();
1781}"#,
1782 expect![[r#"
487cf647
FG
1783 53..57 'self': &Self
1784 66..68 '{}': u32
1785 119..120 'x': &impl Trait1
1786 136..152 '{ ...o(); }': ()
1787 142..143 'x': &impl Trait1
1788 142..149 'x.foo()': u32
064997fb
FG
1789 "#]],
1790 );
1791}
1792
1793#[test]
1794fn super_trait_cycle() {
1795 // This just needs to not crash
1796 check_infer(
1797 r#"
1798 trait A: B {}
1799 trait B: A {}
1800
1801 fn test<T: A>(x: T) {
1802 x.foo();
1803 }
1804 "#,
1805 expect![[r#"
1806 43..44 'x': T
1807 49..65 '{ ...o(); }': ()
1808 55..56 'x': T
1809 55..62 'x.foo()': {unknown}
1810 "#]],
1811 );
1812}
1813
1814#[test]
1815fn super_trait_assoc_type_bounds() {
1816 check_infer(
1817 r#"
1818trait SuperTrait { type Type; }
1819trait Trait where Self: SuperTrait {}
1820
1821fn get2<U, T: Trait<Type = U>>(t: T) -> U {}
1822fn set<T: Trait<Type = u64>>(t: T) -> T {t}
1823
1824struct S<T>;
1825impl<T> SuperTrait for S<T> { type Type = T; }
1826impl<T> Trait for S<T> {}
1827
1828fn test() {
1829 get2(set(S));
1830}"#,
1831 expect![[r#"
1832 102..103 't': T
1833 113..115 '{}': U
1834 145..146 't': T
1835 156..159 '{t}': T
1836 157..158 't': T
1837 258..279 '{ ...S)); }': ()
1838 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64
1839 264..276 'get2(set(S))': u64
1840 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64>
1841 269..275 'set(S)': S<u64>
1842 273..274 'S': S<u64>
1843 "#]],
1844 );
1845}
1846
1847#[test]
1848fn fn_trait() {
1849 check_infer_with_mismatches(
1850 r#"
1851trait FnOnce<Args> {
1852 type Output;
1853
1854 fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
1855}
1856
1857fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1858 f.call_once((1, 2));
1859}"#,
1860 expect![[r#"
1861 56..60 'self': Self
1862 62..66 'args': Args
1863 149..150 'f': F
1864 155..183 '{ ...2)); }': ()
1865 161..162 'f': F
1866 161..180 'f.call...1, 2))': u128
1867 173..179 '(1, 2)': (u32, u64)
1868 174..175 '1': u32
1869 177..178 '2': u64
1870 "#]],
1871 );
1872}
1873
1874#[test]
1875fn fn_ptr_and_item() {
1876 check_infer_with_mismatches(
1877 r#"
1878#[lang="fn_once"]
1879trait FnOnce<Args> {
1880 type Output;
1881
1882 fn call_once(self, args: Args) -> Self::Output;
1883}
1884
1885trait Foo<T> {
1886 fn foo(&self) -> T;
1887}
1888
1889struct Bar<T>(T);
1890
1891impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1892 fn foo(&self) -> (A1, R) { loop {} }
1893}
1894
1895enum Opt<T> { None, Some(T) }
1896impl<T> Opt<T> {
1897 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} }
1898}
1899
1900fn test() {
1901 let bar: Bar<fn(u8) -> u32>;
1902 bar.foo();
1903
1904 let opt: Opt<u8>;
1905 let f: fn(u8) -> u32;
1906 opt.map(f);
1907}"#,
1908 expect![[r#"
1909 74..78 'self': Self
1910 80..84 'args': Args
1911 139..143 'self': &Self
1912 243..247 'self': &Bar<F>
1913 260..271 '{ loop {} }': (A1, R)
1914 262..269 'loop {}': !
1915 267..269 '{}': ()
1916 355..359 'self': Opt<T>
1917 361..362 'f': F
1918 377..388 '{ loop {} }': Opt<U>
1919 379..386 'loop {}': !
1920 384..386 '{}': ()
1921 402..518 '{ ...(f); }': ()
1922 412..415 'bar': Bar<fn(u8) -> u32>
1923 441..444 'bar': Bar<fn(u8) -> u32>
1924 441..450 'bar.foo()': (u8, u32)
1925 461..464 'opt': Opt<u8>
1926 483..484 'f': fn(u8) -> u32
1927 505..508 'opt': Opt<u8>
1928 505..515 'opt.map(f)': Opt<u32>
1929 513..514 'f': fn(u8) -> u32
1930 "#]],
1931 );
1932}
1933
1934#[test]
1935fn fn_trait_deref_with_ty_default() {
1936 check_infer(
1937 r#"
1938//- minicore: deref, fn
1939struct Foo;
1940
1941impl Foo {
1942 fn foo(&self) -> usize {}
1943}
1944
1945struct Lazy<T, F = fn() -> T>(F);
1946
1947impl<T, F> Lazy<T, F> {
1948 pub fn new(f: F) -> Lazy<T, F> {}
1949}
1950
1951impl<T, F: FnOnce() -> T> core::ops::Deref for Lazy<T, F> {
1952 type Target = T;
1953}
1954
1955fn test() {
1956 let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo);
1957 let r1 = lazy1.foo();
1958
1959 fn make_foo_fn() -> Foo {}
1960 let make_foo_fn_ptr: fn() -> Foo = make_foo_fn;
1961 let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr);
1962 let r2 = lazy2.foo();
1963}"#,
1964 expect![[r#"
1965 36..40 'self': &Foo
1966 51..53 '{}': usize
1967 131..132 'f': F
1968 151..153 '{}': Lazy<T, F>
1969 251..497 '{ ...o(); }': ()
1970 261..266 'lazy1': Lazy<Foo, || -> Foo>
1971 283..292 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo>
1972 283..300 'Lazy::...| Foo)': Lazy<Foo, || -> Foo>
1973 293..299 '|| Foo': || -> Foo
1974 296..299 'Foo': Foo
1975 310..312 'r1': usize
1976 315..320 'lazy1': Lazy<Foo, || -> Foo>
1977 315..326 'lazy1.foo()': usize
1978 368..383 'make_foo_fn_ptr': fn() -> Foo
1979 399..410 'make_foo_fn': fn make_foo_fn() -> Foo
1980 420..425 'lazy2': Lazy<Foo, fn() -> Foo>
1981 442..451 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
1982 442..468 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
1983 452..467 'make_foo_fn_ptr': fn() -> Foo
1984 478..480 'r2': usize
1985 483..488 'lazy2': Lazy<Foo, fn() -> Foo>
1986 483..494 'lazy2.foo()': usize
1987 357..359 '{}': Foo
1988 "#]],
1989 );
1990}
1991
1992#[test]
1993fn closure_1() {
1994 check_infer_with_mismatches(
1995 r#"
1996//- minicore: fn
1997enum Option<T> { Some(T), None }
1998impl<T> Option<T> {
1999 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
2000}
2001
2002fn test() {
2003 let x = Option::Some(1u32);
2004 x.map(|v| v + 1);
2005 x.map(|_v| 1u64);
2006 let y: Option<i64> = x.map(|_v| 1);
2007}"#,
2008 expect![[r#"
2009 86..90 'self': Option<T>
2010 92..93 'f': F
2011 111..122 '{ loop {} }': Option<U>
2012 113..120 'loop {}': !
2013 118..120 '{}': ()
2014 136..255 '{ ... 1); }': ()
2015 146..147 'x': Option<u32>
2016 150..162 'Option::Some': Some<u32>(u32) -> Option<u32>
2017 150..168 'Option...(1u32)': Option<u32>
2018 163..167 '1u32': u32
2019 174..175 'x': Option<u32>
2020 174..190 'x.map(...v + 1)': Option<u32>
2021 180..189 '|v| v + 1': |u32| -> u32
2022 181..182 'v': u32
2023 184..185 'v': u32
2024 184..189 'v + 1': u32
2025 188..189 '1': u32
2026 196..197 'x': Option<u32>
2027 196..212 'x.map(... 1u64)': Option<u64>
2028 202..211 '|_v| 1u64': |u32| -> u64
2029 203..205 '_v': u32
2030 207..211 '1u64': u64
2031 222..223 'y': Option<i64>
2032 239..240 'x': Option<u32>
2033 239..252 'x.map(|_v| 1)': Option<i64>
2034 245..251 '|_v| 1': |u32| -> i64
2035 246..248 '_v': u32
2036 250..251 '1': i64
2037 "#]],
2038 );
2039}
2040
2041#[test]
2042fn closure_2() {
2043 check_types(
2044 r#"
2045//- minicore: add, fn
2046
2047impl core::ops::Add for u64 {
2048 type Output = Self;
2049 fn add(self, rhs: u64) -> Self::Output {0}
2050}
2051
2052impl core::ops::Add for u128 {
2053 type Output = Self;
2054 fn add(self, rhs: u128) -> Self::Output {0}
2055}
2056
2057fn test<F: FnOnce(u32) -> u64>(f: F) {
2058 f(1);
2059 // ^ u32
2060 //^^^^ u64
2061 let g = |v| v + 1;
2062 //^^^^^ u64
2063 //^^^^^^^^^ |u64| -> u64
2064 g(1u64);
2065 //^^^^^^^ u64
2066 let h = |v| 1u128 + v;
2067 //^^^^^^^^^^^^^ |u128| -> u128
2068}"#,
2069 );
2070}
2071
2072#[test]
2073fn closure_as_argument_inference_order() {
2074 check_infer_with_mismatches(
2075 r#"
2076//- minicore: fn
2077fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
2078fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
2079
2080struct S;
2081impl S {
2082 fn method(self) -> u64;
2083
2084 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} }
2085 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
2086}
2087
2088fn test() {
2089 let x1 = foo1(S, |s| s.method());
2090 let x2 = foo2(|s| s.method(), S);
2091 let x3 = S.foo1(S, |s| s.method());
2092 let x4 = S.foo2(|s| s.method(), S);
2093}"#,
2094 expect![[r#"
2095 33..34 'x': T
2096 39..40 'f': F
2097 50..61 '{ loop {} }': U
2098 52..59 'loop {}': !
2099 57..59 '{}': ()
2100 95..96 'f': F
2101 101..102 'x': T
2102 112..123 '{ loop {} }': U
2103 114..121 'loop {}': !
2104 119..121 '{}': ()
2105 158..162 'self': S
2106 210..214 'self': S
2107 216..217 'x': T
2108 222..223 'f': F
2109 233..244 '{ loop {} }': U
2110 235..242 'loop {}': !
2111 240..242 '{}': ()
2112 282..286 'self': S
2113 288..289 'f': F
2114 294..295 'x': T
2115 305..316 '{ loop {} }': U
2116 307..314 'loop {}': !
2117 312..314 '{}': ()
2118 330..489 '{ ... S); }': ()
2119 340..342 'x1': u64
2120 345..349 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
2121 345..368 'foo1(S...hod())': u64
2122 350..351 'S': S
2123 353..367 '|s| s.method()': |S| -> u64
2124 354..355 's': S
2125 357..358 's': S
2126 357..367 's.method()': u64
2127 378..380 'x2': u64
2128 383..387 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
2129 383..406 'foo2(|...(), S)': u64
2130 388..402 '|s| s.method()': |S| -> u64
2131 389..390 's': S
2132 392..393 's': S
2133 392..402 's.method()': u64
2134 404..405 'S': S
2135 416..418 'x3': u64
2136 421..422 'S': S
2137 421..446 'S.foo1...hod())': u64
2138 428..429 'S': S
2139 431..445 '|s| s.method()': |S| -> u64
2140 432..433 's': S
2141 435..436 's': S
2142 435..445 's.method()': u64
2143 456..458 'x4': u64
2144 461..462 'S': S
2145 461..486 'S.foo2...(), S)': u64
2146 468..482 '|s| s.method()': |S| -> u64
2147 469..470 's': S
2148 472..473 's': S
2149 472..482 's.method()': u64
2150 484..485 'S': S
2151 "#]],
2152 );
2153}
2154
2155#[test]
2156fn fn_item_fn_trait() {
2157 check_types(
2158 r#"
2159//- minicore: fn
2160struct S;
2161
2162fn foo() -> S { S }
2163
2164fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() }
2165
2166fn test() {
2167 takes_closure(foo);
2168} //^^^^^^^^^^^^^^^^^^ S
2169"#,
2170 );
2171}
2172
2173#[test]
2174fn unselected_projection_in_trait_env_1() {
2175 check_types(
2176 r#"
2177//- /main.rs
2178trait Trait {
2179 type Item;
2180}
2181
2182trait Trait2 {
2183 fn foo(&self) -> u32;
2184}
2185
2186fn test<T: Trait>() where T::Item: Trait2 {
2187 let x: T::Item = no_matter;
2188 x.foo();
2189} //^^^^^^^ u32
2190"#,
2191 );
2192}
2193
2194#[test]
2195fn unselected_projection_in_trait_env_2() {
2196 check_types(
2197 r#"
2198trait Trait<T> {
2199 type Item;
2200}
2201
2202trait Trait2 {
2203 fn foo(&self) -> u32;
2204}
2205
2206fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> {
2207 let x: T::Item = no_matter;
2208 x.foo();
2209} //^^^^^^^ u32
2210"#,
2211 );
2212}
2213
2214#[test]
2215fn unselected_projection_on_impl_self() {
2216 check_infer(
2217 r#"
2218//- /main.rs
2219trait Trait {
2220 type Item;
2221
2222 fn f(&self, x: Self::Item);
2223}
2224
2225struct S;
2226
2227impl Trait for S {
2228 type Item = u32;
2229 fn f(&self, x: Self::Item) { let y = x; }
2230}
2231
2232struct S2;
2233
2234impl Trait for S2 {
2235 type Item = i32;
2236 fn f(&self, x: <Self>::Item) { let y = x; }
2237}"#,
2238 expect![[r#"
2239 40..44 'self': &Self
2240 46..47 'x': Trait::Item<Self>
2241 126..130 'self': &S
2242 132..133 'x': u32
2243 147..161 '{ let y = x; }': ()
2244 153..154 'y': u32
2245 157..158 'x': u32
2246 228..232 'self': &S2
2247 234..235 'x': i32
2248 251..265 '{ let y = x; }': ()
2249 257..258 'y': i32
2250 261..262 'x': i32
2251 "#]],
2252 );
2253}
2254
2255#[test]
2256fn unselected_projection_on_trait_self() {
2257 check_types(
2258 r#"
2259trait Trait {
2260 type Item;
2261
2262 fn f(&self) -> Self::Item { loop {} }
2263}
2264
2265struct S;
2266impl Trait for S {
2267 type Item = u32;
2268}
2269
2270fn test() {
2271 S.f();
2272} //^^^^^ u32
2273"#,
2274 );
2275}
2276
2277#[test]
2278fn unselected_projection_chalk_fold() {
2279 check_types(
2280 r#"
2281trait Interner {}
2282trait Fold<I: Interner, TI = I> {
2283 type Result;
2284}
2285
2286struct Ty<I: Interner> {}
2287impl<I: Interner, TI: Interner> Fold<I, TI> for Ty<I> {
2288 type Result = Ty<TI>;
2289}
2290
2291fn fold<I: Interner, T>(interner: &I, t: T) -> T::Result
2292where
2293 T: Fold<I, I>,
2294{
2295 loop {}
2296}
2297
2298fn foo<I: Interner>(interner: &I, t: Ty<I>) {
2299 fold(interner, t);
2300} //^^^^^^^^^^^^^^^^^ Ty<I>
2301"#,
2302 );
2303}
2304
2305#[test]
2306fn trait_impl_self_ty() {
2307 check_types(
2308 r#"
2309trait Trait<T> {
2310 fn foo(&self);
2311}
2312
2313struct S;
2314
2315impl Trait<Self> for S {}
2316
2317fn test() {
2318 S.foo();
2319} //^^^^^^^ ()
2320"#,
2321 );
2322}
2323
2324#[test]
2325fn trait_impl_self_ty_cycle() {
2326 check_types(
2327 r#"
2328trait Trait {
2329 fn foo(&self);
2330}
2331
2332struct S<T>;
2333
2334impl Trait for S<Self> {}
2335
2336fn test() {
2337 S.foo();
2338} //^^^^^^^ {unknown}
2339"#,
2340 );
2341}
2342
2343#[test]
2344fn unselected_projection_in_trait_env_cycle_1() {
2345 // This is not a cycle, because the `T: Trait2<T::Item>` bound depends only on the `T: Trait`
2346 // bound, not on itself (since only `Trait` can define `Item`).
2347 check_types(
2348 r#"
2349trait Trait {
2350 type Item;
2351}
2352
2353trait Trait2<T> {}
2354
2355fn test<T: Trait>() where T: Trait2<T::Item> {
2356 let x: T::Item = no_matter;
2357} //^^^^^^^^^ Trait::Item<T>
2358"#,
2359 );
2360}
2361
2362#[test]
2363fn unselected_projection_in_trait_env_cycle_2() {
2364 // this is a legitimate cycle
2365 check_types(
2366 r#"
2367//- /main.rs
2368trait Trait<T> {
2369 type Item;
2370}
2371
2372fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
2373 let x: T::Item = no_matter;
2374} //^^^^^^^^^ {unknown}
2375"#,
2376 );
2377}
2378
2379#[test]
2380fn unselected_projection_in_trait_env_cycle_3() {
2381 // this is a cycle for rustc; we currently accept it
2382 check_types(
2383 r#"
2384//- /main.rs
2385trait Trait {
2386 type Item;
2387 type OtherItem;
2388}
2389
2390fn test<T>() where T: Trait<OtherItem = T::Item> {
2391 let x: T::Item = no_matter;
2392} //^^^^^^^^^ Trait::Item<T>
2393"#,
2394 );
2395}
2396
2397#[test]
2398fn unselected_projection_in_trait_env_no_cycle() {
2399 // this is not a cycle
2400 check_types(
2401 r#"
2402//- /main.rs
2403trait Index {
2404 type Output;
2405}
2406
2407type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
2408
2409pub trait UnificationStoreBase: Index<Output = Key<Self>> {
2410 type Key;
2411
2412 fn len(&self) -> usize;
2413}
2414
2415pub trait UnificationStoreMut: UnificationStoreBase {
2416 fn push(&mut self, value: Self::Key);
2417}
2418
2419fn test<T>(t: T) where T: UnificationStoreMut {
2420 let x;
2421 t.push(x);
2422 let y: Key<T>;
2423 (x, y);
2424} //^^^^^^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
2425"#,
2426 );
2427}
2428
2429#[test]
2430fn inline_assoc_type_bounds_1() {
2431 check_types(
2432 r#"
2433trait Iterator {
2434 type Item;
2435}
2436trait OtherTrait<T> {
2437 fn foo(&self) -> T;
2438}
2439
2440// workaround for Chalk assoc type normalization problems
2441pub struct S<T>;
2442impl<T: Iterator> Iterator for S<T> {
2443 type Item = <T as Iterator>::Item;
2444}
2445
2446fn test<I: Iterator<Item: OtherTrait<u32>>>() {
2447 let x: <S<I> as Iterator>::Item;
2448 x.foo();
2449} //^^^^^^^ u32
2450"#,
2451 );
2452}
2453
2454#[test]
2455fn inline_assoc_type_bounds_2() {
2456 check_types(
2457 r#"
2458trait Iterator {
2459 type Item;
2460}
2461
2462fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
2463 let x: <<I as Iterator>::Item as Iterator>::Item;
2464 x;
2465} //^ u32
2466"#,
2467 );
2468}
2469
2470#[test]
2471fn proc_macro_server_types() {
2472 check_infer(
2473 r#"
2474macro_rules! with_api {
2475 ($S:ident, $self:ident, $m:ident) => {
2476 $m! {
2477 TokenStream {
2478 fn new() -> $S::TokenStream;
2479 },
2480 Group {
2481 },
2482 }
2483 };
2484}
2485macro_rules! associated_item {
2486 (type TokenStream) =>
2487 (type TokenStream: 'static;);
2488 (type Group) =>
2489 (type Group: 'static;);
2490 ($($item:tt)*) => ($($item)*;)
2491}
2492macro_rules! declare_server_traits {
2493 ($($name:ident {
2494 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
2495 }),* $(,)?) => {
2496 pub trait Types {
2497 $(associated_item!(type $name);)*
2498 }
2499
2500 $(pub trait $name: Types {
2501 $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2502 })*
2503
2504 pub trait Server: Types $(+ $name)* {}
2505 impl<S: Types $(+ $name)*> Server for S {}
2506 }
2507}
2508
2509with_api!(Self, self_, declare_server_traits);
2510struct G {}
2511struct T {}
2512struct RustAnalyzer;
2513impl Types for RustAnalyzer {
2514 type TokenStream = T;
2515 type Group = G;
2516}
2517
2518fn make<T>() -> T { loop {} }
2519impl TokenStream for RustAnalyzer {
2520 fn new() -> Self::TokenStream {
2521 let group: Self::Group = make();
2522 make()
2523 }
2524}"#,
2525 expect![[r#"
2526 1075..1086 '{ loop {} }': T
2527 1077..1084 'loop {}': !
2528 1082..1084 '{}': ()
2529 1157..1220 '{ ... }': T
2530 1171..1176 'group': G
2531 1192..1196 'make': fn make<G>() -> G
2532 1192..1198 'make()': G
2533 1208..1212 'make': fn make<T>() -> T
2534 1208..1214 'make()': T
2535 "#]],
2536 );
2537}
2538
2539#[test]
2540fn unify_impl_trait() {
2541 check_infer_with_mismatches(
2542 r#"
2543//- minicore: sized
2544trait Trait<T> {}
2545
2546fn foo(x: impl Trait<u32>) { loop {} }
2547fn bar<T>(x: impl Trait<T>) -> T { loop {} }
2548
2549struct S<T>(T);
2550impl<T> Trait<T> for S<T> {}
2551
2552fn default<T>() -> T { loop {} }
2553
2554fn test() -> impl Trait<i32> {
2555 let s1 = S(default());
2556 foo(s1);
2557 let x: i32 = bar(S(default()));
2558 S(default())
2559}"#,
2560 expect![[r#"
2561 26..27 'x': impl Trait<u32>
2562 46..57 '{ loop {} }': ()
2563 48..55 'loop {}': !
2564 53..55 '{}': ()
2565 68..69 'x': impl Trait<T>
2566 91..102 '{ loop {} }': T
2567 93..100 'loop {}': !
2568 98..100 '{}': ()
2569 171..182 '{ loop {} }': T
2570 173..180 'loop {}': !
2571 178..180 '{}': ()
2572 213..309 '{ ...t()) }': S<i32>
2573 223..225 's1': S<u32>
2574 228..229 'S': S<u32>(u32) -> S<u32>
2575 228..240 'S(default())': S<u32>
2576 230..237 'default': fn default<u32>() -> u32
2577 230..239 'default()': u32
2578 246..249 'foo': fn foo(S<u32>)
2579 246..253 'foo(s1)': ()
2580 250..252 's1': S<u32>
2581 263..264 'x': i32
2582 272..275 'bar': fn bar<i32>(S<i32>) -> i32
2583 272..289 'bar(S(...lt()))': i32
2584 276..277 'S': S<i32>(i32) -> S<i32>
2585 276..288 'S(default())': S<i32>
2586 278..285 'default': fn default<i32>() -> i32
2587 278..287 'default()': i32
2588 295..296 'S': S<i32>(i32) -> S<i32>
2589 295..307 'S(default())': S<i32>
2590 297..304 'default': fn default<i32>() -> i32
2591 297..306 'default()': i32
2592 "#]],
2593 );
2594}
2595
2596#[test]
2597fn assoc_types_from_bounds() {
2598 check_infer(
2599 r#"
2600//- minicore: fn
2601trait T {
2602 type O;
2603}
2604
2605impl T for () {
2606 type O = ();
2607}
2608
2609fn f<X, F>(_v: F)
2610where
2611 X: T,
2612 F: FnOnce(&X::O),
2613{ }
2614
2615fn main() {
2616 f::<(), _>(|z| { z; });
2617}"#,
2618 expect![[r#"
2619 72..74 '_v': F
2620 117..120 '{ }': ()
2621 132..163 '{ ... }); }': ()
2622 138..148 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ())
2623 138..160 'f::<()... z; })': ()
2624 149..159 '|z| { z; }': |&()| -> ()
2625 150..151 'z': &()
2626 153..159 '{ z; }': ()
2627 155..156 'z': &()
2628 "#]],
2629 );
2630}
2631
2632#[test]
2633fn associated_type_bound() {
2634 check_types(
2635 r#"
2636pub trait Trait {
2637 type Item: OtherTrait<u32>;
2638}
2639pub trait OtherTrait<T> {
2640 fn foo(&self) -> T;
2641}
2642
2643// this is just a workaround for chalk#234
2644pub struct S<T>;
2645impl<T: Trait> Trait for S<T> {
2646 type Item = <T as Trait>::Item;
2647}
2648
2649fn test<T: Trait>() {
2650 let y: <S<T> as Trait>::Item = no_matter;
2651 y.foo();
2652} //^^^^^^^ u32
2653"#,
2654 );
2655}
2656
2657#[test]
2658fn dyn_trait_through_chalk() {
2659 check_types(
2660 r#"
2661//- minicore: deref
2662struct Box<T: ?Sized> {}
2663impl<T: ?Sized> core::ops::Deref for Box<T> {
2664 type Target = T;
2665}
2666trait Trait {
2667 fn foo(&self);
2668}
2669
2670fn test(x: Box<dyn Trait>) {
2671 x.foo();
2672} //^^^^^^^ ()
2673"#,
2674 );
2675}
2676
2677#[test]
2678fn string_to_owned() {
2679 check_types(
2680 r#"
2681struct String {}
2682pub trait ToOwned {
2683 type Owned;
2684 fn to_owned(&self) -> Self::Owned;
2685}
2686impl ToOwned for str {
2687 type Owned = String;
2688}
2689fn test() {
2690 "foo".to_owned();
2691} //^^^^^^^^^^^^^^^^ String
2692"#,
2693 );
2694}
2695
2696#[test]
2697fn iterator_chain() {
2698 check_infer_with_mismatches(
2699 r#"
2700//- minicore: fn, option
2701pub trait Iterator {
2702 type Item;
2703
2704 fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
2705 where
2706 F: FnMut(Self::Item) -> Option<B>,
2707 { loop {} }
2708
2709 fn for_each<F>(self, f: F)
2710 where
2711 F: FnMut(Self::Item),
2712 { loop {} }
2713}
2714
2715pub trait IntoIterator {
2716 type Item;
2717 type IntoIter: Iterator<Item = Self::Item>;
2718 fn into_iter(self) -> Self::IntoIter;
2719}
2720
2721pub struct FilterMap<I, F> { }
2722impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
2723where
2724 F: FnMut(I::Item) -> Option<B>,
2725{
2726 type Item = B;
2727}
2728
2729#[stable(feature = "rust1", since = "1.0.0")]
2730impl<I: Iterator> IntoIterator for I {
2731 type Item = I::Item;
2732 type IntoIter = I;
2733
2734 fn into_iter(self) -> I {
2735 self
2736 }
2737}
2738
2739struct Vec<T> {}
2740impl<T> Vec<T> {
2741 fn new() -> Self { loop {} }
2742}
2743
2744impl<T> IntoIterator for Vec<T> {
2745 type Item = T;
2746 type IntoIter = IntoIter<T>;
2747}
2748
2749pub struct IntoIter<T> { }
2750impl<T> Iterator for IntoIter<T> {
2751 type Item = T;
2752}
2753
2754fn main() {
2755 Vec::<i32>::new().into_iter()
2756 .filter_map(|x| if x > 0 { Some(x as u32) } else { None })
2757 .for_each(|y| { y; });
2758}"#,
2759 expect![[r#"
2760 61..65 'self': Self
2761 67..68 'f': F
2762 152..163 '{ loop {} }': FilterMap<Self, F>
2763 154..161 'loop {}': !
2764 159..161 '{}': ()
2765 184..188 'self': Self
2766 190..191 'f': F
2767 240..251 '{ loop {} }': ()
2768 242..249 'loop {}': !
2769 247..249 '{}': ()
2770 360..364 'self': Self
2771 689..693 'self': I
2772 700..720 '{ ... }': I
2773 710..714 'self': I
2774 779..790 '{ loop {} }': Vec<T>
2775 781..788 'loop {}': !
2776 786..788 '{}': ()
2777 977..1104 '{ ... }); }': ()
2778 983..998 'Vec::<i32>::new': fn new<i32>() -> Vec<i32>
2779 983..1000 'Vec::<...:new()': Vec<i32>
2780 983..1012 'Vec::<...iter()': IntoIter<i32>
2781 983..1075 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>>
2782 983..1101 'Vec::<... y; })': ()
2783 1029..1074 '|x| if...None }': |i32| -> Option<u32>
2784 1030..1031 'x': i32
2785 1033..1074 'if x >...None }': Option<u32>
2786 1036..1037 'x': i32
2787 1036..1041 'x > 0': bool
2788 1040..1041 '0': i32
2789 1042..1060 '{ Some...u32) }': Option<u32>
2790 1044..1048 'Some': Some<u32>(u32) -> Option<u32>
2791 1044..1058 'Some(x as u32)': Option<u32>
2792 1049..1050 'x': i32
2793 1049..1057 'x as u32': u32
2794 1066..1074 '{ None }': Option<u32>
2795 1068..1072 'None': Option<u32>
2796 1090..1100 '|y| { y; }': |u32| -> ()
2797 1091..1092 'y': u32
2798 1094..1100 '{ y; }': ()
2799 1096..1097 'y': u32
2800 "#]],
2801 );
2802}
2803
2804#[test]
2805fn nested_assoc() {
2806 check_types(
2807 r#"
2808struct Bar;
2809struct Foo;
2810
2811trait A {
2812 type OutputA;
2813}
2814
2815impl A for Bar {
2816 type OutputA = Foo;
2817}
2818
2819trait B {
2820 type Output;
2821 fn foo() -> Self::Output;
2822}
2823
2824impl<T:A> B for T {
2825 type Output = T::OutputA;
2826 fn foo() -> Self::Output { loop {} }
2827}
2828
2829fn main() {
2830 Bar::foo();
2831} //^^^^^^^^^^ Foo
2832"#,
2833 );
2834}
2835
2836#[test]
2837fn trait_object_no_coercion() {
2838 check_infer_with_mismatches(
2839 r#"
2840trait Foo {}
2841
2842fn foo(x: &dyn Foo) {}
2843
2844fn test(x: &dyn Foo) {
2845 foo(x);
2846}"#,
2847 expect![[r#"
2848 21..22 'x': &dyn Foo
2849 34..36 '{}': ()
2850 46..47 'x': &dyn Foo
2851 59..74 '{ foo(x); }': ()
2852 65..68 'foo': fn foo(&dyn Foo)
2853 65..71 'foo(x)': ()
2854 69..70 'x': &dyn Foo
2855 "#]],
2856 );
2857}
2858
2859#[test]
2860fn builtin_copy() {
2861 check_infer_with_mismatches(
2862 r#"
2863//- minicore: copy
2864struct IsCopy;
2865impl Copy for IsCopy {}
2866struct NotCopy;
2867
2868trait Test { fn test(&self) -> bool; }
2869impl<T: Copy> Test for T {}
2870
2871fn test() {
2872 IsCopy.test();
2873 NotCopy.test();
2874 (IsCopy, IsCopy).test();
2875 (IsCopy, NotCopy).test();
2876}"#,
2877 expect![[r#"
2878 78..82 'self': &Self
2879 134..235 '{ ...t(); }': ()
2880 140..146 'IsCopy': IsCopy
2881 140..153 'IsCopy.test()': bool
2882 159..166 'NotCopy': NotCopy
2883 159..173 'NotCopy.test()': {unknown}
2884 179..195 '(IsCop...sCopy)': (IsCopy, IsCopy)
2885 179..202 '(IsCop...test()': bool
2886 180..186 'IsCopy': IsCopy
2887 188..194 'IsCopy': IsCopy
2888 208..225 '(IsCop...tCopy)': (IsCopy, NotCopy)
2889 208..232 '(IsCop...test()': {unknown}
2890 209..215 'IsCopy': IsCopy
2891 217..224 'NotCopy': NotCopy
2892 "#]],
2893 );
2894}
2895
2896#[test]
2897fn builtin_fn_def_copy() {
2898 check_infer_with_mismatches(
2899 r#"
2900//- minicore: copy
2901fn foo() {}
2902fn bar<T: Copy>(T) -> T {}
2903struct Struct(usize);
2904enum Enum { Variant(usize) }
2905
2906trait Test { fn test(&self) -> bool; }
2907impl<T: Copy> Test for T {}
2908
2909fn test() {
2910 foo.test();
2911 bar.test();
2912 Struct.test();
2913 Enum::Variant.test();
2914}"#,
2915 expect![[r#"
2916 9..11 '{}': ()
2917 28..29 'T': {unknown}
2918 36..38 '{}': T
2919 36..38: expected T, got ()
2920 113..117 'self': &Self
2921 169..249 '{ ...t(); }': ()
2922 175..178 'foo': fn foo()
2923 175..185 'foo.test()': bool
2924 191..194 'bar': fn bar<{unknown}>({unknown}) -> {unknown}
2925 191..201 'bar.test()': bool
2926 207..213 'Struct': Struct(usize) -> Struct
2927 207..220 'Struct.test()': bool
2928 226..239 'Enum::Variant': Variant(usize) -> Enum
2929 226..246 'Enum::...test()': bool
2930 "#]],
2931 );
2932}
2933
2934#[test]
2935fn builtin_fn_ptr_copy() {
2936 check_infer_with_mismatches(
2937 r#"
2938//- minicore: copy
2939trait Test { fn test(&self) -> bool; }
2940impl<T: Copy> Test for T {}
2941
2942fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) {
2943 f1.test();
2944 f2.test();
2945 f3.test();
2946}"#,
2947 expect![[r#"
2948 22..26 'self': &Self
2949 76..78 'f1': fn()
2950 86..88 'f2': fn(usize) -> u8
2951 107..109 'f3': fn(u8, u8) -> &u8
2952 130..178 '{ ...t(); }': ()
2953 136..138 'f1': fn()
2954 136..145 'f1.test()': bool
2955 151..153 'f2': fn(usize) -> u8
2956 151..160 'f2.test()': bool
2957 166..168 'f3': fn(u8, u8) -> &u8
2958 166..175 'f3.test()': bool
2959 "#]],
2960 );
2961}
2962
2963#[test]
2964fn builtin_sized() {
2965 check_infer_with_mismatches(
2966 r#"
2967//- minicore: sized
2968trait Test { fn test(&self) -> bool; }
2969impl<T: Sized> Test for T {}
2970
2971fn test() {
2972 1u8.test();
2973 (*"foo").test(); // not Sized
2974 (1u8, 1u8).test();
2975 (1u8, *"foo").test(); // not Sized
2976}"#,
2977 expect![[r#"
2978 22..26 'self': &Self
2979 79..194 '{ ...ized }': ()
2980 85..88 '1u8': u8
2981 85..95 '1u8.test()': bool
2982 101..116 '(*"foo").test()': {unknown}
2983 102..108 '*"foo"': str
2984 103..108 '"foo"': &str
2985 135..145 '(1u8, 1u8)': (u8, u8)
2986 135..152 '(1u8, ...test()': bool
2987 136..139 '1u8': u8
2988 141..144 '1u8': u8
2989 158..171 '(1u8, *"foo")': (u8, str)
2990 158..178 '(1u8, ...test()': {unknown}
2991 159..162 '1u8': u8
2992 164..170 '*"foo"': str
2993 165..170 '"foo"': &str
2994 "#]],
2995 );
2996}
2997
2998#[test]
2999fn integer_range_iterate() {
3000 check_types(
3001 r#"
3002//- /main.rs crate:main deps:core
3003fn test() {
3004 for x in 0..100 { x; }
3005} //^ i32
3006
3007//- /core.rs crate:core
3008pub mod ops {
3009 pub struct Range<Idx> {
3010 pub start: Idx,
3011 pub end: Idx,
3012 }
3013}
3014
3015pub mod iter {
3016 pub trait Iterator {
3017 type Item;
3018 }
3019
3020 pub trait IntoIterator {
3021 type Item;
3022 type IntoIter: Iterator<Item = Self::Item>;
3023 }
3024
3025 impl<T> IntoIterator for T where T: Iterator {
3026 type Item = <T as Iterator>::Item;
3027 type IntoIter = Self;
3028 }
3029}
3030
3031trait Step {}
3032impl Step for i32 {}
3033impl Step for i64 {}
3034
3035impl<A: Step> iter::Iterator for ops::Range<A> {
3036 type Item = A;
3037}
3038"#,
3039 );
3040}
3041
3042#[test]
3043fn infer_closure_arg() {
3044 check_infer(
3045 r#"
3046//- /lib.rs
3047
3048enum Option<T> {
3049 None,
3050 Some(T)
3051}
3052
3053fn foo() {
3054 let s = Option::None;
3055 let f = |x: Option<i32>| {};
3056 (&f)(s)
3057}"#,
3058 expect![[r#"
3059 52..126 '{ ...)(s) }': ()
3060 62..63 's': Option<i32>
3061 66..78 'Option::None': Option<i32>
3062 88..89 'f': |Option<i32>| -> ()
3063 92..111 '|x: Op...2>| {}': |Option<i32>| -> ()
3064 93..94 'x': Option<i32>
3065 109..111 '{}': ()
3066 117..124 '(&f)(s)': ()
3067 118..120 '&f': &|Option<i32>| -> ()
3068 119..120 'f': |Option<i32>| -> ()
3069 122..123 's': Option<i32>
3070 "#]],
3071 );
3072}
3073
3074#[test]
3075fn dyn_fn_param_informs_call_site_closure_signature() {
3076 cov_mark::check!(dyn_fn_param_informs_call_site_closure_signature);
3077 check_types(
3078 r#"
3079//- minicore: fn, coerce_unsized
3080struct S;
3081impl S {
3082 fn inherent(&self) -> u8 { 0 }
3083}
3084fn take_dyn_fn(f: &dyn Fn(S)) {}
3085
3086fn f() {
3087 take_dyn_fn(&|x| { x.inherent(); });
3088 //^^^^^^^^^^^^ u8
3089}
3090 "#,
3091 );
3092}
3093
3094#[test]
3095fn infer_fn_trait_arg() {
3096 check_infer_with_mismatches(
3097 r#"
3098//- minicore: fn, option
3099fn foo<F, T>(f: F) -> T
3100where
3101 F: Fn(Option<i32>) -> T,
3102{
3103 let s = None;
3104 f(s)
3105}
3106"#,
3107 expect![[r#"
3108 13..14 'f': F
3109 59..89 '{ ...f(s) }': T
3110 69..70 's': Option<i32>
3111 73..77 'None': Option<i32>
3112 83..84 'f': F
3113 83..87 'f(s)': T
3114 85..86 's': Option<i32>
3115 "#]],
3116 );
3117}
3118
3119#[test]
3120fn infer_box_fn_arg() {
3121 // The type mismatch is because we don't define Unsize and CoerceUnsized
3122 check_infer_with_mismatches(
3123 r#"
3124//- minicore: fn, deref, option
3125#[lang = "owned_box"]
3126pub struct Box<T: ?Sized> {
3127 inner: *mut T,
3128}
3129
3130impl<T: ?Sized> core::ops::Deref for Box<T> {
3131 type Target = T;
3132
3133 fn deref(&self) -> &T {
3134 &self.inner
3135 }
3136}
3137
3138fn foo() {
3139 let s = None;
3140 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3141 f(&s);
3142}"#,
3143 expect![[r#"
3144 154..158 'self': &Box<T>
3145 166..193 '{ ... }': &T
3146 176..187 '&self.inner': &*mut T
3147 177..181 'self': &Box<T>
3148 177..187 'self.inner': *mut T
3149 206..296 '{ ...&s); }': ()
3150 216..217 's': Option<i32>
3151 220..224 'None': Option<i32>
3152 234..235 'f': Box<dyn FnOnce(&Option<i32>)>
3153 269..282 'box (|ps| {})': Box<|&Option<i32>| -> ()>
3154 274..281 '|ps| {}': |&Option<i32>| -> ()
3155 275..277 'ps': &Option<i32>
3156 279..281 '{}': ()
3157 288..289 'f': Box<dyn FnOnce(&Option<i32>)>
3158 288..293 'f(&s)': ()
3159 290..292 '&s': &Option<i32>
3160 291..292 's': Option<i32>
3161 269..282: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|&Option<i32>| -> ()>
3162 "#]],
3163 );
3164}
3165
3166#[test]
3167fn infer_dyn_fn_output() {
3168 check_types(
3169 r#"
3170//- minicore: fn
3171fn foo() {
3172 let f: &dyn Fn() -> i32;
3173 f();
3174 //^^^ i32
3175}"#,
3176 );
3177}
3178
3179#[test]
3180fn infer_dyn_fn_once_output() {
3181 check_types(
3182 r#"
3183//- minicore: fn
3184fn foo() {
3185 let f: dyn FnOnce() -> i32;
3186 f();
3187 //^^^ i32
3188}"#,
3189 );
3190}
3191
3192#[test]
3193fn variable_kinds_1() {
3194 check_types(
3195 r#"
3196trait Trait<T> { fn get(self, t: T) -> T; }
3197struct S;
3198impl Trait<u128> for S {}
3199impl Trait<f32> for S {}
3200fn test() {
3201 S.get(1);
3202 //^^^^^^^^ u128
3203 S.get(1.);
3204 //^^^^^^^^^ f32
3205}
3206 "#,
3207 );
3208}
3209
3210#[test]
3211fn variable_kinds_2() {
3212 check_types(
3213 r#"
3214trait Trait { fn get(self) -> Self; }
3215impl Trait for u128 {}
3216impl Trait for f32 {}
3217fn test() {
3218 1.get();
3219 //^^^^^^^ u128
3220 (1.).get();
3221 //^^^^^^^^^^ f32
3222}
3223 "#,
3224 );
3225}
3226
3227#[test]
3228fn underscore_import() {
3229 check_types(
3230 r#"
3231mod tr {
3232 pub trait Tr {
3233 fn method(&self) -> u8 { 0 }
3234 }
3235}
3236
3237struct Tr;
3238impl crate::tr::Tr for Tr {}
3239
3240use crate::tr::Tr as _;
3241fn test() {
3242 Tr.method();
3243 //^^^^^^^^^^^ u8
3244}
3245 "#,
3246 );
3247}
3248
3249#[test]
3250fn inner_use() {
3251 check_types(
3252 r#"
3253mod m {
3254 pub trait Tr {
3255 fn method(&self) -> u8 { 0 }
3256 }
3257
3258 impl Tr for () {}
3259}
3260
3261fn f() {
3262 use m::Tr;
3263
3264 ().method();
3265 //^^^^^^^^^^^ u8
3266}
3267 "#,
3268 );
3269}
3270
3271#[test]
3272fn trait_in_scope_with_inner_item() {
3273 check_infer(
3274 r#"
3275mod m {
3276 pub trait Tr {
3277 fn method(&self) -> u8 { 0 }
3278 }
3279
3280 impl Tr for () {}
3281}
3282
3283use m::Tr;
3284
3285fn f() {
3286 fn inner() {
3287 ().method();
3288 //^^^^^^^^^^^ u8
3289 }
3290}"#,
3291 expect![[r#"
3292 46..50 'self': &Self
3293 58..63 '{ 0 }': u8
3294 60..61 '0': u8
3295 115..185 '{ ... } }': ()
3296 132..183 '{ ... }': ()
3297 142..144 '()': ()
3298 142..153 '().method()': u8
3299 "#]],
3300 );
3301}
3302
3303#[test]
3304fn inner_use_in_block() {
3305 check_types(
3306 r#"
3307mod m {
3308 pub trait Tr {
3309 fn method(&self) -> u8 { 0 }
3310 }
3311
3312 impl Tr for () {}
3313}
3314
3315fn f() {
3316 {
3317 use m::Tr;
3318
3319 ().method();
3320 //^^^^^^^^^^^ u8
3321 }
3322
3323 {
3324 ().method();
3325 //^^^^^^^^^^^ {unknown}
3326 }
3327
3328 ().method();
3329 //^^^^^^^^^^^ {unknown}
3330}
3331 "#,
3332 );
3333}
3334
3335#[test]
3336fn nested_inner_function_calling_self() {
3337 check_infer(
3338 r#"
3339struct S;
3340fn f() {
3341 fn inner() -> S {
3342 let s = inner();
3343 }
3344}"#,
3345 expect![[r#"
3346 17..73 '{ ... } }': ()
3347 39..71 '{ ... }': S
3348 53..54 's': S
3349 57..62 'inner': fn inner() -> S
3350 57..64 'inner()': S
3351 "#]],
3352 )
3353}
3354
3355#[test]
3356fn infer_default_trait_type_parameter() {
3357 check_infer(
3358 r#"
3359struct A;
3360
3361trait Op<RHS=Self> {
3362 type Output;
3363
3364 fn do_op(self, rhs: RHS) -> Self::Output;
3365}
3366
3367impl Op for A {
3368 type Output = bool;
3369
3370 fn do_op(self, rhs: Self) -> Self::Output {
3371 true
3372 }
3373}
3374
3375fn test() {
3376 let x = A;
3377 let y = A;
3378 let r = x.do_op(y);
3379}"#,
3380 expect![[r#"
3381 63..67 'self': Self
3382 69..72 'rhs': RHS
3383 153..157 'self': A
3384 159..162 'rhs': A
3385 186..206 '{ ... }': bool
3386 196..200 'true': bool
3387 220..277 '{ ...(y); }': ()
3388 230..231 'x': A
3389 234..235 'A': A
3390 245..246 'y': A
3391 249..250 'A': A
3392 260..261 'r': bool
3393 264..265 'x': A
3394 264..274 'x.do_op(y)': bool
3395 272..273 'y': A
3396 "#]],
3397 )
3398}
3399
3400#[test]
3401fn qualified_path_as_qualified_trait() {
3402 check_infer(
3403 r#"
3404mod foo {
3405
3406 pub trait Foo {
3407 type Target;
3408 }
3409 pub trait Bar {
3410 type Output;
3411 fn boo() -> Self::Output {
3412 loop {}
3413 }
3414 }
3415}
3416
3417struct F;
3418impl foo::Foo for F {
3419 type Target = ();
3420}
3421impl foo::Bar for F {
3422 type Output = <F as foo::Foo>::Target;
3423}
3424
3425fn foo() {
3426 use foo::Bar;
3427 let x = <F as Bar>::boo();
3428}"#,
3429 expect![[r#"
3430 132..163 '{ ... }': Bar::Output<Self>
3431 146..153 'loop {}': !
3432 151..153 '{}': ()
3433 306..358 '{ ...o(); }': ()
3434 334..335 'x': ()
3435 338..353 '<F as Bar>::boo': fn boo<F>() -> <F as Bar>::Output
3436 338..355 '<F as ...:boo()': ()
3437 "#]],
3438 );
3439}
3440
3441#[test]
3442fn renamed_extern_crate_in_block() {
3443 check_types(
3444 r#"
3445//- /lib.rs crate:lib deps:serde
3446use serde::Deserialize;
3447
3448struct Foo {}
3449
3450const _ : () = {
3451 extern crate serde as _serde;
3452 impl _serde::Deserialize for Foo {
3453 fn deserialize() -> u8 { 0 }
3454 }
3455};
3456
3457fn foo() {
3458 Foo::deserialize();
3459 //^^^^^^^^^^^^^^^^^^ u8
3460}
3461
3462//- /serde.rs crate:serde
3463
3464pub trait Deserialize {
3465 fn deserialize() -> u8;
3466}"#,
3467 );
3468}
3469
3470#[test]
3471fn bin_op_with_rhs_is_self_for_assoc_bound() {
3472 check_no_mismatches(
3473 r#"//- minicore: eq
3474 fn repro<T>(t: T) -> bool
3475where
3476 T: Request,
3477 T::Output: Convertable,
3478{
3479 let a = execute(&t).convert();
3480 let b = execute(&t).convert();
3481 a.eq(&b);
3482 let a = execute(&t).convert2();
3483 let b = execute(&t).convert2();
3484 a.eq(&b)
3485}
3486fn execute<T>(t: &T) -> T::Output
3487where
3488 T: Request,
3489{
3490 <T as Request>::output()
3491}
3492trait Convertable {
3493 type TraitSelf: PartialEq<Self::TraitSelf>;
3494 type AssocAsDefaultSelf: PartialEq;
3495 fn convert(self) -> Self::AssocAsDefaultSelf;
3496 fn convert2(self) -> Self::TraitSelf;
3497}
3498trait Request {
3499 type Output;
3500 fn output() -> Self::Output;
3501}
3502 "#,
3503 );
3504}
3505
3506#[test]
3507fn bin_op_adt_with_rhs_primitive() {
3508 check_infer_with_mismatches(
3509 r#"
3510#[lang = "add"]
3511pub trait Add<Rhs = Self> {
3512 type Output;
3513 fn add(self, rhs: Rhs) -> Self::Output;
3514}
3515
3516struct Wrapper(u32);
3517impl Add<u32> for Wrapper {
3518 type Output = Self;
3519 fn add(self, rhs: u32) -> Wrapper {
3520 Wrapper(rhs)
3521 }
3522}
3523fn main(){
3524 let wrapped = Wrapper(10);
3525 let num: u32 = 2;
3526 let res = wrapped + num;
3527
3528}"#,
3529 expect![[r#"
3530 72..76 'self': Self
3531 78..81 'rhs': Rhs
3532 192..196 'self': Wrapper
3533 198..201 'rhs': u32
3534 219..247 '{ ... }': Wrapper
3535 229..236 'Wrapper': Wrapper(u32) -> Wrapper
3536 229..241 'Wrapper(rhs)': Wrapper
3537 237..240 'rhs': u32
3538 259..345 '{ ...um; }': ()
3539 269..276 'wrapped': Wrapper
3540 279..286 'Wrapper': Wrapper(u32) -> Wrapper
3541 279..290 'Wrapper(10)': Wrapper
3542 287..289 '10': u32
3543 300..303 'num': u32
3544 311..312 '2': u32
3545 322..325 'res': Wrapper
3546 328..335 'wrapped': Wrapper
3547 328..341 'wrapped + num': Wrapper
3548 338..341 'num': u32
3549 "#]],
3550 )
3551}
3552
3553#[test]
3554fn array_length() {
3555 check_infer(
3556 r#"
3557trait T {
3558 type Output;
3559 fn do_thing(&self) -> Self::Output;
3560}
3561
3562impl T for [u8; 4] {
3563 type Output = usize;
3564 fn do_thing(&self) -> Self::Output {
3565 2
3566 }
3567}
3568
3569impl T for [u8; 2] {
3570 type Output = u8;
3571 fn do_thing(&self) -> Self::Output {
3572 2
3573 }
3574}
3575
3576fn main() {
3577 let v = [0u8; 2];
3578 let v2 = v.do_thing();
3579 let v3 = [0u8; 4];
3580 let v4 = v3.do_thing();
3581}
3582"#,
3583 expect![[r#"
3584 44..48 'self': &Self
3585 133..137 'self': &[u8; 4]
3586 155..172 '{ ... }': usize
3587 165..166 '2': usize
3588 236..240 'self': &[u8; 2]
3589 258..275 '{ ... }': u8
3590 268..269 '2': u8
3591 289..392 '{ ...g(); }': ()
3592 299..300 'v': [u8; 2]
3593 303..311 '[0u8; 2]': [u8; 2]
3594 304..307 '0u8': u8
3595 309..310 '2': usize
3596 321..323 'v2': u8
3597 326..327 'v': [u8; 2]
3598 326..338 'v.do_thing()': u8
3599 348..350 'v3': [u8; 4]
3600 353..361 '[0u8; 4]': [u8; 4]
3601 354..357 '0u8': u8
3602 359..360 '4': usize
3603 371..373 'v4': usize
3604 376..378 'v3': [u8; 4]
3605 376..389 'v3.do_thing()': usize
3606 "#]],
3607 )
3608}
3609
3610#[test]
3611fn const_generics() {
3612 check_infer(
3613 r#"
3614trait T {
3615 type Output;
3616 fn do_thing(&self) -> Self::Output;
3617}
3618
3619impl<const L: usize> T for [u8; L] {
3620 type Output = [u8; L];
3621 fn do_thing(&self) -> Self::Output {
3622 *self
3623 }
3624}
3625
3626fn main() {
3627 let v = [0u8; 2];
3628 let v2 = v.do_thing();
3629}
3630"#,
3631 expect![[r#"
3632 44..48 'self': &Self
3633 151..155 'self': &[u8; L]
3634 173..194 '{ ... }': [u8; L]
3635 183..188 '*self': [u8; L]
3636 184..188 'self': &[u8; L]
3637 208..260 '{ ...g(); }': ()
3638 218..219 'v': [u8; 2]
3639 222..230 '[0u8; 2]': [u8; 2]
3640 223..226 '0u8': u8
3641 228..229 '2': usize
3642 240..242 'v2': [u8; 2]
3643 245..246 'v': [u8; 2]
3644 245..257 'v.do_thing()': [u8; 2]
3645 "#]],
3646 )
3647}
3648
3649#[test]
3650fn fn_returning_unit() {
3651 check_infer_with_mismatches(
3652 r#"
3653//- minicore: fn
3654fn test<F: FnOnce()>(f: F) {
3655 let _: () = f();
3656}"#,
3657 expect![[r#"
3658 21..22 'f': F
3659 27..51 '{ ...f(); }': ()
3660 37..38 '_': ()
3661 45..46 'f': F
3662 45..48 'f()': ()
3663 "#]],
3664 );
3665}
3666
3667#[test]
3668fn trait_in_scope_of_trait_impl() {
3669 check_infer(
3670 r#"
3671mod foo {
3672 pub trait Foo {
3673 fn foo(self);
3674 fn bar(self) -> usize { 0 }
3675 }
3676}
3677impl foo::Foo for u32 {
3678 fn foo(self) {
3679 let _x = self.bar();
3680 }
3681}
3682 "#,
3683 expect![[r#"
3684 45..49 'self': Self
3685 67..71 'self': Self
3686 82..87 '{ 0 }': usize
3687 84..85 '0': usize
3688 131..135 'self': u32
3689 137..173 '{ ... }': ()
3690 151..153 '_x': usize
3691 156..160 'self': u32
3692 156..166 'self.bar()': usize
3693 "#]],
3694 );
3695}
3696
3697#[test]
3698fn infer_async_ret_type() {
3699 check_types(
3700 r#"
3701//- minicore: future, result
3702struct Fooey;
3703
3704impl Fooey {
3705 fn collect<B: Convert>(self) -> B {
3706 B::new()
3707 }
3708}
3709
3710trait Convert {
3711 fn new() -> Self;
3712}
3713impl Convert for u32 {
3714 fn new() -> Self { 0 }
3715}
3716
3717async fn get_accounts() -> Result<u32, ()> {
3718 let ret = Fooey.collect();
3719 // ^^^^^^^^^^^^^^^ u32
3720 Ok(ret)
3721}
3722"#,
3723 );
3724}
3725
3726#[test]
3727fn local_impl_1() {
3728 check!(block_local_impls);
3729 check_types(
3730 r#"
3731trait Trait<T> {
3732 fn foo(&self) -> T;
3733}
3734
3735fn test() {
3736 struct S;
3737 impl Trait<u32> for S {
3738 fn foo(&self) -> u32 { 0 }
3739 }
3740
3741 S.foo();
3742 // ^^^^^^^ u32
3743}
3744"#,
3745 );
3746}
3747
3748#[test]
3749fn local_impl_2() {
3750 check!(block_local_impls);
3751 check_types(
3752 r#"
3753struct S;
3754
3755fn test() {
3756 trait Trait<T> {
3757 fn foo(&self) -> T;
3758 }
3759 impl Trait<u32> for S {
3760 fn foo(&self) -> u32 { 0 }
3761 }
3762
3763 S.foo();
3764 // ^^^^^^^ u32
3765}
3766"#,
3767 );
3768}
3769
3770#[test]
3771fn local_impl_3() {
3772 check!(block_local_impls);
3773 check_types(
3774 r#"
3775trait Trait<T> {
3776 fn foo(&self) -> T;
3777}
3778
3779fn test() {
3780 struct S1;
3781 {
3782 struct S2;
3783
3784 impl Trait<S1> for S2 {
3785 fn foo(&self) -> S1 { S1 }
3786 }
3787
3788 S2.foo();
3789 // ^^^^^^^^ S1
3790 }
3791}
3792"#,
3793 );
3794}
3795
3796#[test]
3797fn associated_type_sized_bounds() {
3798 check_infer(
3799 r#"
3800//- minicore: sized
3801struct Yes;
3802trait IsSized { const IS_SIZED: Yes; }
3803impl<T: Sized> IsSized for T { const IS_SIZED: Yes = Yes; }
3804
3805trait Foo {
3806 type Explicit: Sized;
3807 type Implicit;
3808 type Relaxed: ?Sized;
3809}
3810fn f<F: Foo>() {
3811 F::Explicit::IS_SIZED;
3812 F::Implicit::IS_SIZED;
3813 F::Relaxed::IS_SIZED;
3814}
3815"#,
3816 expect![[r#"
3817 104..107 'Yes': Yes
3818 212..295 '{ ...ZED; }': ()
3819 218..239 'F::Exp..._SIZED': Yes
3820 245..266 'F::Imp..._SIZED': Yes
3821 272..292 'F::Rel..._SIZED': {unknown}
3822 "#]],
3823 );
3824}
3825
3826#[test]
3827fn dyn_map() {
3828 check_types(
3829 r#"
3830pub struct Key<K, V, P = (K, V)> {}
3831
3832pub trait Policy {
3833 type K;
3834 type V;
3835}
3836
3837impl<K, V> Policy for (K, V) {
3838 type K = K;
3839 type V = V;
3840}
3841
3842pub struct KeyMap<KEY> {}
3843
3844impl<P: Policy> KeyMap<Key<P::K, P::V, P>> {
3845 pub fn get(&self, key: &P::K) -> P::V {
3846 loop {}
3847 }
3848}
3849
3850struct Fn {}
3851struct FunctionId {}
3852
3853fn test() {
3854 let key_map: &KeyMap<Key<Fn, FunctionId>> = loop {};
3855 let key;
3856 let result = key_map.get(key);
3857 //^^^^^^ FunctionId
3858}
3859"#,
3860 )
3861}
f2b60f7d
FG
3862
3863#[test]
3864fn dyn_multiple_auto_traits_in_different_order() {
3865 check_no_mismatches(
3866 r#"
3867auto trait Send {}
3868auto trait Sync {}
3869
3870fn f(t: &(dyn Sync + Send)) {}
3871fn g(t: &(dyn Send + Sync)) {
3872 f(t);
3873}
3874 "#,
3875 );
3876
3877 check_no_mismatches(
3878 r#"
3879auto trait Send {}
3880auto trait Sync {}
3881trait T {}
3882
3883fn f(t: &(dyn T + Send + Sync)) {}
3884fn g(t: &(dyn Sync + T + Send)) {
3885 f(t);
3886}
3887 "#,
3888 );
3889
3890 check_infer_with_mismatches(
3891 r#"
3892auto trait Send {}
3893auto trait Sync {}
3894trait T1 {}
3895trait T2 {}
3896
3897fn f(t: &(dyn T1 + T2 + Send + Sync)) {}
3898fn g(t: &(dyn Sync + T2 + T1 + Send)) {
3899 f(t);
3900}
3901 "#,
3902 expect![[r#"
3903 68..69 't': &{unknown}
3904 101..103 '{}': ()
3905 109..110 't': &{unknown}
3906 142..155 '{ f(t); }': ()
3907 148..149 'f': fn f(&{unknown})
3908 148..152 'f(t)': ()
3909 150..151 't': &{unknown}
3910 "#]],
3911 );
3912
3913 check_no_mismatches(
3914 r#"
3915auto trait Send {}
3916auto trait Sync {}
3917trait T {
3918 type Proj: Send + Sync;
3919}
3920
3921fn f(t: &(dyn T<Proj = ()> + Send + Sync)) {}
3922fn g(t: &(dyn Sync + T<Proj = ()> + Send)) {
3923 f(t);
3924}
3925 "#,
3926 );
3927}
3928
3929#[test]
3930fn dyn_multiple_projection_bounds() {
3931 check_no_mismatches(
3932 r#"
3933trait Trait {
3934 type T;
3935 type U;
3936}
3937
3938fn f(t: &dyn Trait<T = (), U = ()>) {}
3939fn g(t: &dyn Trait<U = (), T = ()>) {
3940 f(t);
3941}
3942 "#,
3943 );
3944
3945 check_types(
3946 r#"
3947trait Trait {
3948 type T;
3949}
3950
3951fn f(t: &dyn Trait<T = (), T = ()>) {}
3952 //^&{unknown}
3953 "#,
3954 );
3955}
3956
3957#[test]
3958fn dyn_duplicate_auto_trait() {
3959 check_no_mismatches(
3960 r#"
3961auto trait Send {}
3962
3963fn f(t: &(dyn Send + Send)) {}
3964fn g(t: &(dyn Send)) {
3965 f(t);
3966}
3967 "#,
3968 );
3969
3970 check_no_mismatches(
3971 r#"
3972auto trait Send {}
3973trait T {}
3974
3975fn f(t: &(dyn T + Send + Send)) {}
3976fn g(t: &(dyn T + Send)) {
3977 f(t);
3978}
3979 "#,
3980 );
3981}
487cf647
FG
3982
3983#[test]
3984fn gats_in_path() {
3985 check_types(
3986 r#"
3987//- minicore: deref
3988use core::ops::Deref;
3989trait PointerFamily {
3990 type Pointer<T>: Deref<Target = T>;
3991}
3992
3993fn f<P: PointerFamily>(p: P::Pointer<i32>) {
3994 let a = *p;
3995 //^ i32
3996}
3997fn g<P: PointerFamily>(p: <P as PointerFamily>::Pointer<i32>) {
3998 let a = *p;
3999 //^ i32
4000}
4001 "#,
4002 );
4003}
4004
4005#[test]
4006fn gats_with_impl_trait() {
4007 // FIXME: the last function (`fn i()`) is not valid Rust as of this writing because you cannot
4008 // specify the same associated type multiple times even if their arguments are different (c.f.
4009 // `fn h()`, which is valid). Reconsider how to treat these invalid types.
4010 check_types(
4011 r#"
4012//- minicore: deref
4013use core::ops::Deref;
4014
4015trait Trait {
4016 type Assoc<T>: Deref<Target = T>;
4017 fn get<U>(&self) -> Self::Assoc<U>;
4018}
4019
4020fn f<T>(v: impl Trait) {
4021 let a = v.get::<i32>().deref();
4022 //^ &i32
4023 let a = v.get::<T>().deref();
4024 //^ &T
4025}
4026fn g<'a, T: 'a>(v: impl Trait<Assoc<T> = &'a T>) {
4027 let a = v.get::<T>();
4028 //^ &T
4029 let a = v.get::<()>();
4030 //^ Trait::Assoc<(), impl Trait<Assoc<T> = &T>>
4031}
4032fn h<'a>(v: impl Trait<Assoc<i32> = &'a i32> + Trait<Assoc<i64> = &'a i64>) {
4033 let a = v.get::<i32>();
4034 //^ &i32
4035 let a = v.get::<i64>();
4036 //^ &i64
4037}
4038fn i<'a>(v: impl Trait<Assoc<i32> = &'a i32, Assoc<i64> = &'a i64>) {
4039 let a = v.get::<i32>();
4040 //^ &i32
4041 let a = v.get::<i64>();
4042 //^ &i64
4043}
4044 "#,
4045 );
4046}
4047
4048#[test]
4049fn gats_with_dyn() {
4050 // This test is here to keep track of how we infer things despite traits with GATs being not
4051 // object-safe currently.
4052 // FIXME: reconsider how to treat these invalid types.
4053 check_infer_with_mismatches(
4054 r#"
4055//- minicore: deref
4056use core::ops::Deref;
4057
4058trait Trait {
4059 type Assoc<T>: Deref<Target = T>;
4060 fn get<U>(&self) -> Self::Assoc<U>;
4061}
4062
4063fn f<'a>(v: &dyn Trait<Assoc<i32> = &'a i32>) {
4064 v.get::<i32>().deref();
4065}
4066 "#,
4067 expect![[r#"
4068 90..94 'self': &Self
4069 127..128 'v': &(dyn Trait<Assoc<i32> = &i32>)
4070 164..195 '{ ...f(); }': ()
4071 170..171 'v': &(dyn Trait<Assoc<i32> = &i32>)
4072 170..184 'v.get::<i32>()': &i32
4073 170..192 'v.get:...eref()': &i32
4074 "#]],
4075 );
4076}
4077
4078#[test]
4079fn gats_in_associated_type_binding() {
4080 check_types(
4081 r#"
4082trait Trait {
4083 type Assoc<T>;
4084 fn get<U>(&self) -> Self::Assoc<U>;
4085}
4086
4087fn f<T>(t: T)
4088where
4089 T: Trait<Assoc<i32> = u32>,
4090 T: Trait<Assoc<isize> = usize>,
4091{
4092 let a = t.get::<i32>();
4093 //^ u32
4094 let a = t.get::<isize>();
4095 //^ usize
4096 let a = t.get::<()>();
4097 //^ Trait::Assoc<(), T>
4098}
4099
4100 "#,
4101 );
4102}
f25598a0
FG
4103
4104#[test]
4105fn bin_op_with_scalar_fallback() {
4106 // Extra impls are significant so that chalk doesn't give us definite guidances.
4107 check_types(
4108 r#"
4109//- minicore: add
4110use core::ops::Add;
4111
4112struct Vec2<T>(T, T);
4113
4114impl Add for Vec2<i32> {
4115 type Output = Self;
4116 fn add(self, rhs: Self) -> Self::Output { loop {} }
4117}
4118impl Add for Vec2<u32> {
4119 type Output = Self;
4120 fn add(self, rhs: Self) -> Self::Output { loop {} }
4121}
4122impl Add for Vec2<f32> {
4123 type Output = Self;
4124 fn add(self, rhs: Self) -> Self::Output { loop {} }
4125}
4126impl Add for Vec2<f64> {
4127 type Output = Self;
4128 fn add(self, rhs: Self) -> Self::Output { loop {} }
4129}
4130
4131fn test() {
4132 let a = Vec2(1, 2);
4133 let b = Vec2(3, 4);
4134 let c = a + b;
4135 //^ Vec2<i32>
4136 let a = Vec2(1., 2.);
4137 let b = Vec2(3., 4.);
4138 let c = a + b;
4139 //^ Vec2<f64>
4140}
4141"#,
4142 );
4143}
4144
4145#[test]
4146fn trait_method_with_scalar_fallback() {
4147 check_types(
4148 r#"
4149trait Trait {
4150 type Output;
4151 fn foo(&self) -> Self::Output;
4152}
4153impl<T> Trait for T {
4154 type Output = T;
4155 fn foo(&self) -> Self::Output { loop {} }
4156}
4157fn test() {
4158 let a = 42;
4159 let b = a.foo();
4160 //^ i32
4161 let a = 3.14;
4162 let b = a.foo();
4163 //^ f64
4164}
4165"#,
4166 );
4167}