Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deriving(Eq) requires Eq for type parameter even when phantom #7671

Closed
kmcallister opened this issue Jul 9, 2013 · 8 comments
Closed

deriving(Eq) requires Eq for type parameter even when phantom #7671

kmcallister opened this issue Jul 9, 2013 · 8 comments
Labels
A-syntaxext Area: Syntax extensions

Comments

@kmcallister
Copy link
Contributor

Code:

#[deriving(Eq)]
struct Foo<T> {
    x: int,
}

struct Phantom;

fn main() {
    let x : Foo<Phantom> = Foo { x: 0 };
    println((x == x).to_str());
}

Result:

$ rust -v
rust 0.7 (a2db7c1 2013-07-02 09:25:44 -0700)
host: x86_64-unknown-linux-gnu
$ rust run foo.rs 
foo.rs:10:13: 10:19 error: failed to find an implementation of trait std::cmp::Eq for Phantom
foo.rs:10     println((x == x).to_str());
@mstewartgallus
Copy link
Contributor

This issue is more general than just that deriving Eq requires an Eq bound. As well, deriving Clone requires a Clone bound on all template type parameters.

@huonw
Copy link
Member

huonw commented Jul 19, 2013

This could possibly be controlled by, e.g., #[deriving(phantom="T", Eq, Ord)]. (At the moment, just #[deriving] the trait on the phantom type itself will mostly work.)

@glaebhoerl
Copy link
Contributor

The Eq bound should be required for the types it's actually used with in the derived impl (similarly for Clone etc.). I don't see why this couldn't be determined programmatically (Haskell does it). And then there's no need for a redundant programmer-provided annotation.

@huonw
Copy link
Member

huonw commented Jul 19, 2013

I think Haskell's deriving is built into the type system more strongly than Rust's, which is just a standard syntax extension (it runs on exactly the same code as fmt! and fail!, just deriving is "executed" by being an attribute) and syntax extensions don't have access to type information; so, at the moment, it seems highly unlikely for a fully general programmatic solution to work, unless one pushes deriving deeper into the compiler itself.

@huonw
Copy link
Member

huonw commented Jun 16, 2014

triage: no change.

@cristicbz
Copy link
Contributor

This hit me today with:

#[derive(Debug)] struct Foo;
struct Bar;

#[derive(Debug)] struct Baz<T>(u64);

fn main() {
    println!("{:?}", Baz::<Foo>(10));
    println!("{:?}", Baz::<Bar>(10));  // Does not compile.
}

@Kimundi
Copy link
Member

Kimundi commented Feb 5, 2015

Now that Rust has where clauses, this could probably be resolved by emitting a where clause for each field of a struct that contains a type parameter:

struct NoClone;
struct Foo<A, B, C> {
    a: u8,
    b: Option<B>,
    c: C
}

// CURRENT, wrong way to implement clone in deriving
impl<A: Clone, B: Clone, C: Clone> Clone for Foo<A, B, C> {
    fn clone(&self) -> Self {
        Foo {
            a: Clone::clone(&self.a),
            b: Clone::clone(&self.b),
            c: Clone::clone(&self.c),
        }
    }
}

// NEW, Right way to implement clone in deriving
impl<A, B, C> Clone for Foo<A, B, C> where Option<B>: Clone,
                                           C: Clone {
    fn clone(&self) -> Self {
        Foo {
            a: Clone::clone(&self.a),
            b: Clone::clone(&self.b),
            c: Clone::clone(&self.c),
        }
    }
}

fn main() {
   let t: Foo<NoClone, String, &'static str> = Foo { a: 0, b: None, c: "foo" };
   let _ = t.clone();
}

This should be implementable on a purely syntactic level.

@goffrie
Copy link
Contributor

goffrie commented Feb 6, 2015

The above is implemented in #21237, but unfortunately it seems to have a problem: what if a type inside the struct is private? You can't put a bound on a private type on the trait impl, because the user of your crate (say) doesn't know what impls exist for the private type :(

edit: hm, that PR was updated since I last looked at it - maybe it's a bit different now?

@erickt erickt closed this as completed in 9cabe27 Mar 26, 2015
bors-servo pushed a commit to servo/euclid that referenced this issue Feb 24, 2020
…ical

Switch to using correct fixme link

Issue rust-lang/rust#7671 was closed, the new issue is rust-lang/rust#26925
flip1995 pushed a commit to flip1995/rust that referenced this issue Sep 28, 2021
…ednet

Downgrade many_single_char_names to pedantic

As suggested by `@flip1995` in rust-lang/rust-clippy#7666 (comment), by today's standards this lint would be considered `pedantic`.

This is one of the most widely suppressed Clippy lints on crates.io according to https://github.com/dtolnay/noisy-clippy.

In my opinion this lint is just too domain specific for Clippy to have reliable visibility into. Sure there are some cases where the author is just being lazy and could use a kick in the butt, but we're still left with an enormous number of suppressions where single chars are the most appropriate name. For example in the context of colors, a function using `h`, `s`, `l`, `r`, `g`, `b` is 100% sensible and spelling all those out is silly, but it's past the default lint threshold.

---

changelog: Moved [`many_single_char_names`] to `pedantic`
matthiasgoergens added a commit to 0xmozak/plonky2 that referenced this issue Apr 5, 2024
We can't use Rust's default deriving mechanism, until
rust-lang/rust#26925 and
rust-lang/rust#7671 are fixed.

But fortunately, there's a crate for that.
matthiasgoergens added a commit to 0xmozak/plonky2 that referenced this issue Apr 5, 2024
We can't use Rust's default deriving mechanism, until
rust-lang/rust#26925 and
rust-lang/rust#7671 are fixed.

But fortunately, there's a crate for that.
matthiasgoergens added a commit to 0xmozak/plonky2 that referenced this issue Apr 5, 2024
We can't use Rust's default deriving mechanism, until
rust-lang/rust#26925 and
rust-lang/rust#7671 are fixed.

But fortunately, there's a crate for that.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-syntaxext Area: Syntax extensions
Projects
None yet
Development

No branches or pull requests

7 participants