Open steffahn opened 3 years ago
In this form
fn main() {
let x = Delegate(foo);
println!("{:?}", x);
}
fn foo(_: &String) {}
pub struct Delegate<T> (fn(Data: &T));
use std::fmt;
impl<T> fmt::Debug for Delegate<T> {
fn fmt<'a, 'b>(&'a self, f: &mut fmt::Formatter<'b>) -> std::fmt::Result {
f.debug_tuple("Delegate").field(&self.0 as &fn(&'a T)).finish()
}
}
this is a regression. The code does
Debug for fn(A) -> Ret
implementationDelegate(0x56416464b5e0)
)Encountered error `Unimplemented` selecting `Binder(<fn(&std::string::String) as std::fmt::Debug>)` during codegen
29ef6cf16 2021-08-31
) produce a linking error (like the one quoted in the original post)IMO arguable even two regressions: in 1.10
it stops to compile (that one’s old, admitted), and in 1.46
it stops producing an ICE (I prefer an ICE over a linking error: with an ICE the compiler at least admits that it’s doing something wrong and doesn’t pass invalid code to LLVM, and ultimately the linker).
@rustbot label regression-from-stable-to-stable, A-codegen
I am not sure if it adds any value, but when you 'forget' the & in the struct def. like this
pub struct Delegate<T>(fn(Data: T));
the linker does not crash. and program runs.
problem seems to be the Custom impl for debug
Working examples: https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=638ead9cbca8701ab3e5f73f3b84c6f0
Regards.
Remco
Using &(self.0 as fn(&'a T))
seems to get rid of the error, i.e.:
impl<T> fmt::Debug for Delegate<T> {
fn fmt<'a>(&'a self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Delegate")
.field(&(self.0 as fn(&'a T)))
.finish()
}
}
Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.
@rustbot label -I-prioritize +P-medium
Reduced example:
trait Trait {
fn method(&self);
}
impl<'a> Trait for fn(&'a ()) {
fn method(&self) {}
}
struct Struct(fn(&()));
impl Trait for Struct {
fn method<'a>(&'a self) {
let _x = &self.0 as &fn(&'a ()) as &dyn Trait;
}
}
fn main() {
let _x = Trait::method as fn(&Struct);
}
Further reduced:
trait Trait {}
impl Trait for fn(&'static ()) {}
fn main() {
let f: fn(&()) = |_| ();
let _x = &f as &fn(&'static ()) as &dyn Trait;
}
(playground)
@rustbot label T-compiler
Edit: In case that isn’t clear: I’m expecting the code to compile. The context is this thread on URLO.