@@ -27,79 +27,21 @@ Procedural macros must be defined in a crate with the [crate type] of
27
27
# ## The `proc_macro` crate
28
28
29
29
Procedural macro crates almost always will link to the compiler-provided
30
- `proc_macro` crate. The `proc_macro` crate is a crate which provides
31
- facilities to working with the types of each procedural macro function. You can
32
- learn more about this crate by exploring [its documentation][proc macro crate].
30
+ [`proc_macro` crate ]. The `proc_macro` crate provides types required for
31
+ writing procedural macros and facilities to make it easier.
33
32
34
- # ## The `TokenStream` Type
35
-
36
- It primarily contains a `TokenStream` type.
37
- Procedural macros operate over *token streams* instead of AST nodes,
38
- which is a far more stable interface over time for both the compiler and for
39
- procedural macros to target.
40
-
41
- A *token stream* is roughly equivalent to `Vec<TokenTree>` where a `TokenTree`
33
+ This crate primarily contains a [`TokenStream`] type. Procedural macros operate
34
+ over *token streams* instead of AST nodes, which is a far more stable interface
35
+ over time for both the compiler and for procedural macros to target. A
36
+ *token stream* is roughly equivalent to `Vec<TokenTree>` where a `TokenTree`
42
37
can roughly be thought of as lexical token. For example `foo` is an `Ident`
43
38
token, `.` is a `Punct` token, and `1.2` is a `Literal` token. The `TokenStream`
44
- type, unlike `Vec<TokenTree>`, is cheap to clone (like `Rc<T>`).
45
-
46
- # ## Spans
47
-
48
- All tokens have an associated `Span`. A `Span` is currently an opaque value you
49
- cannot modify (but you can manufacture). `Span`s represent an extent of source
50
- code within a program and are primarily used for error reporting currently. You
51
- can modify the `Span` of any token, and by doing so if the compiler would like
52
- to print an error for the token in question it'll use the `Span` that you
53
- manufactured.
54
-
55
- For example let's create a wonky procedural macro which swaps the spans of the
56
- first two tokens:
57
-
58
- ```rust,ignore
59
- // my-macro/src/lib.rs
60
- extern crate proc_macro;
61
-
62
- use proc_macro::*;
63
-
64
- # [proc_macro]
65
- pub fn swap_spans(input: TokenStream) -> TokenStream {
66
- let mut iter = input.into_iter();
67
- let mut a = iter.next().unwrap();
68
- let mut b = iter.next().unwrap();
69
- let a_span = a.span();
70
- a.set_span(b.span());
71
- b.set_span(a_span);
72
- return vec![a, b].into_iter().chain(iter).collect()
73
- }
74
- ```
75
-
76
- ``` rust,ignore
77
- extern crate my_macro;
78
-
79
- my_macro::swap_spans! {
80
- fn _() {}
81
- }
82
-
83
- fn main() {}
84
- ```
85
-
86
- and compile it:
87
-
88
- ``` sh
89
- $ cargo run
90
- Compiling foo v0.1.0 (file://.../foo)
91
- error: expected identifier, found reserved identifier ` _`
92
- --> src/main.rs:4:5
93
- |
94
- 4 | fn _ () {}
95
- | ^^ expected identifier, found reserved identifier
96
-
97
- error: aborting due to previous error
98
- ```
39
+ type, unlike `Vec<TokenTree>`, is cheap to clone.
99
40
100
- notice how the error message is pointing to the wrong span! This is because we
101
- swapped the spans of the first two tokens, giving the compiler false information
102
- about where the tokens came from.
41
+ All tokens have an associated `Span`. A `Span` is an opaque value that cannot
42
+ be modified but can be manufactured. `Span`s represent an extent of source
43
+ code within a program and are primarily used for error reporting. You can modify
44
+ the `Span` of any token.
103
45
104
46
# ## Procedural macros and hygiene
105
47
@@ -398,5 +340,6 @@ argument. Notably these arguments do not include the delimiters used to enclose
398
340
the arguments (like procedural bang macros. Furthermore we can see the item
399
341
continue to operate on it, either replacing it or augmenting it.
400
342
401
- [ crate type ] : linkage.html
402
- [ proc_macro crate ] : ../proc_macro/index.html
343
+ [ `TokenStream` ] : ../proc_macro/struct.TokenStream.html
344
+ [ `proc_macro` crate ] : ../proc_macro/index.html
345
+ [ crate type ] : linkage.html
0 commit comments