Skip to content

Commit 1320d21

Browse files
committed
Auto merge of #54877 - arielb1:destabilize-outlives, r=nikomatsakis
[beta] back out #53793 - stabilize outlives requirements Fixes #54467 for beta, looks like a less risky fix than #54701
2 parents e473232 + e954510 commit 1320d21

File tree

139 files changed

+807
-802
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+807
-802
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# `infer_outlives_requirements`
2+
3+
The tracking issue for this feature is: [#44493]
4+
5+
[#44493]: https://github.com/rust-lang/rust/issues/44493
6+
7+
------------------------
8+
The `infer_outlives_requirements` feature indicates that certain
9+
outlives requirements can be inferred by the compiler rather than
10+
stating them explicitly.
11+
12+
For example, currently generic struct definitions that contain
13+
references, require where-clauses of the form T: 'a. By using
14+
this feature the outlives predicates will be inferred, although
15+
they may still be written explicitly.
16+
17+
```rust,ignore (pseudo-Rust)
18+
struct Foo<'a, T>
19+
where T: 'a // <-- currently required
20+
{
21+
bar: &'a T,
22+
}
23+
```
24+
25+
26+
## Examples:
27+
28+
29+
```rust,ignore (pseudo-Rust)
30+
#![feature(infer_outlives_requirements)]
31+
32+
// Implicitly infer T: 'a
33+
struct Foo<'a, T> {
34+
bar: &'a T,
35+
}
36+
```
37+
38+
```rust,ignore (pseudo-Rust)
39+
#![feature(infer_outlives_requirements)]
40+
41+
// Implicitly infer `U: 'b`
42+
struct Foo<'b, U> {
43+
bar: Bar<'b, U>
44+
}
45+
46+
struct Bar<'a, T> where T: 'a {
47+
x: &'a (),
48+
y: T,
49+
}
50+
```
51+
52+
```rust,ignore (pseudo-Rust)
53+
#![feature(infer_outlives_requirements)]
54+
55+
// Implicitly infer `b': 'a`
56+
struct Foo<'a, 'b, T> {
57+
x: &'a &'b T
58+
}
59+
```
60+
61+
```rust,ignore (pseudo-Rust)
62+
#![feature(infer_outlives_requirements)]
63+
64+
// Implicitly infer `<T as std::iter::Iterator>::Item : 'a`
65+
struct Foo<'a, T: Iterator> {
66+
bar: &'a T::Item
67+
```

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#![cfg_attr(not(test), feature(fn_traits))]
7878
#![cfg_attr(not(test), feature(generator_trait))]
7979
#![cfg_attr(not(stage0), feature(nll))]
80+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
8081
#![cfg_attr(test, feature(test))]
8182

8283
#![feature(allocator_api)]

src/liballoc_jemalloc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![feature(libc)]
1818
#![feature(linkage)]
1919
#![cfg_attr(not(stage0), feature(nll))]
20+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2021
#![feature(staged_api)]
2122
#![feature(rustc_attrs)]
2223
#![cfg_attr(dummy_jemalloc, allow(dead_code, unused_extern_crates))]

src/liballoc_system/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#![feature(allocator_api)]
1919
#![feature(core_intrinsics)]
2020
#![cfg_attr(not(stage0), feature(nll))]
21+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2122
#![feature(staged_api)]
2223
#![feature(rustc_attrs)]
2324
#![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))]

src/libarena/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#![feature(core_intrinsics)]
2828
#![feature(dropck_eyepatch)]
2929
#![cfg_attr(not(stage0), feature(nll))]
30+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3031
#![feature(raw_vec_internals)]
3132
#![cfg_attr(test, feature(test))]
3233

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#![feature(link_llvm_intrinsics)]
9393
#![feature(never_type)]
9494
#![cfg_attr(not(stage0), feature(nll))]
95+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
9596
#![feature(exhaustive_patterns)]
9697
#![feature(macro_at_most_once_rep)]
9798
#![feature(no_core)]

src/libfmt_macros/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
test(attr(deny(warnings))))]
2222

2323
#![cfg_attr(not(stage0), feature(nll))]
24+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2425

2526
pub use self::Piece::*;
2627
pub use self::Position::*;

src/libgraphviz/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@
289289
test(attr(allow(unused_variables), deny(warnings))))]
290290

291291
#![cfg_attr(not(stage0), feature(nll))]
292+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
292293
#![feature(str_escape)]
293294

294295
use self::LabelText::*;

src/libpanic_abort/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#![feature(core_intrinsics)]
2626
#![feature(libc)]
2727
#![cfg_attr(not(stage0), feature(nll))]
28+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2829
#![feature(panic_runtime)]
2930
#![feature(staged_api)]
3031
#![feature(rustc_attrs)]

src/libpanic_unwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#![feature(lang_items)]
3636
#![feature(libc)]
3737
#![cfg_attr(not(stage0), feature(nll))]
38+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3839
#![feature(panic_unwind)]
3940
#![feature(raw)]
4041
#![feature(staged_api)]

src/libproc_macro/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
2929

3030
#![cfg_attr(not(stage0), feature(nll))]
31+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3132
#![feature(rustc_private)]
3233
#![feature(staged_api)]
3334
#![feature(lang_items)]

src/libprofiler_builtins/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
issue = "0")]
1717
#![allow(unused_features)]
1818
#![cfg_attr(not(stage0), feature(nll))]
19+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1920
#![feature(staged_api)]

src/librustc/diagnostics.rs

+38-52
Original file line numberDiff line numberDiff line change
@@ -1232,54 +1232,41 @@ let x: i32 = "I am not a number!";
12321232
"##,
12331233

12341234
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.
12411239
12421240
```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
12461243
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
12591245
}
12601246
```
12611247
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:
12651249
12661250
```
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
12721253
}
1254+
```
12731255
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
12761263
}
12771264
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!
12831270
}
12841271
```
12851272
"##,
@@ -1478,31 +1465,30 @@ A reference has a longer lifetime than the data it references.
14781465
Erroneous code example:
14791466
14801467
```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,
14831472
}
14841473
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
14871479
}
14881480
```
14891481
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:
14951483
14961484
```
1497-
trait SomeTrait<'a> {
1498-
type Output;
1485+
struct Struct<'a> {
1486+
ref_i32: &'a i32,
14991487
}
15001488
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>,
15061492
}
15071493
```
15081494
"##,

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#![feature(exhaustive_patterns)]
5353
#![feature(extern_types)]
5454
#![cfg_attr(not(stage0), feature(nll))]
55+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
5556
#![feature(non_exhaustive)]
5657
#![feature(proc_macro_internals)]
5758
#![feature(quote)]

src/librustc_allocator/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![cfg_attr(not(stage0), feature(nll))]
12+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1213
#![feature(rustc_private)]
1314

1415
#[macro_use] extern crate log;

src/librustc_apfloat/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#![forbid(unsafe_code)]
4747

4848
#![cfg_attr(not(stage0), feature(nll))]
49+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
4950
#![feature(try_from)]
5051
// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
5152
#[allow(unused_extern_crates)]

src/librustc_asan/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![sanitizer_runtime]
1212
#![feature(alloc_system)]
1313
#![cfg_attr(not(stage0), feature(nll))]
14+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1415
#![feature(sanitizer_runtime)]
1516
#![feature(staged_api)]
1617
#![no_std]

src/librustc_borrowck/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#![allow(non_camel_case_types)]
1616

1717
#![cfg_attr(not(stage0), feature(nll))]
18+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1819
#![feature(quote)]
1920

2021
#![recursion_limit="256"]

src/librustc_codegen_llvm/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#![allow(unused_attributes)]
2828
#![feature(libc)]
2929
#![cfg_attr(not(stage0), feature(nll))]
30+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3031
#![feature(quote)]
3132
#![feature(range_contains)]
3233
#![feature(rustc_diagnostic_macros)]

src/librustc_codegen_utils/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(box_syntax)]
2121
#![feature(custom_attribute)]
2222
#![cfg_attr(not(stage0), feature(nll))]
23+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2324
#![allow(unused_attributes)]
2425
#![feature(quote)]
2526
#![feature(rustc_diagnostic_macros)]

src/librustc_cratesio_shim/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![allow(unused_extern_crates)]
1313

1414
#![cfg_attr(not(stage0), feature(nll))]
15+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1516

1617
extern crate bitflags;
1718
extern crate log;

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#![feature(optin_builtin_traits)]
3030
#![cfg_attr(stage0, feature(macro_vis_matcher))]
3131
#![cfg_attr(not(stage0), feature(nll))]
32+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3233
#![feature(allow_internal_unstable)]
3334
#![feature(vec_resize_with)]
3435

src/librustc_driver/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#![feature(box_syntax)]
2222
#![cfg_attr(unix, feature(libc))]
2323
#![cfg_attr(not(stage0), feature(nll))]
24+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2425
#![feature(option_replace)]
2526
#![feature(quote)]
2627
#![feature(rustc_diagnostic_macros)]

src/librustc_errors/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![feature(range_contains)]
1818
#![cfg_attr(unix, feature(libc))]
1919
#![cfg_attr(not(stage0), feature(nll))]
20+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
2021
#![feature(optin_builtin_traits)]
2122

2223
extern crate atty;

src/librustc_incremental/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
html_root_url = "https://doc.rust-lang.org/nightly/")]
1616

1717
#![cfg_attr(not(stage0), feature(nll))]
18+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1819
#![feature(specialization)]
1920

2021
#![recursion_limit="256"]

src/librustc_lint/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#![feature(box_syntax)]
2929
#![cfg_attr(stage0, feature(macro_vis_matcher))]
3030
#![cfg_attr(not(stage0), feature(nll))]
31+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
3132
#![feature(quote)]
3233
#![feature(rustc_diagnostic_macros)]
3334
#![feature(macro_at_most_once_rep)]

src/librustc_llvm/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![cfg_attr(not(stage0), feature(nll))]
12+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1213
#![feature(static_nobundle)]
1314

1415
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",

src/librustc_lsan/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![sanitizer_runtime]
1212
#![feature(alloc_system)]
1313
#![cfg_attr(not(stage0), feature(nll))]
14+
#![cfg_attr(not(stage0), feature(infer_outlives_requirements))]
1415
#![feature(sanitizer_runtime)]
1516
#![feature(staged_api)]
1617
#![no_std]

0 commit comments

Comments
 (0)