HRTBs with two lifetimes: implementation is not general enough when impl uses lifetime bound #113967
Open
Description
opened on Jul 22, 2023
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(());
}
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(());
}
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