Mismatch reported for fn impl with HRTB lifetime without cast #112046
Description
type IntCallback = fn(&i32);
enum Callback {
Int(IntCallback)
}
impl Into<Callback> for for<'a> fn(&'a i32) {
fn into(self) -> Callback {
Callback::Int(self)
}
}
fn callback(_: &i32) {
}
fn main() {
let callback: Callback = callback.into();
}
I expected to see this happen: the impl for the fn pointer should be picked up and used.
Instead, this happened:
Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/nightly/error_codes/E0277.html): the trait bound `Callback: From<for<'a> fn(&'a i32) {callback}>` is not satisfied
--> src/main.rs:17:39
|
17 | let callback: Callback = callback.into();
| ^^^^ the trait `From<for<'a> fn(&'a i32) {callback}>` is not implemented for `Callback`
|
= help: the trait `Into<Callback>` is implemented for fn pointer `for<'a> fn(&'a i32)`, cast using `as`
= note: required for `for<'a> fn(&'a i32) {callback}` to implement `Into<Callback>`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to previous error
Since callback
can be passed directly to a function taking IntCallback
as a parameter, it should be possible for the existing From<>
impl to be used directly.
This makes it extremely verbose to use generic bounds to accept a callback:
fn callback(_: &i32) {
}
fn foo<C: Into<Callback>>(c: C) {
todo!();
}
fn main() {
foo(callback);
}
which returns
error[[E0277]](https://doc.rust-lang.org/nightly/error_codes/E0277.html): the trait bound `Callback: From<for<'a> fn(&'a i32) {callback}>` is not satisfied
--> src/main.rs:17:9
|
17 | foo(callback);
| --- ^^^^^^^^ the trait `From<for<'a> fn(&'a i32) {callback}>` is not implemented for `Callback`
| |
| required by a bound introduced by this call
|
= help: the trait `Into<Callback>` is implemented for fn pointer `for<'a> fn(&'a i32)`, cast using `as`
= note: required for `for<'a> fn(&'a i32) {callback}` to implement `Into<Callback>`
note: required by a bound in `foo`
--> src/main.rs:20:11
|
20 | fn foo<C: Into<Callback>>(c: C) {
| ^^^^^^^^^^^^^^ required by this bound in `foo`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to previous error
Playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c367afd81fc7219e802099735acc2507
Side note: the diagnostics for this have drastically improved in the latest nightlies. The nightly build I have installed didn't give me the "cast using as
" hint and instead said "type xxxx doesn't implement Foo, implemented for <same type xxxx>"
Meta
rustc --version --verbose
:
1.71.0-nightly (2023-05-27 cca7ee58110726983951)
Activity