Commit 4d526e0
committed
Auto merge of rust-lang#40939 - jseyfried:proc_macro_api, r=nrc
proc_macro: implement `TokenTree`, `TokenKind`, hygienic `quote!`, and other API
All new API is gated behind `#![feature(proc_macro)]` and may be used with `#[proc_macro]`, `#[proc_macro_attribute]`, and `#[proc_macro_derive]` procedural macros.
More specifically, this PR adds the following in `proc_macro`:
```rust
// `TokenStream` constructors:
impl TokenStream { fn empty() -> TokenStream { ... } }
impl From<TokenTree> for TokenStream { ... }
impl From<TokenKind> for TokenStream { ... }
impl<T: Into<TokenStream>> FromIterator<T> for TokenStream { ... }
macro quote($($t:tt)*) { ... } // A hygienic `TokenStream` quoter
// `TokenStream` destructuring:
impl TokenStream { fn is_empty(&self) -> bool { ... } }
impl IntoIterator for TokenStream { type Item = TokenTree; ... }
struct TokenTree { span: Span, kind: TokenKind }
impl From<TokenKind> for TokenTree { ... }
impl Display for TokenTree { ... }
struct Span { ... } // a region of source code along with expansion/hygiene information
impl Default for Span { ... } // a span from the current procedural macro definition
impl Span { fn call_site() -> Span { ... } } // the call site of the current expansion
fn quote_span(span: Span) -> TokenStream;
enum TokenKind {
Group(Delimiter, TokenStream), // A delimited sequence, e.g. `( ... )`
Term(Term), // a unicode identifier, lifetime ('a), or underscore
Op(char, Spacing), // a punctuation character (`+`, `,`, `$`, etc.).
Literal(Literal), // a literal character (`'a'`), string (`"hello"`), or number (`2.3`)
}
enum Delimiter {
Parenthesis, // `( ... )`
Brace, // `[ ... ]`
Bracket, // `{ ... }`
None, // an implicit delimiter, e.g. `$var`, where $var is `...`.
}
struct Term { ... } // An interned string
impl Term {
fn intern(string: &str) -> Symbol { ... }
fn as_str(&self) -> &str { ... }
}
enum Spacing {
Alone, // not immediately followed by another `Op`, e.g. `+` in `+ =`.
Joint, // immediately followed by another `Op`, e.g. `+` in `+=`
}
struct Literal { ... }
impl Display for Literal { ... }
impl Literal {
fn integer(n: i128) -> Literal { .. } // unsuffixed integer literal
fn float(n: f64) -> Literal { .. } // unsuffixed floating point literal
fn u8(n: u8) -> Literal { ... } // similarly: i8, u16, i16, u32, i32, u64, i64, f32, f64
fn string(string: &str) -> Literal { ... }
fn character(ch: char) -> Literal { ... }
fn byte_string(bytes: &[u8]) -> Literal { ... }
}
```
For details on `quote!` hygiene, see [this example](rust-lang@20a9048) and [declarative macros 2.0](rust-lang#40847).
r? @nrcFile tree
63 files changed
+1562
-842
lines changed- src
- bootstrap
- doc/unstable-book/src/library-features
- libproc_macro_plugin
- libproc_macro
- librustc_driver
- librustc_metadata
- librustc
- ich
- middle
- librustdoc/html
- libsyntax_ext
- deriving
- libsyntax_pos
- libsyntax
- ext
- tt
- parse
- lexer
- print
- util
- test
- compile-fail
- run-pass-fulldeps
- auxiliary
- proc-macro
- auxiliary
- ui/token
- tools/tidy/src
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
63 files changed
+1562
-842
lines changedSome generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
482 | 482 | | |
483 | 483 | | |
484 | 484 | | |
485 | | - | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
486 | 488 | | |
487 | 489 | | |
488 | 490 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
0 commit comments