Skip to content

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

New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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