Skip to content

self and hygiene interact in unfortunate ways #39922

Closed
@nikomatsakis

Description

In this example, the code is attempting to use a macro to match generically over &self, &mut self, etc. In so doing, the self in the function signature is produced by a token-tree fragment. Unfortunately, if you do this, then self in the macro itself is considered a different self. Given that self is a keyword and not a normal variable, this seems a bit odd:

macro_rules! method {
    ($t:ty, $a:tt $($s:tt)*) => {
        impl $t {
            // To make the error go away, switch the commented code:
            // fn foo($a $($s)*) -> u32 { $($s)*.i }
            fn foo($a $($s)*) -> u32 { self.i }
        }
    };
}

struct Foo { i: u32 }

method!(Foo, &self);

fn main() {
    let mut f = Foo { i: 22 };
    f.foo();
}

Error:

error[E0424]: `self` is not available in a static method
  --> <anon>:5:40
   |
5  |             fn foo($a $($s)*) -> u32 { self.i }
   |                                        ^^^^ not available in static method
...
12 | method!(Foo, &self);
   | -------------------- in this macro invocation
   |
   = note: maybe a `self` argument is missing?

Also, the friendly error here is quite confusing.

cc @jseyfried @nrc @pnkfelix @wycats @dherman

Metadata

Assignees

Labels

A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions