Why does this not compile? Box<T>::Target != T?

This code compiles fine:

use std::ops::Deref;

struct Data {
    boxed: Box<&'static i32>

impl Data {
    fn use_data(&self, user: impl for <'a> FnOnce(&'a i32)) {

However, modifying the definition of user with this will cause the compilation to fail:

user: impl for <'a> FnOnce(<Box<&'a i32> as Deref>::Target)
// instead of   for <'a> FnOnce(&'a i32)

This does not make sense to me as it is my understanding that <Box<T> as Deref>::Target should be identical to T. What am I missing in this example?

1 Like
    fn use_data(
        user: impl for<'a> FnOnce(<Box<&'a i32> as Deref>::Target) + std::ops::FnOnce(&i32),
    ) {

Why is it necessary to add that? The example I gave is being used in a context where the T of Box<T> won't be known ahead of time so I can't manually add the + FnOnce(&i32). I want to understand why <Box<T> as Deref>::Target is not equivalent to T in the first place.

Without high rank trait bounds it equivalent:

fn use_data<'a>(&self, user: impl FnOnce(<Box<&'a i32> as Deref>::Target)) {


Yeah, that seems like it should be equivalent. I've opened an issue.

Upon researching more, it seems 'a as a template parameter is not equivalent to for<'a>. The template form means that the function has to work for a specific lifetime 'a which is specified when the function is called. The for form is a higher-rank trait bound, meaning the function has to work for any possible lifetime 'a, you cannot pass a function which will only work for a specific lifetime.

I'm still uncertain as to why the original discrepancy exists though, as both versions use for<'a>.


You are hitting a current limitation of the type-checker when dealing with higher-order lifetimes. Very annoying limitation indeed.

I expect this will be "fixed" / supporting this will be implemented by the time GATs want to go stable, since it will otherwise be quite frustrating to work with them.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.