dtolnay / paste

Macros for all your token pasting needs
Apache License 2.0
1.02k stars 56 forks source link

Does not preserve invisible delimiters from declarative macros #85

Closed Kyuuhachi closed 1 year ago

Kyuuhachi commented 2 years ago

The below example requires parentheses around the $val to compile, which it doesn't without paste.

macro_rules! clone {
  ($val:expr) => {
    paste::paste! {
      $val.clone()
    }
  }
}

#[derive(Clone)]
struct A;

impl A {
  fn consume_self(self) {}
}

fn main() {
  clone!(&A).consume_self();
}

The correct resulting token tree would be ⟦⟦&A⟧.clone()⟧.consume_self(), but with paste, it appears to be flattened to ⟦&A.clone()⟧.consume_self().

The docs do say null delimiters might not survive roundtripping, but I think it should be possible to avoid here.

dtolnay commented 2 years ago

This is a rustc bug — paste! expands this input correctly (preserving the None-delimited group) but rustc's parser that is used for parsing the tokens returned by a proc macro just totally ignores None-delimited groups as if they were not grouped at all. See https://github.com/rust-lang/rust/issues/67062.