@@ -1232,54 +1232,41 @@ let x: i32 = "I am not a number!";
1232
1232
"## ,
1233
1233
1234
1234
E0309 : r##"
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:
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.
1241
1239
1242
1240
```compile_fail,E0309
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.
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
1246
1243
struct Foo<'a, T> {
1247
- foo: <T as SomeTrait<'a>>::Output,
1248
- }
1249
-
1250
- trait SomeTrait<'a> {
1251
- type Output;
1252
- }
1253
-
1254
- impl<'a, T> SomeTrait<'a> for T
1255
- where
1256
- T: 'a,
1257
- {
1258
- type Output = u32;
1244
+ foo: &'a T
1259
1245
}
1260
1246
```
1261
1247
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:
1248
+ This will compile, because it has the constraint on the type parameter:
1265
1249
1266
1250
```
1267
- struct Foo<'a, T>
1268
- where
1269
- T: 'a,
1270
- {
1271
- foo: <T as SomeTrait<'a>>::Output
1251
+ struct Foo<'a, T: 'a> {
1252
+ foo: &'a T
1272
1253
}
1254
+ ```
1273
1255
1274
- trait SomeTrait<'a> {
1275
- type Output;
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:
1259
+
1260
+ ```compile_fail,E0309
1261
+ struct Foo<'a, T> {
1262
+ foo: &'a T
1276
1263
}
1277
1264
1278
- impl<'a, T> SomeTrait<'a> for T
1279
- where
1280
- T: 'a,
1281
- {
1282
- type Output = u32;
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!
1283
1270
}
1284
1271
```
1285
1272
"## ,
@@ -1478,31 +1465,30 @@ A reference has a longer lifetime than the data it references.
1478
1465
Erroneous code example:
1479
1466
1480
1467
```compile_fail,E0491
1481
- trait SomeTrait<'a> {
1482
- type Output;
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,
1483
1472
}
1484
1473
1485
- impl<'a, T> SomeTrait<'a> for T {
1486
- type Output = &'a T; // compile error E0491
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
1487
1479
}
1488
1480
```
1489
1481
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`.
1482
+ To fix this issue, you can specify a bound to the lifetime like below:
1495
1483
1496
1484
```
1497
- trait SomeTrait <'a> {
1498
- type Output;
1485
+ struct Struct <'a> {
1486
+ ref_i32: &'a i32,
1499
1487
}
1500
1488
1501
- impl<'a, T> SomeTrait<'a> for T
1502
- where
1503
- T: 'a,
1504
- {
1505
- type Output = &'a T; // compile error E0491
1489
+ // 'a: 'b means 'a outlives 'b
1490
+ struct Nested<'a: 'b, 'b> {
1491
+ ref_struct: &'b Struct<'a>,
1506
1492
}
1507
1493
```
1508
1494
"## ,
0 commit comments