Skip to content

Deriving can't be used within macros because it generates duplicate impls #6976

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

Closed
bstrie opened this issue Jun 6, 2013 · 5 comments
Closed
Labels
A-syntaxext Area: Syntax extensions E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@bstrie
Copy link
Contributor

bstrie commented Jun 6, 2013

This:

macro_rules! define_vec (
    () => (
        mod foo {
            #[deriving(Eq)]
            pub struct bar;
        }
    )
)

define_vec!()

fn main() {}

...doesn't compile:

moon.rs:4:23: 4:25 error: conflicting implementations for a trait
moon.rs:4             #[deriving(Eq)]
                                 ^~
moon.rs:4:23: 4:25 note: note conflicting implementation here
moon.rs:4             #[deriving(Eq)]
                                 ^~
moon.rs:4:23: 4:25 error: conflicting implementations for a trait
moon.rs:4             #[deriving(Eq)]
                                 ^~
moon.rs:4:23: 4:25 note: note conflicting implementation here
moon.rs:4             #[deriving(Eq)]
                                 ^~
error: aborting due to 2 previous errors

Taking a look at the expanded code:

mod foo {
    #[deriving(Eq)]
    pub struct bar;
    #[doc = "Automatically derived."]
    pub impl ::std::cmp::Eq for bar {
        pub fn eq(&self, __arg_0: &bar) -> ::bool {
            match *__arg_0 { bar => match *self { bar => true } }
        }
        pub fn ne(&self, __arg_0: &bar) -> ::bool {
            match *__arg_0 { bar => match *self { bar => false } }
        }
    }
    #[doc = "Automatically derived."]
    pub impl ::std::cmp::Eq for bar {
        pub fn eq(&self, __arg_0: &bar) -> ::bool {
            match *__arg_0 { bar => match *self { bar => true } }
        }
        pub fn ne(&self, __arg_0: &bar) -> ::bool {
            match *__arg_0 { bar => match *self { bar => false } }
        }
    }
}


fn main() { }

Notice that it's generating a second identical impl for the given trait. I've tested that this happens with both Eq and ToStr, so I presume it applies to the deriving code in general.

@huonw
Copy link
Member

huonw commented Jun 6, 2013

IIRC, this actually happens with any syntax extension, but someone should double check. (I.e. when #[auto_encode] was around, it had the same behaviour.)

@emberian
Copy link
Member

emberian commented Aug 5, 2013

Still relevant

@huonw
Copy link
Member

huonw commented Nov 15, 2013

Triage: cool! This appears to have fixed itself. @cmr, could you bisect it? I don't remember anything that would've affected this.

(Tagging as needstest.)

@ghost ghost assigned emberian Nov 15, 2013
@emberian
Copy link
Member

@huonw Something somewhere in the let hygiene fixed it.

@huonw
Copy link
Member

huonw commented Nov 16, 2013

Ah, cool; makes sense.

flip1995 pushed a commit to flip1995/rust that referenced this issue Apr 8, 2021
Don't lint `manual_map` in const functions

fixes: rust-lang#6967

changelog: Don't lint `manual_map` in const functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-syntaxext Area: Syntax extensions E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

3 participants