@@ -1232,41 +1232,54 @@ let x: i32 = "I am not a number!";
1232
1232
"## ,
1233
1233
1234
1234
E0309 : r##"
1235
- Types in type definitions have lifetimes associated with them that represent
1236
- how long the data stored within them is guaranteed to be live. This lifetime
1237
- must be as long as the data needs to be alive, and missing the constraint that
1238
- denotes this will cause this error.
1235
+ The type definition contains some field whose type
1236
+ requires an outlives annotation. Outlives annotations
1237
+ (e.g., `T: 'a`) are used to guarantee that all the data in T is valid
1238
+ for at least the lifetime `'a`. This scenario most commonly
1239
+ arises when the type contains an associated type reference
1240
+ like `<T as SomeTrait<'a>>::Output`, as shown in this example:
1239
1241
1240
1242
```compile_fail,E0309
1241
- // This won't compile because T is not constrained, meaning the data
1242
- // stored in it is not guaranteed to last as long as the reference
1243
+ // This won't compile because the applicable impl of
1244
+ // `SomeTrait` (below) requires that `T: 'a`, but the struct does
1245
+ // not have a matching where-clause.
1243
1246
struct Foo<'a, T> {
1244
- foo: &'a T
1247
+ foo: <T as SomeTrait<'a>>::Output,
1245
1248
}
1246
- ```
1247
1249
1248
- This will compile, because it has the constraint on the type parameter:
1250
+ trait SomeTrait<'a> {
1251
+ type Output;
1252
+ }
1249
1253
1250
- ```
1251
- struct Foo<'a, T: 'a> {
1252
- foo: &'a T
1254
+ impl<'a, T> SomeTrait<'a> for T
1255
+ where
1256
+ T: 'a,
1257
+ {
1258
+ type Output = u32;
1253
1259
}
1254
1260
```
1255
1261
1256
- To see why this is important, consider the case where `T` is itself a reference
1257
- (e.g., `T = &str`). If we don't include the restriction that `T: 'a`, the
1258
- following code would be perfectly legal :
1262
+ Here, the where clause `T: 'a` that appears on the impl is not known to be
1263
+ satisfied on the struct. To make this example compile, you have to add
1264
+ a where-clause like `T: 'a` to the struct definition :
1259
1265
1260
- ```compile_fail,E0309
1261
- struct Foo<'a, T> {
1262
- foo: &'a T
1266
+ ```
1267
+ struct Foo<'a, T>
1268
+ where
1269
+ T: 'a,
1270
+ {
1271
+ foo: <T as SomeTrait<'a>>::Output
1263
1272
}
1264
1273
1265
- fn main() {
1266
- let v = "42".to_string();
1267
- let f = Foo{foo: &v};
1268
- drop(v);
1269
- println!("{}", f.foo); // but we've already dropped v!
1274
+ trait SomeTrait<'a> {
1275
+ type Output;
1276
+ }
1277
+
1278
+ impl<'a, T> SomeTrait<'a> for T
1279
+ where
1280
+ T: 'a,
1281
+ {
1282
+ type Output = u32;
1270
1283
}
1271
1284
```
1272
1285
"## ,
@@ -1465,30 +1478,31 @@ A reference has a longer lifetime than the data it references.
1465
1478
Erroneous code example:
1466
1479
1467
1480
```compile_fail,E0491
1468
- // struct containing a reference requires a lifetime parameter,
1469
- // because the data the reference points to must outlive the struct (see E0106)
1470
- struct Struct<'a> {
1471
- ref_i32: &'a i32,
1481
+ trait SomeTrait<'a> {
1482
+ type Output;
1472
1483
}
1473
1484
1474
- // However, a nested struct like this, the signature itself does not tell
1475
- // whether 'a outlives 'b or the other way around.
1476
- // So it could be possible that 'b of reference outlives 'a of the data.
1477
- struct Nested<'a, 'b> {
1478
- ref_struct: &'b Struct<'a>, // compile error E0491
1485
+ impl<'a, T> SomeTrait<'a> for T {
1486
+ type Output = &'a T; // compile error E0491
1479
1487
}
1480
1488
```
1481
1489
1482
- To fix this issue, you can specify a bound to the lifetime like below:
1490
+ Here, the problem is that a reference type like `&'a T` is only valid
1491
+ if all the data in T outlives the lifetime `'a`. But this impl as written
1492
+ is applicable to any lifetime `'a` and any type `T` -- we have no guarantee
1493
+ that `T` outlives `'a`. To fix this, you can add a where clause like
1494
+ `where T: 'a`.
1483
1495
1484
1496
```
1485
- struct Struct <'a> {
1486
- ref_i32: &'a i32,
1497
+ trait SomeTrait <'a> {
1498
+ type Output;
1487
1499
}
1488
1500
1489
- // 'a: 'b means 'a outlives 'b
1490
- struct Nested<'a: 'b, 'b> {
1491
- ref_struct: &'b Struct<'a>,
1501
+ impl<'a, T> SomeTrait<'a> for T
1502
+ where
1503
+ T: 'a,
1504
+ {
1505
+ type Output = &'a T; // compile error E0491
1492
1506
}
1493
1507
```
1494
1508
"## ,
0 commit comments