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

Wrong tokenization of doc comments in proc_macro #49655

Closed
dtolnay opened this issue Apr 4, 2018 · 2 comments
Closed

Wrong tokenization of doc comments in proc_macro #49655

dtolnay opened this issue Apr 4, 2018 · 2 comments
Assignees
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-bug Category: This is a bug.

Comments

@dtolnay
Copy link
Member

dtolnay commented Apr 4, 2018

In #49545 I believe we want /// doc to become doc = " doc", not "/// doc".

You can see this handled correctly by macro_rules:

macro_rules! tokens {
    (#[doc = $tt:tt]) => {
        println!("{:?}", $tt);
    }
}

fn main() {
    tokens! {
        /// doc
    }
}
" doc"

The incorrect behavior in proc_macro:

#!/bin/sh

cargo new --lib repro_macro
cargo new --lib repro

echo >repro_macro/src/lib.rs '
#![feature(proc_macro)]

extern crate proc_macro;
use proc_macro::{TokenStream, TokenNode};

#[proc_macro]
pub fn repro(_input: TokenStream) -> TokenStream {
    let mut tts = "/// doc\n".parse::<TokenStream>().unwrap().into_iter();
    println!("{}", tts.next().unwrap());
    match tts.next().unwrap().kind {
        TokenNode::Group(_, tts) => {
            let mut tts = tts.into_iter();
            println!("{}", tts.next().unwrap());
            println!("{}", tts.next().unwrap());
            println!("{}", tts.next().unwrap());
        }
        _ => unimplemented!(),
    }
    TokenStream::empty()
}
'

echo >>repro_macro/Cargo.toml '
[lib]
proc-macro = true
'

echo >repro/src/lib.rs '
#![feature(proc_macro)]

extern crate repro_macro;
repro_macro::repro!();
'

echo >>repro/Cargo.toml '
repro_macro = { path = "../repro_macro" }
'

cargo build --manifest-path repro/Cargo.toml
#
doc
=
"/// doc"

@alexcrichton

@alexcrichton
Copy link
Member

One interesting consequence of something like this (which makes sense in retrospect) is that I think syn can no longer have an is_sugared_doc_comment field, right? In that syn can't actually differentiate based on the token stream between literal comments like /// and those with #[doc]. I don't think that's too much of an issue though?

In any case I've added a fix for this to #49597

@dtolnay
Copy link
Member Author

dtolnay commented Apr 4, 2018

Yes, in fact I thought is_sugared_doc was already useless -- dtolnay/syn#389. We can remove it.

@pietroalbini pietroalbini added the C-bug Category: This is a bug. label Apr 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants