未验证 提交 89249b19 编写于 作者: M Matthias Krüger 提交者: GitHub

Rollup merge of #97875 - JohnTitor:rm-infer-static-outlives-requirements, r=pnkfelix

Remove the `infer_static_outlives_requirements` feature

Closes #54185
r? ``@pnkfelix``
...@@ -409,8 +409,6 @@ pub fn set(&self, features: &mut Features, span: Span) { ...@@ -409,8 +409,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
(active, if_let_guard, "1.47.0", Some(51114), None), (active, if_let_guard, "1.47.0", Some(51114), None),
/// Allows using imported `main` function /// Allows using imported `main` function
(active, imported_main, "1.53.0", Some(28937), None), (active, imported_main, "1.53.0", Some(28937), None),
/// Allows inferring `'static` outlives requirements (RFC 2093).
(active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
/// Allows associated types in inherent impls. /// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995), None), (incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
/// Allow anonymous constants from an inline `const` block /// Allow anonymous constants from an inline `const` block
......
...@@ -109,6 +109,9 @@ ...@@ -109,6 +109,9 @@
/// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
(removed, in_band_lifetimes, "1.23.0", Some(44524), None, (removed, in_band_lifetimes, "1.23.0", Some(44524), None,
Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity")), Some("removed due to unsolved ergonomic questions and added lifetime resolution complexity")),
/// Allows inferring `'static` outlives requirements (RFC 2093).
(removed, infer_static_outlives_requirements, "1.63.0", Some(54185), None,
Some("removed as it caused some confusion and discussion was inactive for years")),
/// Lazily evaluate constants. This allows constants to depend on type parameters. /// Lazily evaluate constants. This allows constants to depend on type parameters.
(removed, lazy_normalization_consts, "1.46.0", Some(72219), None, Some("superseded by `generic_const_exprs`")), (removed, lazy_normalization_consts, "1.46.0", Some(72219), None, Some("superseded by `generic_const_exprs`")),
/// Allows using the `#[link_args]` attribute. /// Allows using the `#[link_args]` attribute.
......
...@@ -2113,7 +2113,6 @@ fn collect_outlives_bound_spans<'tcx>( ...@@ -2113,7 +2113,6 @@ fn collect_outlives_bound_spans<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
bounds: &hir::GenericBounds<'_>, bounds: &hir::GenericBounds<'_>,
inferred_outlives: &[ty::Region<'tcx>], inferred_outlives: &[ty::Region<'tcx>],
infer_static: bool,
) -> Vec<(usize, Span)> { ) -> Vec<(usize, Span)> {
use rustc_middle::middle::resolve_lifetime::Region; use rustc_middle::middle::resolve_lifetime::Region;
...@@ -2123,9 +2122,6 @@ fn collect_outlives_bound_spans<'tcx>( ...@@ -2123,9 +2122,6 @@ fn collect_outlives_bound_spans<'tcx>(
.filter_map(|(i, bound)| { .filter_map(|(i, bound)| {
if let hir::GenericBound::Outlives(lifetime) = bound { if let hir::GenericBound::Outlives(lifetime) = bound {
let is_inferred = match tcx.named_region(lifetime.hir_id) { let is_inferred = match tcx.named_region(lifetime.hir_id) {
Some(Region::Static) if infer_static => {
inferred_outlives.iter().any(|r| matches!(**r, ty::ReStatic))
}
Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| { Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| {
if let ty::ReEarlyBound(ebr) = **r { ebr.index == index } else { false } if let ty::ReEarlyBound(ebr) = **r { ebr.index == index } else { false }
}), }),
...@@ -2201,7 +2197,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { ...@@ -2201,7 +2197,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
use rustc_middle::middle::resolve_lifetime::Region; use rustc_middle::middle::resolve_lifetime::Region;
let infer_static = cx.tcx.features().infer_static_outlives_requirements;
let def_id = item.def_id; let def_id = item.def_id;
if let hir::ItemKind::Struct(_, ref hir_generics) if let hir::ItemKind::Struct(_, ref hir_generics)
| hir::ItemKind::Enum(_, ref hir_generics) | hir::ItemKind::Enum(_, ref hir_generics)
...@@ -2262,12 +2257,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { ...@@ -2262,12 +2257,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
continue; continue;
} }
let bound_spans = self.collect_outlives_bound_spans( let bound_spans =
cx.tcx, self.collect_outlives_bound_spans(cx.tcx, bounds, &relevant_lifetimes);
bounds,
&relevant_lifetimes,
infer_static,
);
bound_count += bound_spans.len(); bound_count += bound_spans.len();
let drop_predicate = bound_spans.len() == bounds.len(); let drop_predicate = bound_spans.len() == bounds.len();
......
...@@ -21,7 +21,7 @@ pub fn insert_outlives_predicate<'tcx>( ...@@ -21,7 +21,7 @@ pub fn insert_outlives_predicate<'tcx>(
) { ) {
// If the `'a` region is bound within the field type itself, we // If the `'a` region is bound within the field type itself, we
// don't want to propagate this constraint to the header. // don't want to propagate this constraint to the header.
if !is_free_region(tcx, outlived_region) { if !is_free_region(outlived_region) {
return; return;
} }
...@@ -119,7 +119,7 @@ pub fn insert_outlives_predicate<'tcx>( ...@@ -119,7 +119,7 @@ pub fn insert_outlives_predicate<'tcx>(
} }
GenericArgKind::Lifetime(r) => { GenericArgKind::Lifetime(r) => {
if !is_free_region(tcx, r) { if !is_free_region(r) {
return; return;
} }
required_predicates.entry(ty::OutlivesPredicate(kind, outlived_region)).or_insert(span); required_predicates.entry(ty::OutlivesPredicate(kind, outlived_region)).or_insert(span);
...@@ -131,7 +131,7 @@ pub fn insert_outlives_predicate<'tcx>( ...@@ -131,7 +131,7 @@ pub fn insert_outlives_predicate<'tcx>(
} }
} }
fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { fn is_free_region(region: Region<'_>) -> bool {
// First, screen for regions that might appear in a type header. // First, screen for regions that might appear in a type header.
match *region { match *region {
// These correspond to `T: 'a` relationships: // These correspond to `T: 'a` relationships:
...@@ -144,13 +144,12 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool { ...@@ -144,13 +144,12 @@ fn is_free_region(tcx: TyCtxt<'_>, region: Region<'_>) -> bool {
ty::ReEarlyBound(_) => true, ty::ReEarlyBound(_) => true,
// These correspond to `T: 'static` relationships which can be // These correspond to `T: 'static` relationships which can be
// rather surprising. We are therefore putting this behind a // rather surprising.
// feature flag:
// //
// struct Foo<'a, T> { // struct Foo<'a, T> {
// field: &'static T, // this would generate a ReStatic // field: &'static T, // this would generate a ReStatic
// } // }
ty::ReStatic => tcx.sess.features_untracked().infer_static_outlives_requirements, ty::ReStatic => false,
// Late-bound regions can appear in `fn` types: // Late-bound regions can appear in `fn` types:
// //
......
# `infer_static_outlives_requirements`
The tracking issue for this feature is: [#54185]
[#54185]: https://github.com/rust-lang/rust/issues/54185
------------------------
The `infer_static_outlives_requirements` feature indicates that certain
`'static` outlives requirements can be inferred by the compiler rather than
stating them explicitly.
Note: It is an accompanying feature to `infer_outlives_requirements`,
which must be enabled to infer outlives requirements.
For example, currently generic struct definitions that contain
references, require where-clauses of the form T: 'static. By using
this feature the outlives predicates will be inferred, although
they may still be written explicitly.
```rust,ignore (pseudo-Rust)
struct Foo<U> where U: 'static { // <-- currently required
bar: Bar<U>
}
struct Bar<T: 'static> {
x: T,
}
```
## Examples:
```rust,ignore (pseudo-Rust)
#![feature(infer_outlives_requirements)]
#![feature(infer_static_outlives_requirements)]
#[rustc_outlives]
// Implicitly infer U: 'static
struct Foo<U> {
bar: Bar<U>
}
struct Bar<T: 'static> {
x: T,
}
```
// Needs an explicit where clause stating outlives condition. (RFC 2093)
// Type T needs to outlive lifetime 'static.
struct Foo<U> {
bar: Bar<U> //~ ERROR the parameter type `U` may not live long enough [E0310]
}
struct Bar<T: 'static> {
x: T,
}
fn main() { }
error[E0310]: the parameter type `U` may not live long enough
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:10
|
LL | bar: Bar<U>
| ^^^^^^ ...so that the type `U` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:7:15
|
LL | struct Bar<T: 'static> {
| ^^^^^^^
help: consider adding an explicit lifetime bound...
|
LL | struct Foo<U: 'static> {
| +++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0310`.
/* /*
* We don't infer `T: 'static` outlives relationships by default. * We don't infer `T: 'static` outlives relationships.
* Instead an additional feature gate `infer_static_outlives_requirements`
* is required.
*/ */
struct Foo<U> { struct Foo<U> {
......
error[E0310]: the parameter type `U` may not live long enough error[E0310]: the parameter type `U` may not live long enough
--> $DIR/dont-infer-static.rs:8:10 --> $DIR/dont-infer-static.rs:6:10
| |
LL | bar: Bar<U> LL | bar: Bar<U>
| ^^^^^^ ...so that the type `U` will meet its required lifetime bounds... | ^^^^^^ ...so that the type `U` will meet its required lifetime bounds...
| |
note: ...that is required by this bound note: ...that is required by this bound
--> $DIR/dont-infer-static.rs:10:15 --> $DIR/dont-infer-static.rs:8:15
| |
LL | struct Bar<T: 'static> { LL | struct Bar<T: 'static> {
| ^^^^^^^ | ^^^^^^^
......
#![feature(rustc_attrs)]
#![feature(infer_static_outlives_requirements)]
#[rustc_outlives]
struct Foo<U> { //~ ERROR rustc_outlives
bar: Bar<U>
}
struct Bar<T: 'static> {
x: T,
}
fn main() {}
error: rustc_outlives
--> $DIR/infer-static.rs:5:1
|
LL | / struct Foo<U> {
LL | | bar: Bar<U>
LL | | }
| |_^
|
= note: U: 'static
error: aborting due to previous error
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册