Skip to content

HRTBs with two lifetimes: implementation is not general enough when impl uses lifetime bound #113967

@JanBeh

Description

@JanBeh

I tried this code:

fn foo<'a, 'b: 'a>(_arg: &'a &'b i32) {}

trait Trait<T> {
    fn method(&self, arg: T);
}

impl<'a, 'b> Trait<&'a &'b i32> for ()
where
    'b: 'a, // `main` compiles if this line is commented out
{
    fn method(&self, arg: &'a &'b i32) {
        foo(arg);
    }
}

fn works_fine1<'a, 'b>(arg: &'a &'b i32) { foo(arg) }
fn works_fine2<T: for<'a, 'b> FnMut(&'a &'b i32)>(_arg: T) {}
fn fails<T: for<'a, 'b> Trait<&'a &'b i32>>(_arg: T) {}

fn main() {
    works_fine1(&&0);
    works_fine2(|x| foo(x));
    fails(());
}

(Playground)

I expected the program to compile and run without errors because 'b: 'a irregardless of explicitly adding that bound (as shown by calling foo).

Instead, this compilation error occurred:

error: implementation of `Trait` is not general enough
  --> src/main.rs:23:5
   |
23 |     fails(());
   |     ^^^^^^^^^ implementation of `Trait` is not general enough
   |
   = note: `()` must implement `Trait<&'0 &'1 i32>`, for any two lifetimes `'0` and `'1`...
   = note: ...but it actually implements `Trait<&&'2 i32>`, for some specific lifetime `'2`

Minimal example:

trait Trait<T> {}
impl<'a, 'b: 'a> Trait<&'a &'b i32> for () {}

fn fails<T: for<'a, 'b> Trait<&'a &'b i32>>(_arg: T) {}

fn main() {
    fails(());
}

(Playground)

The minimal example will compile if we replace:

-impl<'a, 'b: 'a> Trait<&'a &'b i32> for () {}
+impl<'a, 'b> Trait<&'a &'b i32> for () {}

Meta

rustc --version --verbose:

rustc 1.73.0-nightly (0308df23e 2023-07-21)
binary: rustc
commit-hash: 0308df23e621e783e31a27ca5beaa01b9df60d4a
commit-date: 2023-07-21
host: x86_64-unknown-freebsd
release: 1.73.0-nightly
LLVM version: 16.0.5

See also

See also: Why can’t I use lifetime bounds in HRTBs? on URLO.

I ran into that problem in a PR #1048 for regex where it wasn't trivial to work around. See also comment below in that matter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions