summaryrefslogtreecommitdiffstats
path: root/tests/ui/rust-2018/edition-lint-infer-outlives-macro.rs
blob: 647906c2dc228366e713dc40217f98e907d5a8b1 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// edition:2018
// aux-build:edition-lint-infer-outlives-macro.rs
// run-rustfix

#![deny(explicit_outlives_requirements)]
#![allow(dead_code)]

#[macro_use]
extern crate edition_lint_infer_outlives_macro;

// Test that the lint does not fire if the predicate is from the local crate,
// but all the bounds are from an external macro.
macro_rules! make_foo {
    ($a:tt) => {
        struct Foo<$a, 'b: $a> {
            foo: &$a &'b (),
        }

        struct FooWhere<$a, 'b> where 'b: $a {
            foo: &$a &'b (),
        }
    }
}

gimme_a! {make_foo!}

struct Bar<'a, 'b: 'a> {
    //~^ ERROR: outlives requirements can be inferred
    bar: &'a &'b (),
}

struct BarWhere<'a, 'b> where 'b: 'a {
    //~^ ERROR: outlives requirements can be inferred
    bar: &'a &'b (),
}

// Test that the lint *does* fire if the predicate is contained in a local macro.
mod everything_inside {
    macro_rules! m {
        ('b: 'a) => {
            struct Foo<'a, 'b: 'a>(&'a &'b ());
            //~^ ERROR: outlives requirements can be inferred
            struct Bar<'a, 'b>(&'a &'b ()) where 'b: 'a;
            //~^ ERROR: outlives requirements can be inferred
            struct Baz<'a, 'b>(&'a &'b ()) where (): Sized, 'b: 'a;
            //~^ ERROR: outlives requirements can be inferred
        };
    }
    m!('b: 'a);
}

mod inner_lifetime_outside_colon_inside {
    macro_rules! m {
        ($b:lifetime: 'a) => {
            struct Foo<'a, $b: 'a>(&'a &$b ());
            //~^ ERROR: outlives requirements can be inferred
            struct Bar<'a, $b>(&'a &$b ()) where $b: 'a;
            //~^ ERROR: outlives requirements can be inferred
            struct Baz<'a, $b>(&'a &$b ()) where (): Sized, $b: 'a;
            //~^ ERROR: outlives requirements can be inferred
        }
    }
    m!('b: 'a);
}

mod outer_lifetime_outside_colon_inside {
    macro_rules! m {
        ('b: $a:lifetime) => {
            struct Foo<$a, 'b: $a>(&$a &'b ());
            struct Bar<$a, 'b>(&$a &'b ()) where 'b: $a;
            struct Baz<$a, 'b>(&$a &'b ()) where (): Sized, 'b: $a;
        }
    }
    m!('b: 'a);
}

mod both_lifetimes_outside_colon_inside {
    macro_rules! m {
        ($b:lifetime: $a:lifetime) => {
            struct Foo<$a, $b: $a>(&$a &$b ());
            struct Bar<$a, $b>(&$a &$b ()) where $b: $a;
            struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b: $a;
        }
    }
    m!('b: 'a);
}

mod everything_outside {
    macro_rules! m {
        ($b:lifetime $colon:tt $a:lifetime) => {
            struct Foo<$a, $b $colon $a>(&$a &$b ());
            struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
            struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
        }
    }
    m!('b: 'a);
}

mod everything_outside_with_tt_inner {
    macro_rules! m {
        ($b:tt $colon:tt $a:lifetime) => {
            struct Foo<$a, $b $colon $a>(&$a &$b ());
            struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
            struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
        }
    }
    m!('b: 'a);
}

// FIXME: These should be consistent.
mod everything_outside_with_tt_outer {
    macro_rules! m {
        ($b:lifetime $colon:tt $a:tt) => {
            struct Foo<$a, $b $colon $a>(&$a &$b ());
            //~^ ERROR: outlives requirements can be inferred
            struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
            struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
        }
    }
    m!('b: 'a);
}

mod everything_outside_with_tt_both {
    macro_rules! m {
        ($b:tt $colon:tt $a:tt) => {
            struct Foo<$a, $b $colon $a>(&$a &$b ());
            //~^ ERROR: outlives requirements can be inferred
            struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
            //~^ ERROR: outlives requirements can be inferred
            struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
            //~^ ERROR: outlives requirements can be inferred
        }
    }
    m!('b: 'a);
}

fn main() {}