Stabilize precise_capturing_in_traits

This commit is contained in:
Michael Goulet
2025-03-06 20:50:51 +00:00
parent 97fc1f62d8
commit eb3707e4b4
24 changed files with 22 additions and 91 deletions

View File

@@ -141,9 +141,6 @@ ast_lowering_never_pattern_with_guard =
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait` ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
ast_lowering_no_precise_captures_on_rpitit = `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
.note = currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
ast_lowering_previously_used_here = previously used here ast_lowering_previously_used_here = previously used here
ast_lowering_register1 = register `{$reg1_name}` ast_lowering_register1 = register `{$reg1_name}`

View File

@@ -444,14 +444,6 @@ pub(crate) struct NoPreciseCapturesOnApit {
pub span: Span, pub span: Span,
} }
#[derive(Diagnostic)]
#[diag(ast_lowering_no_precise_captures_on_rpitit)]
#[note]
pub(crate) struct NoPreciseCapturesOnRpitit {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(ast_lowering_yield_in_closure)] #[diag(ast_lowering_yield_in_closure)]
pub(crate) struct YieldInClosure { pub(crate) struct YieldInClosure {

View File

@@ -1438,28 +1438,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show. // frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
// Feature gate for RPITIT + use<..>
match origin {
rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
if !self.tcx.features().precise_capturing_in_traits()
&& let Some(span) = bounds.iter().find_map(|bound| match *bound {
ast::GenericBound::Use(_, span) => Some(span),
_ => None,
})
{
let mut diag =
self.tcx.dcx().create_err(errors::NoPreciseCapturesOnRpitit { span });
add_feature_diagnostics(
&mut diag,
self.tcx.sess,
sym::precise_capturing_in_traits,
);
diag.emit();
}
}
_ => {}
}
self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| { self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
this.lower_param_bounds(bounds, itctx) this.lower_param_bounds(bounds, itctx)
}) })

View File

@@ -331,6 +331,8 @@ declare_features! (
(accepted, pattern_parentheses, "1.31.0", Some(51087)), (accepted, pattern_parentheses, "1.31.0", Some(51087)),
/// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args.
(accepted, precise_capturing, "1.82.0", Some(123432)), (accepted, precise_capturing, "1.82.0", Some(123432)),
/// Allows `use<..>` precise capturign on impl Trait in traits.
(accepted, precise_capturing_in_traits, "CURRENT_RUSTC_VERSION", Some(130044)),
/// Allows procedural macros in `proc-macro` crates. /// Allows procedural macros in `proc-macro` crates.
(accepted, proc_macro, "1.29.0", Some(38356)), (accepted, proc_macro, "1.29.0", Some(38356)),
/// Allows multi-segment paths in attributes and derives. /// Allows multi-segment paths in attributes and derives.

View File

@@ -600,8 +600,6 @@ declare_features! (
(incomplete, pin_ergonomics, "1.83.0", Some(130494)), (incomplete, pin_ergonomics, "1.83.0", Some(130494)),
/// Allows postfix match `expr.match { ... }` /// Allows postfix match `expr.match { ... }`
(unstable, postfix_match, "1.79.0", Some(121618)), (unstable, postfix_match, "1.79.0", Some(121618)),
/// Allows `use<..>` precise capturign on impl Trait in traits.
(unstable, precise_capturing_in_traits, "1.83.0", Some(130044)),
/// Allows macro attributes on expressions, statements and non-inline modules. /// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)), (unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows the use of raw-dylibs on ELF platforms /// Allows the use of raw-dylibs on ELF platforms

View File

@@ -1,6 +0,0 @@
trait Foo {
fn test() -> impl Sized + use<Self>;
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position
}
fn main() {}

View File

@@ -1,13 +0,0 @@
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
--> $DIR/feature-gate-precise_capturing_in_traits.rs:2:31
|
LL | fn test() -> impl Sized + use<Self>;
| ^^^^^^^^^
|
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error

View File

@@ -1,6 +1,6 @@
//@ compile-flags: -Zverbose-internals //@ compile-flags: -Zverbose-internals
#![feature(precise_capturing_in_traits, rustc_attrs)] #![feature(rustc_attrs)]
#![rustc_hidden_type_of_opaques] #![rustc_hidden_type_of_opaques]
trait Foo { trait Foo {

View File

@@ -1,5 +1,3 @@
#![feature(precise_capturing_in_traits)]
trait LifetimeParam<'a> { trait LifetimeParam<'a> {
fn test() -> impl Sized; fn test() -> impl Sized;
} }

View File

@@ -1,5 +1,5 @@
warning: impl trait in impl method captures fewer lifetimes than in trait warning: impl trait in impl method captures fewer lifetimes than in trait
--> $DIR/refine-captures.rs:8:31 --> $DIR/refine-captures.rs:6:31
| |
LL | fn test() -> impl Sized + use<> {} LL | fn test() -> impl Sized + use<> {}
| ^^^^^ | ^^^^^
@@ -13,7 +13,7 @@ LL | fn test() -> impl Sized + use<'a> {}
| ++ | ++
warning: impl trait in impl method captures fewer lifetimes than in trait warning: impl trait in impl method captures fewer lifetimes than in trait
--> $DIR/refine-captures.rs:22:31 --> $DIR/refine-captures.rs:20:31
| |
LL | fn test() -> impl Sized + use<> {} LL | fn test() -> impl Sized + use<> {}
| ^^^^^ | ^^^^^
@@ -26,7 +26,7 @@ LL | fn test() -> impl Sized + use<'a> {}
| ++ | ++
warning: impl trait in impl method captures fewer lifetimes than in trait warning: impl trait in impl method captures fewer lifetimes than in trait
--> $DIR/refine-captures.rs:27:31 --> $DIR/refine-captures.rs:25:31
| |
LL | fn test() -> impl Sized + use<'b> {} LL | fn test() -> impl Sized + use<'b> {}
| ^^^^^^^ | ^^^^^^^
@@ -39,7 +39,7 @@ LL | fn test() -> impl Sized + use<'a, 'b> {}
| ++++ | ++++
error: `impl Trait` must mention all type parameters in scope in `use<...>` error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/refine-captures.rs:32:18 --> $DIR/refine-captures.rs:30:18
| |
LL | impl<T> TypeParam<T> for u64 { LL | impl<T> TypeParam<T> for u64 {
| - type parameter is implicitly captured by this `impl Trait` | - type parameter is implicitly captured by this `impl Trait`

View File

@@ -1,4 +1,4 @@
#![feature(rustc_attrs, precise_capturing_in_traits)] #![feature(rustc_attrs)]
#![allow(internal_features)] #![allow(internal_features)]
#![rustc_variance_of_opaques] #![rustc_variance_of_opaques]

View File

@@ -1,5 +1,3 @@
#![feature(precise_capturing_in_traits)]
fn type_param<T>() -> impl Sized + use<> {} fn type_param<T>() -> impl Sized + use<> {}
//~^ ERROR `impl Trait` must mention all type parameters in scope //~^ ERROR `impl Trait` must mention all type parameters in scope

View File

@@ -1,5 +1,5 @@
error: `impl Trait` must mention all type parameters in scope in `use<...>` error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-type.rs:3:23 --> $DIR/forgot-to-capture-type.rs:1:23
| |
LL | fn type_param<T>() -> impl Sized + use<> {} LL | fn type_param<T>() -> impl Sized + use<> {}
| - ^^^^^^^^^^^^^^^^^^ | - ^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | fn type_param<T>() -> impl Sized + use<> {}
= note: currently, all type parameters are required to be mentioned in the precise captures list = note: currently, all type parameters are required to be mentioned in the precise captures list
error: `impl Trait` must mention the `Self` type of the trait in `use<...>` error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
--> $DIR/forgot-to-capture-type.rs:7:17 --> $DIR/forgot-to-capture-type.rs:5:17
| |
LL | trait Foo { LL | trait Foo {
| --------- `Self` type parameter is implicitly captured by this `impl Trait` | --------- `Self` type parameter is implicitly captured by this `impl Trait`

View File

@@ -1,6 +1,5 @@
//@ edition: 2024 //@ edition: 2024
#![feature(precise_capturing_in_traits)]
#![deny(impl_trait_redundant_captures)] #![deny(impl_trait_redundant_captures)]
fn hello<'a>() -> impl Sized + use<'a> {} fn hello<'a>() -> impl Sized + use<'a> {}

View File

@@ -1,5 +1,5 @@
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:6:19 --> $DIR/redundant.rs:5:19
| |
LL | fn hello<'a>() -> impl Sized + use<'a> {} LL | fn hello<'a>() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^------- | ^^^^^^^^^^^^^-------
@@ -7,13 +7,13 @@ LL | fn hello<'a>() -> impl Sized + use<'a> {}
| help: remove the `use<...>` syntax | help: remove the `use<...>` syntax
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/redundant.rs:4:9 --> $DIR/redundant.rs:3:9
| |
LL | #![deny(impl_trait_redundant_captures)] LL | #![deny(impl_trait_redundant_captures)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:11:27 --> $DIR/redundant.rs:10:27
| |
LL | fn inherent(&self) -> impl Sized + use<'_> {} LL | fn inherent(&self) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^------- | ^^^^^^^^^^^^^-------
@@ -21,7 +21,7 @@ LL | fn inherent(&self) -> impl Sized + use<'_> {}
| help: remove the `use<...>` syntax | help: remove the `use<...>` syntax
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:16:22 --> $DIR/redundant.rs:15:22
| |
LL | fn in_trait() -> impl Sized + use<'a, Self>; LL | fn in_trait() -> impl Sized + use<'a, Self>;
| ^^^^^^^^^^^^^------------- | ^^^^^^^^^^^^^-------------
@@ -29,7 +29,7 @@ LL | fn in_trait() -> impl Sized + use<'a, Self>;
| help: remove the `use<...>` syntax | help: remove the `use<...>` syntax
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
--> $DIR/redundant.rs:20:22 --> $DIR/redundant.rs:19:22
| |
LL | fn in_trait() -> impl Sized + use<'a> {} LL | fn in_trait() -> impl Sized + use<'a> {}
| ^^^^^^^^^^^^^------- | ^^^^^^^^^^^^^-------

View File

@@ -2,8 +2,6 @@
// trait definition, which is not allowed. Due to the default lifetime capture // trait definition, which is not allowed. Due to the default lifetime capture
// rules of RPITITs, this is only doable if we use precise capturing. // rules of RPITITs, this is only doable if we use precise capturing.
#![feature(precise_capturing_in_traits)]
pub trait Foo { pub trait Foo {
fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>; fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
} }

View File

@@ -1,5 +1,5 @@
error: return type captures more lifetimes than trait definition error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-captures-more-method-lifetimes.rs:12:40 --> $DIR/rpitit-captures-more-method-lifetimes.rs:10:40
| |
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {} LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
| --- ^^^^^^^^^^^^^^^^^^^^^ | --- ^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
| this lifetime was captured | this lifetime was captured
| |
note: hidden type must only reference lifetimes captured by this impl trait note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-captures-more-method-lifetimes.rs:8:40 --> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
| |
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>; LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -1,5 +1,3 @@
#![feature(precise_capturing_in_traits)]
struct Invariant<'a>(&'a mut &'a mut ()); struct Invariant<'a>(&'a mut &'a mut ());
trait Trait { trait Trait {

View File

@@ -1,5 +1,5 @@
error: return type captures more lifetimes than trait definition error: return type captures more lifetimes than trait definition
--> $DIR/rpitit-impl-captures-too-much.rs:10:39 --> $DIR/rpitit-impl-captures-too-much.rs:8:39
| |
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>; LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
| -- this lifetime was captured | -- this lifetime was captured
@@ -8,7 +8,7 @@ LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
| |
note: hidden type must only reference lifetimes captured by this impl trait note: hidden type must only reference lifetimes captured by this impl trait
--> $DIR/rpitit-impl-captures-too-much.rs:6:39 --> $DIR/rpitit-impl-captures-too-much.rs:4:39
| |
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>; LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -2,8 +2,6 @@
// Ensure that we skip uncaptured args from RPITITs when comptuing outlives. // Ensure that we skip uncaptured args from RPITITs when comptuing outlives.
#![feature(precise_capturing_in_traits)]
struct Invariant<T>(*mut T); struct Invariant<T>(*mut T);
trait Foo { trait Foo {

View File

@@ -3,8 +3,6 @@
// Ensure that we skip uncaptured args from RPITITs when collecting the regions // Ensure that we skip uncaptured args from RPITITs when collecting the regions
// to enforce member constraints in opaque type inference. // to enforce member constraints in opaque type inference.
#![feature(precise_capturing_in_traits)]
struct Invariant<T>(*mut T); struct Invariant<T>(*mut T);
trait Foo { trait Foo {

View File

@@ -3,8 +3,6 @@
// To fix this soundly, we need to make sure that all the trait header args // To fix this soundly, we need to make sure that all the trait header args
// remain captured, since they affect trait selection. // remain captured, since they affect trait selection.
#![feature(precise_capturing_in_traits)]
fn eq_types<T>(_: T, _: T) {} fn eq_types<T>(_: T, _: T) {}
trait TraitLt<'a: 'a> { trait TraitLt<'a: 'a> {

View File

@@ -1,5 +1,5 @@
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
--> $DIR/rpitit.rs:11:19 --> $DIR/rpitit.rs:9:19
| |
LL | trait TraitLt<'a: 'a> { LL | trait TraitLt<'a: 'a> {
| -- all lifetime parameters originating from a trait are captured implicitly | -- all lifetime parameters originating from a trait are captured implicitly
@@ -7,7 +7,7 @@ LL | fn hello() -> impl Sized + use<Self>;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/rpitit.rs:15:5 --> $DIR/rpitit.rs:13:5
| |
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () { LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
| -- -- lifetime `'b` defined here | -- -- lifetime `'b` defined here
@@ -24,7 +24,7 @@ LL | | );
= help: consider adding the following bound: `'a: 'b` = help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/rpitit.rs:15:5 --> $DIR/rpitit.rs:13:5
| |
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () { LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
| -- -- lifetime `'b` defined here | -- -- lifetime `'b` defined here

View File

@@ -1,7 +1,5 @@
//@ check-pass //@ check-pass
#![feature(precise_capturing_in_traits)]
trait Foo { trait Foo {
fn bar<'a>() -> impl Sized + use<Self>; fn bar<'a>() -> impl Sized + use<Self>;
} }