Open
Description
Code
// Slightly modified from tests/ui/impl-trait/issues/issue-54895.rs
trait Trait<'a> {
type Out;
fn call(&'a self) -> Self::Out;
}
struct X(());
impl<'a> Trait<'a> for X {
type Out = ();
fn call(&'a self) -> Self::Out {
()
}
}
fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
//[edition2024]~^^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
X(())
}
fn main() {
let _ = f();
}
Current output
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> tests/ui/impl-trait/issues/issue-54895.rs:18:44
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^^^^^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
note: lifetime declared here
--> tests/ui/impl-trait/issues/issue-54895.rs:18:24
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> tests/ui/impl-trait/issues/issue-54895.rs:18:44
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^^^^^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope
|
note: lifetime declared here
--> tests/ui/impl-trait/issues/issue-54895.rs:18:20
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> tests/ui/impl-trait/issues/issue-54895.rs:18:57
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
|
note: lifetime declared here
--> tests/ui/impl-trait/issues/issue-54895.rs:18:20
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> tests/ui/impl-trait/issues/issue-54895.rs:18:62
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
|
note: lifetime declared here
--> tests/ui/impl-trait/issues/issue-54895.rs:18:24
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^
error: aborting due to 4 previous errors
Desired output
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> tests/ui/impl-trait/issues/issue-54895.rs:18:44
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^^^^^^^^^ ^^ ^^
| |
| `impl Trait` implicitly captures all lifetimes in scope
note: captured lifetimes declared here
--> tests/ui/impl-trait/issues/issue-54895.rs:18:24
|
18 | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> {
| ^^ ^^
error: aborting due to 1 previous error
Rationale and extra context
In the example we're emitting 4 errors when a single one would suffice. In ediiton 2024, implicit captures cause two errors per lifetime, one pointing at the whole impl Trait + 'lt
and another pointing at the 'lt
. This gets repeated for each lifetime involved. Deduplication doesn't happen first because the primary span is different, and later because the "lifetime declared here" span points to a different one each time. It might be reasonable to not mention the implicit lifetime captures if there's an explicit one causing an error already.
Other cases
Rust Version
rustc 1.90.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.90.0-dev
LLVM version: 20.1.7
Anything else?
Noticed while working on #142255.
Metadata
Metadata
Assignees
Labels
Area: Messages for errors, warnings, and lintsArea: The 2024 editionArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: Lifetimes / regionsDiagnostics: Too much output caused by a single piece of incorrect code.Relevant to the compiler team, which will review and decide on the PR/issue.