Remove lifetime_capture_rules_2024 feature

This commit is contained in:
Michael Goulet 2025-02-09 19:09:43 +00:00
parent a26e97be88
commit 6fe8b8d4a0
12 changed files with 35 additions and 78 deletions

View file

@ -135,6 +135,8 @@ declare_features! (
Some("removed as it caused some confusion and discussion was inactive for years")),
/// Lazily evaluate constants. This allows constants to depend on type parameters.
(removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
/// Changes `impl Trait` to capture all lifetimes in scope.
(removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")),
/// Allows using the `#[link_args]` attribute.
(removed, link_args, "1.53.0", Some(29596),
Some("removed in favor of using `-C link-arg=ARG` on command line, \

View file

@ -214,8 +214,6 @@ declare_features! (
(internal, intrinsics, "1.0.0", None),
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
(internal, lang_items, "1.0.0", None),
/// Changes `impl Trait` to capture all lifetimes in scope.
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
(internal, link_cfg, "1.14.0", None),
/// Allows using `?Trait` trait bounds in more contexts.

View file

@ -305,21 +305,15 @@ fn generic_param_def_as_bound_arg(param: &ty::GenericParamDef) -> ty::BoundVaria
}
/// Whether this opaque always captures lifetimes in scope.
/// Right now, this is all RPITIT and TAITs, and when `lifetime_capture_rules_2024`
/// is enabled. We don't check the span of the edition, since this is done
/// on a per-opaque basis to account for nested opaques.
fn opaque_captures_all_in_scope_lifetimes<'tcx>(
tcx: TyCtxt<'tcx>,
opaque: &'tcx hir::OpaqueTy<'tcx>,
) -> bool {
/// Right now, this is all RPITIT and TAITs, and when the opaque
/// is coming from a span corresponding to edition 2024.
fn opaque_captures_all_in_scope_lifetimes<'tcx>(opaque: &'tcx hir::OpaqueTy<'tcx>) -> bool {
match opaque.origin {
// if the opaque has the `use<...>` syntax, the user is telling us that they only want
// to account for those lifetimes, so do not try to be clever.
_ if opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) => false,
hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => true,
_ if tcx.features().lifetime_capture_rules_2024() || opaque.span.at_least_rust_2024() => {
true
}
_ if opaque.span.at_least_rust_2024() => true,
hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(),
}
}
@ -519,8 +513,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) {
let captures = RefCell::new(FxIndexMap::default());
let capture_all_in_scope_lifetimes =
opaque_captures_all_in_scope_lifetimes(self.tcx, opaque);
let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque);
if capture_all_in_scope_lifetimes {
let lifetime_ident = |def_id: LocalDefId| {
let name = self.tcx.item_name(def_id.to_def_id());
@ -2273,7 +2266,7 @@ fn is_late_bound_map(
}
let mut appears_in_output =
AllCollector { tcx, has_fully_capturing_opaque: false, regions: Default::default() };
AllCollector { has_fully_capturing_opaque: false, regions: Default::default() };
intravisit::walk_fn_ret_ty(&mut appears_in_output, &sig.decl.output);
if appears_in_output.has_fully_capturing_opaque {
appears_in_output.regions.extend(generics.params.iter().map(|param| param.def_id));
@ -2286,7 +2279,7 @@ fn is_late_bound_map(
// Subtle point: because we disallow nested bindings, we can just
// ignore binders here and scrape up all names we see.
let mut appears_in_where_clause =
AllCollector { tcx, has_fully_capturing_opaque: true, regions: Default::default() };
AllCollector { has_fully_capturing_opaque: true, regions: Default::default() };
appears_in_where_clause.visit_generics(generics);
debug!(?appears_in_where_clause.regions);
@ -2452,23 +2445,21 @@ fn is_late_bound_map(
}
}
struct AllCollector<'tcx> {
tcx: TyCtxt<'tcx>,
struct AllCollector {
has_fully_capturing_opaque: bool,
regions: FxHashSet<LocalDefId>,
}
impl<'v> Visitor<'v> for AllCollector<'v> {
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
impl<'tcx> Visitor<'tcx> for AllCollector {
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
self.regions.insert(def_id);
}
}
fn visit_opaque_ty(&mut self, opaque: &'v hir::OpaqueTy<'v>) {
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
if !self.has_fully_capturing_opaque {
self.has_fully_capturing_opaque =
opaque_captures_all_in_scope_lifetimes(self.tcx, opaque);
self.has_fully_capturing_opaque = opaque_captures_all_in_scope_lifetimes(opaque);
}
intravisit::walk_opaque_ty(self, opaque);
}

View file

@ -86,8 +86,7 @@ declare_lint! {
///
/// ### Example
///
/// ```rust,compile_fail
/// # #![feature(lifetime_capture_rules_2024)]
/// ```rust,edition2024,compile_fail
/// # #![deny(impl_trait_redundant_captures)]
/// fn test<'a>(x: &'a i32) -> impl Sized + use<'a> { x }
/// ```
@ -268,8 +267,7 @@ where
&& parent == self.parent_def_id
{
let opaque_span = self.tcx.def_span(opaque_def_id);
let new_capture_rules = opaque_span.at_least_rust_2024()
|| self.tcx.features().lifetime_capture_rules_2024();
let new_capture_rules = opaque_span.at_least_rust_2024();
if !new_capture_rules
&& !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..)))
{

View file

@ -1,13 +1,13 @@
//@ known-bug: #117647
//@ edition: 2024
#![feature(lifetime_capture_rules_2024)]
#![feature(rustc_attrs)]
#![allow(internal_features)]
#![rustc_variance_of_opaques]
use std::ops::Deref;
fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> { //~ ['a: o]
//~^ ERROR cannot capture higher-ranked lifetime
Box::new(x)
}

View file

@ -1,17 +1,17 @@
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
--> $DIR/implicit-capture-late.rs:10:55
--> $DIR/implicit-capture-late.rs:9:55
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
note: lifetime declared here
--> $DIR/implicit-capture-late.rs:10:36
--> $DIR/implicit-capture-late.rs:9:36
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^
error: ['a: o]
--> $DIR/implicit-capture-late.rs:10:55
--> $DIR/implicit-capture-late.rs:9:55
|
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^^^^^^^^^^

View file

@ -1,9 +1,8 @@
//@ check-pass
//@ edition: 2024
// Show how precise captures allow us to skip capturing a higher-ranked lifetime
#![feature(lifetime_capture_rules_2024)]
trait Trait<'a> {
type Item;
}

View file

@ -1,9 +1,8 @@
//@ check-pass
//@ edition: 2024
// Show that precise captures allow us to skip a lifetime param for outlives
#![feature(lifetime_capture_rules_2024)]
fn hello<'a: 'a, 'b: 'b>() -> impl Sized + use<'a> { }
fn outlives<'a, T: 'a>(_: T) {}

View file

@ -1,23 +1,23 @@
error: ['a: *, 'a: o]
--> $DIR/variance.rs:13:36
--> $DIR/variance.rs:11:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: ['a: *, 'a: o]
--> $DIR/variance.rs:18:32
--> $DIR/variance.rs:15:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: ['a: o]
--> $DIR/variance.rs:20:40
--> $DIR/variance.rs:17:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: ['a: o]
--> $DIR/variance.rs:25:36
--> $DIR/variance.rs:21:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,26 +0,0 @@
error: ['a: *, 'a: o]
--> $DIR/variance.rs:13:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: ['a: *, 'a: o]
--> $DIR/variance.rs:18:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: ['a: o]
--> $DIR/variance.rs:20:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: ['a: o]
--> $DIR/variance.rs:25:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors

View file

@ -1,23 +1,23 @@
error: ['a: *]
--> $DIR/variance.rs:13:36
--> $DIR/variance.rs:11:36
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: ['a: *, 'a: o]
--> $DIR/variance.rs:18:32
--> $DIR/variance.rs:15:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: []
--> $DIR/variance.rs:20:40
--> $DIR/variance.rs:17:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: ['a: o]
--> $DIR/variance.rs:25:36
--> $DIR/variance.rs:21:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,8 +1,6 @@
//@ revisions: old new e2024
//@ revisions: old e2024
//@[e2024] edition: 2024
#![cfg_attr(new, feature(lifetime_capture_rules_2024))]
#![feature(rustc_attrs)]
#![allow(internal_features)]
#![rustc_variance_of_opaques]
@ -12,15 +10,13 @@ impl<T> Captures<'_> for T {}
fn not_captured_early<'a: 'a>() -> impl Sized {}
//[old]~^ ['a: *]
//[new]~^^ ['a: *, 'a: o]
//[e2024]~^^^ ['a: *, 'a: o]
//[e2024]~^^ ['a: *, 'a: o]
fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o]
fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
//[old]~^ []
//[new]~^^ ['a: o]
//[e2024]~^^^ ['a: o]
//[e2024]~^^ ['a: o]
fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o]