Skip to content

Allow proc macro to initialize a private field with a def_site value #47311

Closed

Description

In a struct initializer expression S { k: v } generated by a procedural macro where the field k is private, it seems both k and v need to be spanned with call_site in order for the generated code to compile. I believe only k should be required to be call_site, and v should be allowed to be def_site or anything else.

This currently blocks a correct implementation of derive(Deserialize).

#![feature(proc_macro)]

extern crate mac;

struct S {
    unit: (),
}

fn main() {
    // Expands to `S { unit: () }`.
    mac::init_field_unit!(S unit);
}
#![feature(proc_macro)]

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

#[proc_macro]
pub fn init_field_unit(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());

    // Expands to `$struct_name { $field_name: () }`.
    vec![
        struct_name,
        TokenTree {
            span: Span::call_site(),
            kind: TokenNode::Group(Delimiter::Brace, vec![
                field_name,
                TokenTree {
                    span: Span::call_site(),
                    kind: TokenNode::Op(':', Spacing::Alone),
                },
                TokenTree {
                    // Works if this is call_site, but in derive(Deserialize) I
                    // need to be able to use def_site variables here.
                    span: Span::def_site(),
                    kind: TokenNode::Group(Delimiter::Parenthesis, TokenStream::empty()),
                },
            ].into_iter().collect()),
        },
    ].into_iter().collect()
}
error[E0451]: field `unit` of struct `S` is private
  --> src/main.rs:49:5
   |
49 |     mac::init_field_unit!(S unit);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unit` is private

@jseyfried

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

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