forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#132795 - compiler-errors:refine-rpitit, r=lcnr Check `use<..>` in RPITIT for refinement `#![feature(precise_capturing_in_traits)]` allows users to write `+ use<>` bounds on RPITITs to control what lifetimes are captured by the RPITIT. Since RPITITs currently also warn for refinement in implementations, this PR extends that refinement check for cases where we *undercapture* in an implementation, since that may be indirectly "promising" a more relaxed outlives bound than the impl author intended. For an opaque to be refining, we need to capture *fewer* parameters than those mentioned in the captured params of the trait. For example: ``` trait TypeParam<T> { fn test() -> impl Sized; } // Indirectly capturing a lifetime param through a type param substitution. impl<'a> TypeParam<&'a ()> for i32 { fn test() -> impl Sized + use<> {} //~^ WARN impl trait in impl method captures fewer lifetimes than in trait } ``` Since the opaque in the method (implicitly) captures `use<Self, T>`, and `Self = i32, T = &'a ()` in the impl, we must mention `'a` in our `use<..>` on the impl. Tracking: * rust-lang#130044
- Loading branch information
Showing
5 changed files
with
204 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#![feature(precise_capturing_in_traits)] | ||
|
||
trait LifetimeParam<'a> { | ||
fn test() -> impl Sized; | ||
} | ||
// Refining via capturing fewer lifetimes than the trait definition. | ||
impl<'a> LifetimeParam<'a> for i32 { | ||
fn test() -> impl Sized + use<> {} | ||
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait | ||
} | ||
// If the lifetime is substituted, then we don't refine anything. | ||
impl LifetimeParam<'static> for u32 { | ||
fn test() -> impl Sized + use<> {} | ||
// Ok | ||
} | ||
|
||
trait TypeParam<T> { | ||
fn test() -> impl Sized; | ||
} | ||
// Indirectly capturing a lifetime param through a type param substitution. | ||
impl<'a> TypeParam<&'a ()> for i32 { | ||
fn test() -> impl Sized + use<> {} | ||
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait | ||
} | ||
// Two of them, but only one is captured... | ||
impl<'a, 'b> TypeParam<(&'a (), &'b ())> for u32 { | ||
fn test() -> impl Sized + use<'b> {} | ||
//~^ WARN impl trait in impl method captures fewer lifetimes than in trait | ||
} | ||
// What if we don't capture a type param? That should be an error otherwise. | ||
impl<T> TypeParam<T> for u64 { | ||
fn test() -> impl Sized + use<> {} | ||
//~^ ERROR `impl Trait` must mention all type parameters in scope in `use<...>` | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
warning: impl trait in impl method captures fewer lifetimes than in trait | ||
--> $DIR/refine-captures.rs:8:31 | ||
| | ||
LL | fn test() -> impl Sized + use<> {} | ||
| ^^^^^ | ||
| | ||
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate | ||
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information | ||
= note: `#[warn(refining_impl_trait_internal)]` on by default | ||
help: modify the `use<..>` bound to capture the same lifetimes that the trait does | ||
| | ||
LL | fn test() -> impl Sized + use<'a> {} | ||
| ~~~~~~~ | ||
|
||
warning: impl trait in impl method captures fewer lifetimes than in trait | ||
--> $DIR/refine-captures.rs:22:31 | ||
| | ||
LL | fn test() -> impl Sized + use<> {} | ||
| ^^^^^ | ||
| | ||
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate | ||
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information | ||
help: modify the `use<..>` bound to capture the same lifetimes that the trait does | ||
| | ||
LL | fn test() -> impl Sized + use<'a> {} | ||
| ~~~~~~~ | ||
|
||
warning: impl trait in impl method captures fewer lifetimes than in trait | ||
--> $DIR/refine-captures.rs:27:31 | ||
| | ||
LL | fn test() -> impl Sized + use<'b> {} | ||
| ^^^^^^^ | ||
| | ||
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate | ||
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information | ||
help: modify the `use<..>` bound to capture the same lifetimes that the trait does | ||
| | ||
LL | fn test() -> impl Sized + use<'a, 'b> {} | ||
| ~~~~~~~~~~~ | ||
|
||
error: `impl Trait` must mention all type parameters in scope in `use<...>` | ||
--> $DIR/refine-captures.rs:32:18 | ||
| | ||
LL | impl<T> TypeParam<T> for u64 { | ||
| - type parameter is implicitly captured by this `impl Trait` | ||
LL | fn test() -> impl Sized + use<> {} | ||
| ^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: currently, all type parameters are required to be mentioned in the precise captures list | ||
|
||
error: aborting due to 1 previous error; 3 warnings emitted | ||
|