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

Cannot use Self to construct a tuple struct in a macro #57523

Closed
kennytm opened this issue Jan 11, 2019 · 6 comments
Closed

Cannot use Self to construct a tuple struct in a macro #57523

kennytm opened this issue Jan 11, 2019 · 6 comments
Labels
C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kennytm
Copy link
Member

kennytm commented Jan 11, 2019

Reproduced on both on beta and nightly (not tested on stable since #51994 wasn't stabilized in 1.31).

#![warn(clippy::use_self)]

pub struct S(pub u16);

impl From<u8> for S {
    fn from(a: u8) -> Self {
        Self(a.into())            // <-- this is fine
    }
}

macro_rules! a {
    () => {
        impl From<u16> for S {
            fn from(a: u16) -> Self {
                // S(a)            // <-- this is fine but triggers the `clippy::use_self` warning
                Self(a)            // <-- ERROR E0423
                // Self { 0: a }   // <-- this is fine but ugly
            }
        }
    }
}

a!();

fn main() {}

This is particularly troublesome on nightly since clippy::use_self is recently upgraded to emit the lint in a local macro thanks to rust-lang/rust-clippy#3627, but the suggestion failed to compile.

@kennytm kennytm added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Jan 11, 2019
@varkor
Copy link
Member

varkor commented Jan 11, 2019

This also applies to type aliases.

struct T;

type B = T;

macro_rules! a {
    () => {
        impl T {
            fn b() -> B {
                B()
            }
        }
    }
}

a!();

I suspect this is to do with

// FIXME: can't resolve paths in macro namespace yet, macros are
// processed by the little special hack below.

cc @alexreg

@alexreg
Copy link
Contributor

alexreg commented Jan 11, 2019

Yes, I think @varkor is right.

@petrochenkov Maybe you could elaborate on this FIXME? What's stopping us from resolving paths in the macro NS here?

@petrochenkov petrochenkov self-assigned this Jan 12, 2019
@petrochenkov
Copy link
Contributor

That FIXME is unrelated to the issue.
The issue is that Self in value namespace accidentally uses "let variable hygiene" rather than "item hygiene", so macro_rules "hides" it from the outside world like it would do for a let variable.

Regarding type aliases, B defined by type B = T; doesn't exist in value namespace, so B() doesn't resolve (with or without macros).

@petrochenkov
Copy link
Contributor

@varkor
Looks like const generic parameters in #53645 have the same issue.

@petrochenkov
Copy link
Contributor

Fixed in #57560

@petrochenkov petrochenkov removed their assignment Jan 12, 2019
@alexreg
Copy link
Contributor

alexreg commented Jan 12, 2019

@petrochenkov Ahh, that makes perfect sense. Feel free (but not obliged) to r? me for that PR.

Centril added a commit to Centril/rust that referenced this issue Jan 13, 2019
hygiene: Do not treat `Self` ctor as a local variable

Fixes rust-lang#57523
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants