Skip to content

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

Closed
@kennytm

Description

@kennytm
Member

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

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
varkor

varkor commented on Jan 11, 2019

@varkor
Member

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

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?

self-assigned this
on Jan 12, 2019
petrochenkov

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

petrochenkov

petrochenkov commented on Jan 12, 2019

@petrochenkov
Contributor

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

petrochenkov

petrochenkov commented on Jan 12, 2019

@petrochenkov
Contributor

Fixed in #57560

removed their assignment
on Jan 12, 2019
alexreg

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.

1 remaining item

Loading
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

        Participants

        @alexreg@kennytm@varkor@petrochenkov

        Issue actions

          Cannot use `Self` to construct a tuple struct in a macro · Issue #57523 · rust-lang/rust