File: mixed-site-span.rs

package info (click to toggle)
rustc 1.90.0%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 925,928 kB
  • sloc: xml: 158,148; javascript: 19,781; sh: 19,174; python: 15,732; ansic: 13,096; cpp: 7,181; asm: 4,376; makefile: 697; lisp: 176; sql: 15
file content (91 lines) | stat: -rw-r--r-- 2,979 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#![feature(proc_macro_quote)]

extern crate proc_macro;
use proc_macro::*;


#[proc_macro]
pub fn proc_macro_item(input: TokenStream) -> TokenStream {
    input
}

#[proc_macro]
pub fn proc_macro_rules(_input: TokenStream) -> TokenStream {
    let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site()));
    let item_def = id("ItemDef");
    let local_def = id("local_def");
    let item_use = id("ItemUse");
    let local_use = id("local_use");
    let mut single_quote = Punct::new('\'', Spacing::Joint);
    single_quote.set_span(Span::mixed_site());
    let label_use: TokenStream = [
        TokenTree::from(single_quote),
        id("label_use"),
    ].iter().cloned().collect();
    let dollar_crate = id("$crate");
    quote!(
        use $dollar_crate::proc_macro_item as _; // OK
        type A = $dollar_crate::ItemUse; // ERROR

        struct $item_def;
        let $local_def = 0;

        $item_use; // OK
        $local_use; // ERROR
        break $label_use; // ERROR
    )
}

#[proc_macro]
pub fn with_crate(input: TokenStream) -> TokenStream {
    let mut input = input.into_iter();
    let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") };
    let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") };
    let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") };

    match (krate.to_string().as_str(), span.to_string().as_str()) {
        ("$crate", "input") => {},
        (_, "input") => krate = Ident::new("$crate", krate.span()),

        ("$crate", "mixed") => krate.set_span(Span::mixed_site()),
        (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()),

        ("$crate", "call") => krate.set_span(Span::call_site()),
        (_, "call") => krate = Ident::new("$crate", Span::call_site()),

        (_, x) => panic!("bad span {}", x),
    }

    quote!(use $krate::$ident as _;)
}

#[proc_macro]
pub fn declare_macro(input: TokenStream) -> TokenStream {
    let mut input = input.into_iter();
    let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") };
    let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") };
    let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") };


    match (krate.to_string().as_str(), span.to_string().as_str()) {
        ("$crate", "input") => {},
        (_, "input") => krate = Ident::new("$crate", krate.span()),

        ("$crate", "mixed") => krate.set_span(Span::mixed_site()),
        (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()),

        ("$crate", "call") => krate.set_span(Span::call_site()),
        (_, "call") => krate = Ident::new("$crate", Span::call_site()),

        (_, x) => panic!("bad span {}", x),
    }

    quote!(
        #[macro_export]
        macro_rules! $ident {
            ($$i:ident) => {
                use $krate::$$i as _;
            };
        }
    )
}