Skip to content

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

Open
@JanBeh

Description

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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