Rollup merge of #138128 - compiler-errors:precise-capturing-in-traits, r=oli-obk,traviscross
Stabilize `#![feature(precise_capturing_in_traits)]` # Precise capturing (`+ use<>` bounds) in traits - Stabilization Report Fixes https://github.com/rust-lang/rust/issues/130044. ## Stabilization summary This report proposes the stabilization of `use<>` precise capturing bounds in return-position impl traits in traits (RPITITs). This completes a missing part of [RFC 3617 "Precise capturing"]. Precise capturing in traits was not ready for stabilization when the first subset was proposed for stabilization (namely, RPITs on free and inherent functions - https://github.com/rust-lang/rust/pull/127672) since this feature has a slightly different implementation, and it hadn't yet been implemented or tested at the time. It is now complete, and the type system implications of this stabilization are detailed below. ## Motivation Currently, RPITITs capture all in-scope lifetimes, according to the decision made in the ["lifetime capture rules 2024" RFC](https://rust-lang.github.io/rfcs/3498-lifetime-capture-rules-2024.html#return-position-impl-trait-in-trait-rpitit). However, traits can be designed such that some lifetimes in arguments may not want to be captured. There is currently no way to express this. ## Major design decisions since the RFC No major decisions were made. This is simply an extension to the RFC that was understood as a follow-up from the original stabilization. ## What is stabilized? Users may write `+ use<'a, T>` bounds on their RPITITs. This conceptually modifies the desugaring of the RPITIT to omit the lifetimes that we would copy over from the method. For example, ```rust trait Foo { fn method<'a>(&'a self) -> impl Sized; // ... desugars to something like: type RPITIT_1<'a>: Sized; fn method_desugared<'a>(&'a self) -> Self::RPITIT_1<'a>; // ... whereas with precise capturing ... fn precise<'a>(&'a self) -> impl Sized + use<Self>; // ... desugars to something like: type RPITIT_2: Sized; fn precise_desugared<'a>(&'a self) -> Self::RPITIT_2; } ``` And thus the GAT doesn't name `'a`. In the compiler internals, it's not implemented exactly like this, but not in a way that users should expect to be able to observe. #### Limitations on what generics must be captured Currently, we require that all generics from the trait (including the `Self`) type are captured. This is because the generics from the trait are required to be *invariant* in order to do associated type normalization. And like regular precise capturing bounds, all type and const generics in scope must be captured. Thus, only the in-scope method lifetimes may be relaxed with this syntax today. ## What isn't stabilized? (a.k.a. potential future work) See section above. Relaxing the requirement to capture all type and const generics in scope may be relaxed when https://github.com/rust-lang/rust/issues/130043 is implemented, however it currently interacts with some underexplored corners of the type system (e.g. unconstrained type bivariance) so I don't expect it to come soon after. ## Implementation summary This functionality is implemented analogously to the way that *opaque type* precise capturing works. Namely, we currently use *variance* to model the capturedness of lifetimes. However, since RPITITs are anonymous GATs instead of opaque types, we instead modify the type relation of GATs to consider variances for RPITITs (along with opaque types which it has done since https://github.com/rust-lang/rust/pull/103491).30f168ef81/compiler/rustc_middle/src/ty/util.rs (L954-L976)
30f168ef81/compiler/rustc_type_ir/src/relate.rs (L240-L244)
Using variance to model capturedness is an implementation detail, and in the future it would be desirable if opaques and RPITITs simply did not include the uncaptured lifetimes in their generics. This can be changed in a forwards-compatible way, and almost certainly would not be observable by users (at least not negatively, since it may indeed fix some bugs along the way). ## Tests * Test that the lifetime isn't actually captured: `tests/ui/impl-trait/precise-capturing/rpitit.rs` and `tests/ui/impl-trait/precise-capturing/rpitit-outlives.rs` and `tests/ui/impl-trait/precise-capturing/rpitit-outlives-2.rs`. * Technical test for variance computation: `tests/ui/impl-trait/in-trait/variance.rs`. * Test that you must capture all trait generics: `tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs`. * Test that you cannot capture more than what the trait specifies: `tests/ui/impl-trait/precise-capturing/rpitit-captures-more-method-lifetimes.rs` and `tests/ui/impl-trait/precise-capturing/rpitit-impl-captures-too-much.rs`. * Undercapturing (refinement) lint: `tests/ui/impl-trait/in-trait/refine-captures.rs`. ### What other unstable features may be exposed by this feature? I don't believe that this exposes any new unstable features indirectly. ## Remaining bugs and open issues Not aware of any open issues or bugs. ## Tooling support Rustfmt: ✅ Supports formatting `+ use<>` everywhere. Clippy: ✅ No support needed, unless specific clippy lints are impl'd to care for precise capturing itself. Rustdoc: ✅ Rendering `+ use<>` precise capturing bounds is supported. Rust-analyzer: ✅ Parser support, and then lifetime support isn't needed https://github.com/rust-lang/rust/pull/138128#issuecomment-2705292494 (previous: ~~❓ There is parser support, but I am unsure of rust-analyzer's level of support for RPITITs in general.~~) ## History Tracking issue: https://github.com/rust-lang/rust/issues/130044 * https://github.com/rust-lang/rust/pull/131033 * https://github.com/rust-lang/rust/pull/132795 * https://github.com/rust-lang/rust/pull/136554
This commit is contained in:
commit
1c84c063f0
24 changed files with 22 additions and 91 deletions
|
@ -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}`
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -1440,28 +1440,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)
|
||||||
})
|
})
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {}
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![feature(precise_capturing_in_traits)]
|
|
||||||
|
|
||||||
trait LifetimeParam<'a> {
|
trait LifetimeParam<'a> {
|
||||||
fn test() -> impl Sized;
|
fn test() -> impl Sized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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> {}
|
||||||
|
|
|
@ -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> {}
|
||||||
| ^^^^^^^^^^^^^-------
|
| ^^^^^^^^^^^^^-------
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue