Skip to content

Tokens in an attribute macro receive wrong spacing #50700

Closed
@dtolnay

Description

@dtolnay

Originally reported by @CodeSandwich as dtolnay/syn#425.

We are seeing a functionlike procedural macro invocation m![< -] receive the expected spacing (Alone for both tokens) but preprocessing the same input with an attribute macro #[attribute] m![< -] receives incorrect spacing -- Joint for the < token even though it is followed by whitespace. Strangely using parentheses appears to fix the spacing so that #[attribute] m!(< -) correctly has Alone for both tokens.

Repro script

#!/bin/sh

cargo new --lib repro
cargo new --lib repro_macros

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

extern crate repro_macros;
use repro_macros::{tokens, nothing};

// alone + alone
tokens![< -];

// joint + alone
#[nothing]
asdf![< -];

// alone + alone
#[nothing]
asdf!(< -);

fn main() {}
'

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

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

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro]
pub fn tokens(input: TokenStream) -> TokenStream {
    println!("{:#?}", input);
    TokenStream::empty()
}

#[proc_macro_attribute]
pub fn nothing(_: TokenStream, input: TokenStream) -> TokenStream {
    println!("{:#?}", input);
    TokenStream::empty()
}
'

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

cargo build --manifest-path repro/Cargo.toml
Output
TokenStream [
    Op {
        op: '<',
        spacing: Alone,
        span: #0 bytes(116..117)
    },
    Op {
        op: '-',
        spacing: Alone,
        span: #0 bytes(118..119)
    }
]
TokenStream [
    Term {
        sym: asdf,
        span: #0 bytes(7615976..7615980)
    },
    Op {
        op: '!',
        spacing: Alone,
        span: #0 bytes(0..0)
    },
    Group {
        delimiter: Parenthesis,
        stream: TokenStream [
            Op {
                op: '<',
                spacing: Joint,
                span: #0 bytes(0..0)
            },
            Op {
                op: '-',
                spacing: Alone,
                span: #0 bytes(0..0)
            }
        ],
        span: #0 bytes(0..0)
    },
    Op {
        op: ';',
        spacing: Alone,
        span: #0 bytes(0..0)
    }
]
TokenStream [
    Term {
        sym: asdf,
        span: #0 bytes(192..196)
    },
    Op {
        op: '!',
        spacing: Alone,
        span: #0 bytes(196..197)
    },
    Group {
        delimiter: Parenthesis,
        stream: TokenStream [
            Op {
                op: '<',
                spacing: Alone,
                span: #0 bytes(198..199)
            },
            Op {
                op: '-',
                spacing: Alone,
                span: #0 bytes(200..201)
            }
        ],
        span: #0 bytes(197..202)
    },
    Op {
        op: ';',
        spacing: Alone,
        span: #0 bytes(202..203)
    }
]

@alexcrichton

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-decl-macros-2-0Area: Declarative macros 2.0 (#39412)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions