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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
//@ check-fail
use std::fmt::Debug;
// We have a `&'a self`, so we need a `Self: 'a`
trait Iterable {
type Item<'x>;
//~^ missing required
fn iter<'a>(&'a self) -> Self::Item<'a>;
}
/*
impl<T> Iterable for T {
type Item<'a> = &'a T;
fn iter<'a>(&'a self) -> Self::Item<'a> {
self
}
}
*/
// We have a `&'a T`, so we need a `T: 'x`
trait Deserializer<T> {
type Out<'x>;
//~^ missing required
fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>;
}
/*
impl<T> Deserializer<T> for () {
type Out<'a> = &'a T;
fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a> { input }
}
*/
// We have a `&'b T` and a `'b: 'a`, so it is implied that `T: 'a`. Therefore, we need a `T: 'x`
trait Deserializer2<T> {
type Out<'x>;
//~^ missing required
fn deserialize2<'a, 'b: 'a>(&self, input1: &'b T) -> Self::Out<'a>;
}
// We have a `&'a T` and a `&'b U`, so we need a `T: 'x` and a `U: 'y`
trait Deserializer3<T, U> {
type Out<'x, 'y>;
//~^ missing required
fn deserialize2<'a, 'b>(&self, input: &'a T, input2: &'b U) -> Self::Out<'a, 'b>;
}
// `T` is a param on the function, so it can't be named by the associated type
trait Deserializer4 {
type Out<'x>;
fn deserialize<'a, T>(&self, input: &'a T) -> Self::Out<'a>;
}
struct Wrap<T>(T);
// We pass `Wrap<T>` and we see `&'z Wrap<T>`, so we require `D: 'x`
trait Des {
type Out<'x, D>;
//~^ missing required
fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>;
}
/*
impl Des for () {
type Out<'x, D> = &'x D; // Not okay
fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, Wrap<T>> {
data
}
}
*/
// We have `T` and `'z` as GAT substs. Because of `&'z Wrap<T>`, there is an
// implied bound that `T: 'z`, so we require `D: 'x`
trait Des2 {
type Out<'x, D>;
//~^ missing required
fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, T>;
}
/*
impl Des2 for () {
type Out<'x, D> = &'x D;
fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, T> {
&data.0
}
}
*/
// We see `&'z T`, so we require `D: 'x`
trait Des3 {
type Out<'x, D>;
//~^ missing required
fn des<'z, T>(&self, data: &'z T) -> Self::Out<'z, T>;
}
/*
impl Des3 for () {
type Out<'x, D> = &'x D;
fn des<'a, T>(&self, data: &'a T) -> Self::Out<'a, T> {
data
}
}
*/
// Similar case to before, except with GAT.
trait NoGat<'a> {
type Bar;
fn method(&'a self) -> Self::Bar;
}
// Lifetime is not on function; except `Self: 'a`
// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
trait TraitLifetime<'a> {
type Bar<'b>;
//~^ missing required
fn method(&'a self) -> Self::Bar<'a>;
}
// Like above, but we have a where clause that can prove what we want
// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
trait TraitLifetimeWhere<'a> where Self: 'a {
type Bar<'b>;
//~^ missing required
fn method(&'a self) -> Self::Bar<'a>;
}
// Explicit bound instead of implicit; we want to still error
trait ExplicitBound {
type Bar<'b>;
//~^ missing required
fn method<'b>(&self, token: &'b ()) -> Self::Bar<'b> where Self: 'b;
}
// The use of the GAT here is not in the return, we don't want to error
trait NotInReturn {
type Bar<'b>;
fn method<'b>(&'b self) where Self::Bar<'b>: Debug;
}
// We obviously error for `Iterator`, but we should also error for `Item`
trait IterableTwo {
type Item<'a>;
//~^ missing required
type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
//~^ missing required
fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}
trait IterableTwoWhere {
type Item<'a>;
//~^ missing required
type Iterator<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}
// We also should report region outlives clauses. Here, we know that `'y: 'x`,
// because of `&'x &'y`, so we require that `'b: 'a`.
trait RegionOutlives {
type Bar<'a, 'b>;
//~^ missing required
fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y>;
}
/*
impl Foo for () {
type Bar<'a, 'b> = &'a &'b ();
fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y> {
input
}
}
*/
// Similar to the above, except with explicit bounds
trait ExplicitRegionOutlives<'ctx> {
type Fut<'out>;
//~^ missing required
fn test<'out>(ctx: &'ctx i32) -> Self::Fut<'out>
where
'ctx: 'out;
}
// If there are multiple methods that return the GAT, require a set of clauses
// that can be satisfied by *all* methods
trait MultipleMethods {
type Bar<'me>;
fn gimme<'a>(&'a self) -> Self::Bar<'a>;
fn gimme_default(&self) -> Self::Bar<'static>;
}
// We would normally require `Self: 'a`, but we can prove that `Self: 'static`
// because of the bounds on the trait, so the bound is proven
trait Trait: 'static {
type Assoc<'a>;
fn make_assoc(_: &u32) -> Self::Assoc<'_>;
}
// We ignore `'static` lifetimes for any lints
trait StaticReturn<'a> {
type Y<'b>;
fn foo(&self) -> Self::Y<'static>;
}
// Same as above, but with extra method that takes GAT - just make sure this works
trait StaticReturnAndTakes<'a> {
type Y<'b>;
fn foo(&self) -> Self::Y<'static>;
fn bar<'b>(&self, arg: Self::Y<'b>);
}
// We require bounds when the GAT appears in the inputs
trait Input {
type Item<'a>;
//~^ missing required
fn takes_item<'a>(&'a self, item: Self::Item<'a>);
}
// We don't require bounds when the GAT appears in the where clauses
trait WhereClause {
type Item<'a>;
fn takes_item<'a>(&'a self) where Self::Item<'a>: ;
}
fn main() {}
|