Skip to content

<Box<T> as Deref>::Target is not equivalent to T in this case. #76956

Closed
@someguynamedjosh

Description

@someguynamedjosh

This code compiles correctly:

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

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

However, this code does not:

use std::ops::Deref;

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

impl Data {
    fn use_data(&self, user: impl for <'a> FnOnce(<Box<&'a i32> as Deref>::Target)) {
        user(*self.boxed)
    }
}

The only change was effectively replacing T with <Box<T> as Deref>::Target. My understanding is that these are supposed to be equivalent as it is defined that way in the standard library. The exact compile error is as follows:

error[E0308]: mismatched types
 --> src/main.rs:9:14
  |
9 |         user(*self.boxed)
  |              ^^^^^^^^^^^ expected associated type, found `&i32`
  |
  = note: expected associated type `<std::boxed::Box<&i32> as std::ops::Deref>::Target`
                   found reference `&'static i32`
  = help: consider constraining the associated type `<std::boxed::Box<&i32> as std::ops::Deref>::Target` to `&'static i32` or calling a method that returns `<std::boxed::Box<&i32> as std::ops::Deref>::Target`
  = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error[E0277]: expected a `std::ops::FnOnce<(&i32,)>` closure, found `impl for<'a> FnOnce(<Box<&'a i32> as Deref>::Target)`
 --> src/main.rs:9:9
  |
9 |         user(*self.boxed)
  |         ^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&i32,)>` closure, found `impl for<'a> FnOnce(<Box<&'a i32> as Deref>::Target)`
  |
  = help: the trait `std::ops::FnOnce<(&i32,)>` is not implemented for `impl for<'a> FnOnce(<Box<&'a i32> as Deref>::Target)`
help: consider further restricting this bound
  |
8 |     fn use_data(&self, user: impl for <'a> FnOnce(<Box<&'a i32> as Deref>::Target) + std::ops::FnOnce<(&i32,)>) {
  |                                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Meta

The error also occurs on the Nightly compiler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions