Skip to content

Commit 4d526e0

Browse files
committed
Auto merge of #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](20a9048) and [declarative macros 2.0](#40847). r? @nrc
2 parents 3610a70 + 78fdbfc commit 4d526e0

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 changed

src/Cargo.lock

-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,9 @@ impl Build {
482482
}
483483
}
484484

485-
if self.config.extended && compiler.is_final_stage(self) {
485+
if mode == Mode::Libstd &&
486+
self.config.extended &&
487+
compiler.is_final_stage(self) {
486488
cargo.env("RUSTC_SAVE_ANALYSIS", "api".to_string());
487489
}
488490

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# `proc_macro`
2+
3+
The tracking issue for this feature is: [#38356]
4+
5+
[#38356]: https://github.com/rust-lang/rust/issues/38356
6+
7+
------------------------

src/libproc_macro/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ crate-type = ["dylib"]
99

1010
[dependencies]
1111
syntax = { path = "../libsyntax" }
12+
syntax_pos = { path = "../libsyntax_pos" }

0 commit comments

Comments
 (0)