Closed as duplicate of#58052
Description
I tried this code:
struct Foo<A, B>(A, B);
#[allow(non_camel_case_types, dead_code)]
trait Fn_require_outlives_in_method<A, B> {
// a for<'a> alternative that is type checked
// at the call site
fn call<'a>(self, value: &'a A) -> &'a B;
}
// impl the trait for FnOnce(&A) -> &B
impl<A, B, F: for<'a> FnOnce(&'a A) -> &'a B /* where A: 'a, B: 'a (trivial bounds) */>
Fn_require_outlives_in_method<A, B> for F {
#[inline(always)]
fn call<'a>(self, value: &'a A) -> &'a B {
self(value)
}
}
impl<A, B> Foo<A, B> {
fn new(_value: A, _callback: impl Fn_require_outlives_in_method<A, B>) -> Self {
todo!()
}
}
fn check_fn_once_impl_universal_over_lifetime_a(_: impl for<'a> FnOnce(&'a i32) -> &'a i32) {}
fn main() {
Foo::new(0, |e| e);
}
I expected to see this happen: compiles
Instead, this happened:
error: implementation of `FnOnce` is not general enough
--> src/main.rs:28:5
|
28 | Foo::new(0, |e| e);
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 i32) -> &i32` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2`
Other examples with comments:
fn check_fn_once_impl_universal_over_lifetime_a(_: impl for<'a> FnOnce(&'a i32) -> &'a i32) {}
fn main() {
fn test(e: &i32) -> &i32 { e }
// Foo::new(0, |e| e); // fails to compile (not general enough)
// Foo::<i32, i32>::new(0, |e| e); // fails to compile (not general enough)
check_fn_once_impl_universal_over_lifetime_a(|e| e); // ok
Foo::new(0, for<'a> |e: &'a i32| -> &'a i32 { e }); // ok (experimental)
Foo::new(0, test); // ok
}
Meta
rustc --version --verbose
:
rustc 1.87.0-nightly (75530e9f7 2025-03-18)
binary: rustc
commit-hash: 75530e9f72a1990ed2305e16fd51d02f47048f12
commit-date: 2025-03-18
host: aarch64-apple-darwin
release: 1.87.0-nightly
LLVM version: 20.1.0
Backtrace