summaryrefslogtreecommitdiffstats
path: root/tests/ui/generator/auto-trait-regions.rs
blob: fd13e41319f01be565189006571fc5ed7af0019f (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
// revisions: no_drop_tracking drop_tracking drop_tracking_mir
// [drop_tracking] compile-flags: -Zdrop-tracking
// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
#![feature(generators)]
#![feature(auto_traits)]
#![feature(negative_impls)]

auto trait Foo {}

struct No;

impl !Foo for No {}

struct A<'a, 'b>(&'a mut bool, &'b mut bool, No);

impl<'a, 'b: 'a> Foo for A<'a, 'b> {}

struct OnlyFooIfStaticRef(No);
impl Foo for &'static OnlyFooIfStaticRef {}

struct OnlyFooIfRef(No);
impl<'a> Foo for &'a OnlyFooIfRef {}

fn assert_foo<T: Foo>(f: T) {}

fn main() {
    // Make sure 'static is erased for generator interiors so we can't match it in trait selection
    let x: &'static _ = &OnlyFooIfStaticRef(No);
    let gen = || {
        let x = x;
        yield;
        assert_foo(x);
    };
    assert_foo(gen);
    //~^ ERROR implementation of `Foo` is not general enough

    // Allow impls which matches any lifetime
    let x = &OnlyFooIfRef(No);
    let gen = || {
        let x = x;
        yield;
        assert_foo(x);
    };
    assert_foo(gen); // ok

    // Disallow impls which relates lifetimes in the generator interior
    let gen = || {
        let a = A(&mut true, &mut true, No);
        //~^ temporary value dropped while borrowed
        //~| temporary value dropped while borrowed
        yield;
        assert_foo(a);
    };
    assert_foo(gen);
    //~^ ERROR not general enough
}