summaryrefslogtreecommitdiffstats
path: root/tests/ui/impl-trait/bound-normalization-pass.rs
blob: 5613c1916c6cdcd62db21500fa10ba18f14b1095 (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
// check-pass
// edition:2018
// revisions: default sa

#![feature(type_alias_impl_trait)]

// See issue 60414

// Reduction to `impl Trait`

struct Foo<T>(T);

trait FooLike {
    type Output;
}

impl<T> FooLike for Foo<T> {
    type Output = T;
}

mod impl_trait {
    use super::*;

    trait Trait {
        type Assoc;
    }

    /// `T::Assoc` should be normalized to `()` here.
    fn foo_pass<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
        Foo(())
    }
}

// Same with lifetimes in the trait

mod lifetimes {
    use super::*;

    trait Trait<'a> {
        type Assoc;
    }

    /// Like above.
    ///
    /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
    fn foo2_pass<'a, T: Trait<'a, Assoc = ()> + 'a>()
    -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
        Foo(())
    }

    /// Normalization to type containing bound region.
    ///
    /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
    fn foo2_pass2<'a, T: Trait<'a, Assoc = &'a ()> + 'a>()
    -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
        Foo(&())
    }
}

// The same applied to `type Foo = impl Bar`s

mod opaque_types {
    trait Implemented {
        type Assoc;
    }
    impl<T> Implemented for T {
        type Assoc = u8;
    }

    trait Trait {
        type Out;
    }

    impl Trait for () {
        type Out = u8;
    }

    type Ex = impl Trait<Out = <() as Implemented>::Assoc>;

    fn define() -> Ex {
        ()
    }
}

fn main() {}