summaryrefslogtreecommitdiffstats
path: root/src/test/ui/associated-types/issue-54182-1.rs
blob: 1a1e98cbac27f4a74c9aa520a94abcf49aaa9ed9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// run-pass

// Tests that the return type of trait methods is correctly normalized when
// checking that a method in an impl matches the trait definition when the
// return type involves a defaulted associated type.
// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`,
// but the impl leaves out the return type (resulting in `()`).
// Note that specialization is not involved in this test; no items in
// implementations may be overridden. If they were, the normalization wouldn't
// happen.

#![feature(associated_type_defaults)]

macro_rules! overload {
    ($a:expr, $b:expr) => {
        overload::overload2($a, $b)
    };
    ($a:expr, $b:expr, $c:expr) => {
        overload::overload3($a, $b, $c)
    }
}

fn main() {
    let () = overload!(42, true);

    let r: f32 = overload!("Hello world", 13.0);
    assert_eq!(r, 13.0);

    let () = overload!(42, true, 42.5);

    let r: i32 = overload!("Hello world", 13.0, 42);
    assert_eq!(r, 42);
}

mod overload {
    /// This trait has an assoc. type defaulting to `()`, and a required method returning a value
    /// of that assoc. type.
    pub trait Overload {
        // type R;
        type R = ();
        fn overload(self) -> Self::R;
    }

    // overloads for 2 args
    impl Overload for (i32, bool) {
        // type R = ();

        /// This function has no return type specified, and so defaults to `()`.
        ///
        /// This should work, but didn't, until RFC 2532 was implemented.
        fn overload(self) /*-> Self::R*/ {
            let (a, b) = self; // destructure args
            println!("i32 and bool {:?}", (a, b));
        }
    }
    impl<'a> Overload for (&'a str, f32) {
        type R = f32;
        fn overload(self) -> Self::R {
            let (a, b) = self; // destructure args
            println!("&str and f32 {:?}", (a, b));
            b
        }
    }

    // overloads for 3 args
    impl Overload for (i32, bool, f32) {
        // type R = ();
        fn overload(self) /*-> Self::R*/ {
            let (a, b, c) = self; // destructure args
            println!("i32 and bool and f32 {:?}", (a, b, c));
        }
    }
    impl<'a> Overload for (&'a str, f32, i32) {
        type R = i32;
        fn overload(self) -> Self::R {
            let (a, b, c) = self; // destructure args
            println!("&str and f32 and i32: {:?}", (a, b, c));
            c
        }
    }

    // overloads for more args
    // ...

    pub fn overload2<R, A, B>(a: A, b: B) -> R where (A, B): Overload<R = R> {
        (a, b).overload()
    }

    pub fn overload3<R, A, B, C>(a: A, b: B, c: C) -> R where (A, B, C): Overload<R = R> {
        (a, b, c).overload()
    }
}