Upgrade rust/crates/proc-macro-hack to 0.5.16 am: f5ffad3974 Change-Id: I6f83d66947cb6e1020f692a006810d56d0613c01
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 020ca37..e1a1090 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@ { "git": { - "sha1": "29f01e8f33414f20a953dd1363277ac5d1cf7974" + "sha1": "35b1fa620a6486ed4b544d4fec6aa8cbdd017bd6" } }
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fea412f --- /dev/null +++ b/.github/workflows/ci.yml
@@ -0,0 +1,22 @@ +name: CI + +on: + push: + pull_request: + schedule: [cron: "40 1 * * *"] + +jobs: + test: + name: Rust ${{matrix.rust}} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + rust: [nightly, beta, stable, 1.31.0] + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + - run: cargo run --manifest-path example/Cargo.toml + - run: cargo test --all
diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3e6107d..0000000 --- a/.travis.yml +++ /dev/null
@@ -1,13 +0,0 @@ -sudo: false - -language: rust - -rust: - - nightly - - beta - - stable - - 1.31.0 - -script: - - cargo run --manifest-path example/Cargo.toml - - cargo test --all
diff --git a/Cargo.toml b/Cargo.toml index 66f7685..102757c 100644 --- a/Cargo.toml +++ b/Cargo.toml
@@ -13,7 +13,7 @@ [package] edition = "2018" name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.16" authors = ["David Tolnay <[email protected]>"] description = "Procedural macros in expression position" readme = "README.md" @@ -42,5 +42,3 @@ [dev-dependencies.trybuild] version = "1.0" -[badges.travis-ci] -repository = "dtolnay/proc-macro-hack"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 3076694..1f75add 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@ [package] name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.16" authors = ["David Tolnay <[email protected]>"] edition = "2018" license = "MIT OR Apache-2.0" @@ -20,9 +20,6 @@ syn = "1.0.5" trybuild = "1.0" -[badges] -travis-ci = { repository = "dtolnay/proc-macro-hack" } - [workspace] members = ["demo-hack", "demo-hack-impl", "example", "nested"]
diff --git a/METADATA b/METADATA index 1b6ac6b..932bd30 100644 --- a/METADATA +++ b/METADATA
@@ -9,11 +9,11 @@ type: GIT value: "https://github.com/dtolnay/proc-macro-hack" } - version: "0.5.15" + version: "0.5.16" license_type: NOTICE last_upgrade_date { year: 2020 - month: 4 - day: 17 + month: 5 + day: 25 } }
diff --git a/README.md b/README.md index 7984e6d..d6a6463 100644 --- a/README.md +++ b/README.md
@@ -1,8 +1,10 @@ Procedural macros in expression position ======================================== -[](https://travis-ci.org/dtolnay/proc-macro-hack) -[](https://crates.io/crates/proc-macro-hack) +[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/proc--macro--hack-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/proc-macro-hack) +[<img alt="crates.io" src="https://img.shields.io/crates/v/proc-macro-hack.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/proc-macro-hack) +[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-proc--macro--hack-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/proc-macro-hack) +[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/proc-macro-hack/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/proc-macro-hack/actions?query=branch%3Amaster) As of Rust 1.30, the language supports user-defined function-like procedural macros. However these can only be invoked in item position, not in @@ -22,7 +24,7 @@ This crate must contain nothing but procedural macros. Private helper functions and private modules are fine but nothing can be public. -[> example of an implementation crate][demo-hack-impl] +[» example of an implementation crate][demo-hack-impl] Just like you would use a #\[proc_macro\] attribute to define a natively supported procedural macro, use proc-macro-hack's #\[proc_macro_hack\] @@ -52,7 +54,7 @@ This crate is allowed to contain other public things if you need, for example traits or functions or ordinary macros. -[> example of a declaration crate][demo-hack] +[» example of a declaration crate][demo-hack] Within the declaration crate there needs to be a re-export of your procedural macro from the implementation crate. The re-export also carries a @@ -88,7 +90,7 @@ Users of your crate depend on your declaration crate (not your implementation crate), then use your procedural macros as usual. -[> example of a downstream crate][example] +[» example of a downstream crate][example] ```rust use demo_hack::add_one;
diff --git a/src/iter.rs b/src/iter.rs new file mode 100644 index 0000000..722013c --- /dev/null +++ b/src/iter.rs
@@ -0,0 +1,42 @@ +use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree}; + +pub type Iter<'a> = &'a mut IterImpl; + +pub struct IterImpl { + stack: Vec<token_stream::IntoIter>, + peeked: Option<TokenTree>, +} + +pub fn new(tokens: TokenStream) -> IterImpl { + IterImpl { + stack: vec![tokens.into_iter()], + peeked: None, + } +} + +impl IterImpl { + pub fn peek(&mut self) -> Option<&TokenTree> { + self.peeked = self.next(); + self.peeked.as_ref() + } +} + +impl Iterator for IterImpl { + type Item = TokenTree; + + fn next(&mut self) -> Option<Self::Item> { + if let Some(tt) = self.peeked.take() { + return Some(tt); + } + loop { + let top = self.stack.last_mut()?; + match top.next() { + None => drop(self.stack.pop()), + Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::None => { + self.stack.push(group.stream().into_iter()); + } + Some(tt) => return Some(tt), + } + } + } +}
diff --git a/src/lib.rs b/src/lib.rs index 292ac74..16d7823 100644 --- a/src/lib.rs +++ b/src/lib.rs
@@ -1,3 +1,11 @@ +//! [![github]](https://github.com/dtolnay/proc-macro-hack) [![crates-io]](https://crates.io/crates/proc-macro-hack) [![docs-rs]](https://docs.rs/proc-macro-hack) +//! +//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github +//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust +//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K +//! +//! <br> +//! //! As of Rust 1.30, the language supports user-defined function-like procedural //! macros. However these can only be invoked in item position, not in //! statements or expressions. @@ -14,7 +22,7 @@ //! This crate must contain nothing but procedural macros. Private helper //! functions and private modules are fine but nothing can be public. //! -//! [> example of an implementation crate][demo-hack-impl] +//! [» example of an implementation crate][demo-hack-impl] //! //! Just like you would use a #\[proc_macro\] attribute to define a natively //! supported procedural macro, use proc-macro-hack's #\[proc_macro_hack\] @@ -48,7 +56,7 @@ //! This crate is allowed to contain other public things if you need, for //! example traits or functions or ordinary macros. //! -//! [> example of a declaration crate][demo-hack] +//! [» example of a declaration crate][demo-hack] //! //! Within the declaration crate there needs to be a re-export of your //! procedural macro from the implementation crate. The re-export also carries a @@ -86,7 +94,7 @@ //! Users of your crate depend on your declaration crate (not your //! implementation crate), then use your procedural macros as usual. //! -//! [> example of a downstream crate][example] +//! [» example of a downstream crate][example] //! //! ``` //! use demo_hack::add_one; @@ -131,15 +139,17 @@ mod quote; mod error; +mod iter; mod parse; use crate::error::{compile_error, Error}; -use crate::parse::*; -use proc_macro::{token_stream, Ident, Punct, Spacing, Span, TokenStream, TokenTree}; +use crate::iter::Iter; +use crate::parse::{ + parse_define_args, parse_enum_hack, parse_export_args, parse_fake_call_site, parse_input, +}; +use proc_macro::{Ident, Punct, Spacing, Span, TokenStream, TokenTree}; use std::fmt::Write; -use std::iter::Peekable; -type Iter<'a> = &'a mut Peekable<token_stream::IntoIter>; type Visibility = Option<Span>; enum Input { @@ -169,8 +179,8 @@ #[proc_macro_attribute] pub fn proc_macro_hack(args: TokenStream, input: TokenStream) -> TokenStream { - let ref mut args = args.into_iter().peekable(); - let ref mut input = input.into_iter().peekable(); + let ref mut args = iter::new(args); + let ref mut input = iter::new(input); expand_proc_macro_hack(args, input).unwrap_or_else(compile_error) } @@ -190,7 +200,7 @@ #[doc(hidden)] #[proc_macro_derive(ProcMacroHack)] pub fn enum_hack(input: TokenStream) -> TokenStream { - let ref mut input = input.into_iter().peekable(); + let ref mut input = iter::new(input); parse_enum_hack(input).unwrap_or_else(compile_error) } @@ -202,8 +212,8 @@ #[doc(hidden)] #[proc_macro_attribute] pub fn fake_call_site(args: TokenStream, input: TokenStream) -> TokenStream { - let ref mut args = args.into_iter().peekable(); - let ref mut input = input.into_iter().peekable(); + let ref mut args = iter::new(args); + let ref mut input = iter::new(input); expand_fake_call_site(args, input).unwrap_or_else(compile_error) }
diff --git a/src/parse.rs b/src/parse.rs index c6b1665..de7c599 100644 --- a/src/parse.rs +++ b/src/parse.rs
@@ -1,7 +1,7 @@ -use crate::{Define, Error, Export, ExportArgs, FakeCallSite, Input, Iter, Macro, Visibility}; +use crate::iter::{self, Iter, IterImpl}; +use crate::{Define, Error, Export, ExportArgs, FakeCallSite, Input, Macro, Visibility}; use proc_macro::Delimiter::{Brace, Bracket, Parenthesis}; -use proc_macro::{token_stream, Delimiter, Ident, Span, TokenStream, TokenTree}; -use std::iter::Peekable; +use proc_macro::{Delimiter, Ident, Span, TokenStream, TokenTree}; pub(crate) fn parse_input(tokens: Iter) -> Result<Input, Error> { let attrs = parse_attributes(tokens)?; @@ -29,7 +29,7 @@ let mut macros = Vec::new(); match tokens.peek() { Some(TokenTree::Group(group)) if group.delimiter() == Brace => { - let ref mut content = group.stream().into_iter().peekable(); + let ref mut content = iter::new(group.stream()); loop { macros.push(parse_macro(content)?); if content.peek().is_none() { @@ -124,13 +124,10 @@ } } -fn parse_group( - tokens: Iter, - delimiter: Delimiter, -) -> Result<Peekable<token_stream::IntoIter>, Error> { +fn parse_group(tokens: Iter, delimiter: Delimiter) -> Result<IterImpl, Error> { match &tokens.next() { Some(TokenTree::Group(group)) if group.delimiter() == delimiter => { - Ok(group.stream().into_iter().peekable()) + Ok(iter::new(group.stream())) } tt => Err(Error::new( tt.as_ref().map_or_else(Span::call_site, TokenTree::span),