]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/issue-54182-1.rs
Rollup merge of #105567 - TimNN:kcfi16, r=nikic
[rust.git] / src / test / ui / associated-types / issue-54182-1.rs
1 // run-pass
2
3 // Tests that the return type of trait methods is correctly normalized when
4 // checking that a method in an impl matches the trait definition when the
5 // return type involves a defaulted associated type.
6 // ie. the trait has a method with return type `-> Self::R`, and `type R = ()`,
7 // but the impl leaves out the return type (resulting in `()`).
8 // Note that specialization is not involved in this test; no items in
9 // implementations may be overridden. If they were, the normalization wouldn't
10 // happen.
11
12 #![feature(associated_type_defaults)]
13
14 macro_rules! overload {
15     ($a:expr, $b:expr) => {
16         overload::overload2($a, $b)
17     };
18     ($a:expr, $b:expr, $c:expr) => {
19         overload::overload3($a, $b, $c)
20     }
21 }
22
23 fn main() {
24     let () = overload!(42, true);
25
26     let r: f32 = overload!("Hello world", 13.0);
27     assert_eq!(r, 13.0);
28
29     let () = overload!(42, true, 42.5);
30
31     let r: i32 = overload!("Hello world", 13.0, 42);
32     assert_eq!(r, 42);
33 }
34
35 mod overload {
36     /// This trait has an assoc. type defaulting to `()`, and a required method returning a value
37     /// of that assoc. type.
38     pub trait Overload {
39         // type R;
40         type R = ();
41         fn overload(self) -> Self::R;
42     }
43
44     // overloads for 2 args
45     impl Overload for (i32, bool) {
46         // type R = ();
47
48         /// This function has no return type specified, and so defaults to `()`.
49         ///
50         /// This should work, but didn't, until RFC 2532 was implemented.
51         fn overload(self) /*-> Self::R*/ {
52             let (a, b) = self; // destructure args
53             println!("i32 and bool {:?}", (a, b));
54         }
55     }
56     impl<'a> Overload for (&'a str, f32) {
57         type R = f32;
58         fn overload(self) -> Self::R {
59             let (a, b) = self; // destructure args
60             println!("&str and f32 {:?}", (a, b));
61             b
62         }
63     }
64
65     // overloads for 3 args
66     impl Overload for (i32, bool, f32) {
67         // type R = ();
68         fn overload(self) /*-> Self::R*/ {
69             let (a, b, c) = self; // destructure args
70             println!("i32 and bool and f32 {:?}", (a, b, c));
71         }
72     }
73     impl<'a> Overload for (&'a str, f32, i32) {
74         type R = i32;
75         fn overload(self) -> Self::R {
76             let (a, b, c) = self; // destructure args
77             println!("&str and f32 and i32: {:?}", (a, b, c));
78             c
79         }
80     }
81
82     // overloads for more args
83     // ...
84
85     pub fn overload2<R, A, B>(a: A, b: B) -> R where (A, B): Overload<R = R> {
86         (a, b).overload()
87     }
88
89     pub fn overload3<R, A, B, C>(a: A, b: B, c: C) -> R where (A, B, C): Overload<R = R> {
90         (a, b, c).overload()
91     }
92 }