Skip to content

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

Closed

Description

@kennytm

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.

Activity

  1. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    C-bugCategory: This is a bug.
    on Jan 11, 2019
  2. varkor commented on Jan 11, 2019

    @varkor
    Contributor

    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

  3. alexreg commented on Jan 11, 2019

    @alexreg
    Contributor

    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?

  4. self-assigned this
    on Jan 12, 2019
  5. petrochenkov commented on Jan 12, 2019

    @petrochenkov
    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).

  6. petrochenkov commented on Jan 12, 2019

    @petrochenkov
    Contributor

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

  7. petrochenkov commented on Jan 12, 2019

    @petrochenkov
    Contributor

    Fixed in #57560

  8. removed their assignment
    on Jan 12, 2019
  9. alexreg commented on Jan 12, 2019

    @alexreg
    Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions