Stream: t-compiler

Topic: PartialEq on for <'a> fn(&'a _) #46989


pnkfelix (Oct 07 2019 at 10:16, on Zulip):

I'd like to idly discuss this detail of our current std derives (or lack thereof) for for <'a> T ...

pnkfelix (Oct 07 2019 at 10:17, on Zulip):

a reasonably large set of people think behavior is unintuitive on this playpen

pnkfelix (Oct 07 2019 at 10:19, on Zulip):

hmm after thinking about it, I guess its hard/impossible to "just fix this" via hard-coding our own impls

pnkfelix (Oct 07 2019 at 10:21, on Zulip):

/me goes skimming code to figure out how we even impl PartialEq for fn in general

nikomatsakis (Oct 10 2019 at 14:54, on Zulip):

As we discussed together, @pnkfelix, something I've considered from time to time (and am still vaguely in favor of, presuming there is no complication) is creating a built-in "marker trait" called FnPointer, which is implemented for any fn(...) type (of any ABI etc). This trait might look something like:

#[fundamental]
trait FnPointer: Copy {
    fn as_pointer(self) -> *const ();
}

It would be built-in to the compiler and illegal to manually implement. The trait system would just hard-code it in a simple way.

I think this would allow us to do things like

impl<T: FnPointer> Clone for T { .. }
impl<T: FnPointer> PartialEq  for T { .. }
impl<T: FnPointer> Debug for T { .. }

and so forth. There may be some complications around fundamental that I'm not thinking of, though. Could be "prototyped" fairly easily I guess with just a regular trait that is impemented for fn(A), fn(A, B), etc.

pnkfelix (Oct 16 2019 at 10:11, on Zulip):

/me goes skimming code to figure out how we even impl PartialEq for fn in general

For those wondering where the code was, it is in src/libcore/ptr/mod.rs: https://github.com/rust-lang/rust/blob/master/src/libcore/ptr/mod.rs#L2801

pnkfelix (Oct 16 2019 at 10:13, on Zulip):

@nikomatsakis would your hypothetical trait FnPointer also get magically implemented by the type for <'a> fn(&'a u32), and for <'a> fn(ParameterizedOver<'a>) -> AlsoOver<'a>, etc ?

pnkfelix (Oct 16 2019 at 10:14, on Zulip):

(that bit of magic does not seem as "easy" to prototype)

pnkfelix (Oct 16 2019 at 10:16, on Zulip):

(but it does seem plausible to add support for this to the compiler. I.e. rustc presumably could dive into for <'a> ... (recursively over repeated for <'b> etc) until it find a fn-ptr and can then say "Okay, done, its an FnPointer!)

nikomatsakis (Oct 22 2019 at 12:59, on Zulip):

nikomatsakis would your hypothetical trait FnPointer also get magically implemented by the type for <'a> fn(&'a u32), and for <'a> fn(ParameterizedOver<'a>) -> AlsoOver<'a>, etc ?

I'm not sure what's hard about that, @pnkfelix

nikomatsakis (Oct 22 2019 at 12:59, on Zulip):

oh, for prototyping, you are saying

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

I mean the "prototype" would presuamably be implemented for fn(A), fn(A, B) etc

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

just as we do today for many traits

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

which means it wouldn't handle higher-ranked things

pnkfelix (Oct 22 2019 at 13:00, on Zulip):

which is the primary thing I think I want addressed here

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

I guess we probably do impl<A, R> Trait for fn(A) -> R or something now?

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

yeah so the point of prototyping would just be to check if the fundamental trait setup gives problems

nikomatsakis (Oct 22 2019 at 13:00, on Zulip):

the higher-ranked stuff would come from making it a lang item

pnkfelix (Oct 22 2019 at 13:00, on Zulip):

I guess that makes sense

pnkfelix (Oct 22 2019 at 13:01, on Zulip):

make sure the overall design doesnt have fundamntal problems before adding the new feature

Last update: Nov 16 2019 at 01:40UTC