Skip to content

Inconsistency between accessing field of braced struct vs tuple struct in proc macro #47312

Closed
@dtolnay

Description

@dtolnay

If a procedural macro generates an access to a named struct field like self.x then the . may be either def_site or call_site and it works either way. But if accessing an unnamed tuple struct field like self.0 then it only works if . is call_site.

I believe it should work either way in either case.

#![feature(proc_macro)]

extern crate proc_macro;
use proc_macro::{TokenStream, TokenTree, TokenNode, Spacing, Span};

#[proc_macro]
pub fn field(input: TokenStream) -> TokenStream {
    let mut iter = input.into_iter();
    let struct_name = iter.next().unwrap();
    let field_name = iter.next().unwrap();
    assert!(iter.next().is_none());

    let dot = TokenTree {
        // Call_site works for both braced structs and tuple structs.
        // Def_site works for braced structs but not tuple structs.
        span: Span::def_site(),
        kind: TokenNode::Op('.', Spacing::Alone),
    };
    vec![
        struct_name,
        dot,
        field_name,
    ].into_iter().collect()
}
#![feature(proc_macro)]

extern crate mac;

struct S {
    a: u8,
}

struct T(u8);

fn main() {
    let s = S { a: 0 };
    println!("{:?}", mac::field!(s a));

    let t = T(0);
    println!("{:?}", mac::field!(t 0));
}
error[E0611]: field `0` of tuple-struct `T` is private
  --> src/main.rs:55:34
   |
55 |     println!("{:?}", mac::field!(t 0));
   |                                  ^^^

@jseyfried

Metadata

Metadata

Assignees

Labels

A-decl-macros-2-0Area: Declarative macros 2.0 (#39412)C-enhancementCategory: An issue proposing an enhancement or a PR with one.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