Skip to content

Wrong span of Path if ModSep is inserted by proc macro #84122

@Y-Nak

Description

@Y-Nak

I tried this code:

// macros/src/lib.rs
use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;

#[proc_macro_derive(use_self)]
pub fn use_self(input: TokenStream) -> TokenStream {
    let item: syn::ItemEnum = parse_macro_input!(input);
    let ident = item.ident;
    let var0 = item.variants[0].ident.clone();
    TokenStream::from(quote! {
        #[automatically_derived]
        impl #ident {
            fn foo() -> Self {
                #ident::#var0
            }
        }
    })
}

// src/lib.rs
use macros::use_self;
#[derive(use_self)]
pub enum Direction {
    East,
}

Currently, the Span::ctxt() of Direction::East in the expansion is equal to SyntaxCtxt::root(). But this is obviously wrong because :: is inserted by the macro.

This would be because the span of :: is ignored in

let lo = self.token.span;
let mut segments = Vec::new();
let mod_sep_ctxt = self.token.span.ctxt();
if self.eat(&token::ModSep) {
segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
}
self.parse_path_segments(&mut segments, style)?;
Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None })

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-proc-macrosArea: Procedural macrosC-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

    Issue actions