From f0a4f61899f68ba4e4d86239fab08780ee2f268c Mon Sep 17 00:00:00 2001 From: David LeGare Date: Wed, 2 Mar 2022 16:21:21 +0000 Subject: Update proc-macro2 to 1.0.36 Test: cd external/rust/crates && atest --host -c Change-Id: I1306dd52c8b96f691128e0bd71604c1838edb880 --- .cargo_vcs_info.json | 7 ++-- .github/workflows/ci.yml | 39 +++++++++----------- Android.bp | 10 +---- Cargo.toml | 8 ++-- Cargo.toml.orig | 8 ++-- METADATA | 10 ++--- README.md | 7 ++-- build.rs | 31 ++++++++++++---- src/detection.rs | 18 ++++++--- src/fallback.rs | 94 ++++++++++++++++++++++++++++------------------- src/lib.rs | 96 ++++++++++++++++++++++++++++++++++-------------- src/parse.rs | 13 +++---- src/wrapper.rs | 82 ++++++++++++++++++++++------------------- tests/comments.rs | 18 ++++----- tests/marker.rs | 12 ++++-- tests/test.rs | 13 ++++++- tests/test_fmt.rs | 4 +- 17 files changed, 287 insertions(+), 183 deletions(-) diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index b4a0dce..59bd97e 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "4fc89676e7bdef2ba68e8a1383d07df0bb7bbeb0" - } -} + "sha1": "7ecea3b88fe72672ca4270631b5d4585c0f7c715" + }, + "path_in_vcs": "" +} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e469b08..2063a5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: jobs: test: - name: Rust ${{ matrix.rust }} + name: Rust ${{matrix.rust}} runs-on: ubuntu-latest strategy: fail-fast: false @@ -15,11 +15,9 @@ jobs: rust: [1.31.0, stable, beta] steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: - toolchain: ${{ matrix.rust }} - profile: minimal - override: true + toolchain: ${{matrix.rust}} - run: cargo test - run: cargo test --no-default-features - run: cargo test --features span-locations @@ -31,11 +29,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - profile: minimal - override: true + - uses: dtolnay/rust-toolchain@nightly - run: cargo test - run: cargo test --no-default-features - run: cargo test --no-default-features -- --ignored # run the ignored test to make sure the `proc-macro` feature is disabled @@ -51,23 +45,26 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@nightly with: - toolchain: nightly target: wasm32-unknown-unknown - profile: minimal - override: true - run: cargo test --target wasm32-unknown-unknown --no-run clippy: name: Clippy runs-on: ubuntu-latest + if: github.event_name != 'pull_request' steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - profile: minimal - override: true - components: clippy - - run: cargo clippy -- -Dclippy::all + - uses: dtolnay/rust-toolchain@clippy + - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic + - run: cargo clippy --tests --all-features -- -Dclippy::all -Dclippy::pedantic + + outdated: + name: Outdated + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --exit-code 1 diff --git a/Android.bp b/Android.bp index 10cc0f6..410a4f4 100644 --- a/Android.bp +++ b/Android.bp @@ -41,7 +41,7 @@ rust_library_host { name: "libproc_macro2", crate_name: "proc_macro2", cargo_env_compat: true, - cargo_pkg_version: "1.0.29", + cargo_pkg_version: "1.0.36", srcs: ["src/lib.rs"], edition: "2018", features: [ @@ -50,9 +50,6 @@ rust_library_host { "span-locations", ], cfgs: [ - "hygiene", - "lexerror_display", - "literal_from_str", "span_locations", "use_proc_macro", "wrap_proc_macro", @@ -67,7 +64,7 @@ rust_defaults { name: "proc-macro2_test_defaults", crate_name: "proc_macro2", cargo_env_compat: true, - cargo_pkg_version: "1.0.29", + cargo_pkg_version: "1.0.36", test_suites: ["general-tests"], auto_gen_config: true, edition: "2018", @@ -77,9 +74,6 @@ rust_defaults { "span-locations", ], cfgs: [ - "hygiene", - "lexerror_display", - "literal_from_str", "span_locations", "use_proc_macro", "wrap_proc_macro", diff --git a/Cargo.toml b/Cargo.toml index 901c787..1272f37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,16 +11,18 @@ [package] edition = "2018" +rust-version = "1.31" name = "proc-macro2" -version = "1.0.29" -authors = ["Alex Crichton ", "David Tolnay "] +version = "1.0.36" +authors = ["David Tolnay ", "Alex Crichton "] +autobenches = false description = "A substitute implementation of the compiler's `proc_macro` API to decouple\ntoken-based libraries from the procedural macro use case.\n" documentation = "https://docs.rs/proc-macro2" readme = "README.md" keywords = ["macros"] categories = ["development-tools::procedural-macro-helpers"] license = "MIT OR Apache-2.0" -repository = "https://github.com/alexcrichton/proc-macro2" +repository = "https://github.com/dtolnay/proc-macro2" [package.metadata.docs.rs] rustc-args = ["--cfg", "procmacro2_semver_exempt"] rustdoc-args = ["--cfg", "procmacro2_semver_exempt", "--cfg", "doc_cfg"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 543dca5..401bfaf 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,14 +1,16 @@ [package] name = "proc-macro2" -version = "1.0.29" # remember to update html_root_url -authors = ["Alex Crichton ", "David Tolnay "] +version = "1.0.36" # remember to update html_root_url +authors = ["David Tolnay ", "Alex Crichton "] license = "MIT OR Apache-2.0" readme = "README.md" keywords = ["macros"] -repository = "https://github.com/alexcrichton/proc-macro2" +repository = "https://github.com/dtolnay/proc-macro2" documentation = "https://docs.rs/proc-macro2" categories = ["development-tools::procedural-macro-helpers"] edition = "2018" +autobenches = false +rust-version = "1.31" description = """ A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case. diff --git a/METADATA b/METADATA index e87d081..e2ded2b 100644 --- a/METADATA +++ b/METADATA @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.29.crate" + value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.36.crate" } - version: "1.0.29" + version: "1.0.36" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 9 - day: 22 + year: 2022 + month: 3 + day: 1 } } diff --git a/README.md b/README.md index 3d05e87..35e1876 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # proc-macro2 -[![Build Status](https://img.shields.io/github/workflow/status/alexcrichton/proc-macro2/build%20and%20test)](https://github.com/alexcrichton/proc-macro2/actions) -[![Latest Version](https://img.shields.io/crates/v/proc-macro2.svg)](https://crates.io/crates/proc-macro2) -[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/proc-macro2) +[github](https://github.com/dtolnay/proc-macro2) +[crates.io](https://crates.io/crates/proc-macro2) +[docs.rs](https://docs.rs/proc-macro2) +[build status](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster) A wrapper around the procedural macro API of the compiler's `proc_macro` crate. This library serves two purposes: diff --git a/build.rs b/build.rs index f32d5c8..946be6e 100644 --- a/build.rs +++ b/build.rs @@ -33,6 +33,12 @@ // location of a token. Enabled by procmacro2_semver_exempt or the // "span-locations" Cargo cfg. This is behind a cfg because tracking // location inside spans is a performance hit. +// +// "is_available" +// Use proc_macro::is_available() to detect if the proc macro API is +// available or needs to be polyfilled instead of trying to use the proc +// macro API and catching a panic if it isn't available. Enabled on Rust +// 1.57+. use std::env; use std::iter; @@ -52,9 +58,10 @@ fn main() { process::exit(1); } - let semver_exempt = cfg!(procmacro2_semver_exempt); + let docs_rs = env::var_os("DOCS_RS").is_some(); + let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; if semver_exempt { - // https://github.com/alexcrichton/proc-macro2/issues/147 + // https://github.com/dtolnay/proc-macro2/issues/147 println!("cargo:rustc-cfg=procmacro2_semver_exempt"); } @@ -70,16 +77,24 @@ fn main() { println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard"); } - if version.minor >= 44 { - println!("cargo:rustc-cfg=lexerror_display"); + if version.minor < 44 { + println!("cargo:rustc-cfg=no_lexerror_display"); + } + + if version.minor < 45 { + println!("cargo:rustc-cfg=no_hygiene"); + } + + if version.minor < 54 { + println!("cargo:rustc-cfg=no_literal_from_str"); } - if version.minor >= 45 { - println!("cargo:rustc-cfg=hygiene"); + if version.minor < 55 { + println!("cargo:rustc-cfg=no_group_open_close"); } - if version.minor >= 54 { - println!("cargo:rustc-cfg=literal_from_str"); + if version.minor < 57 { + println!("cargo:rustc-cfg=no_is_available"); } let target = env::var("TARGET").unwrap(); diff --git a/src/detection.rs b/src/detection.rs index c597bc9..d139b73 100644 --- a/src/detection.rs +++ b/src/detection.rs @@ -1,12 +1,11 @@ -use std::panic::{self, PanicInfo}; -use std::sync::atomic::*; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Once; static WORKS: AtomicUsize = AtomicUsize::new(0); static INIT: Once = Once::new(); pub(crate) fn inside_proc_macro() -> bool { - match WORKS.load(Ordering::SeqCst) { + match WORKS.load(Ordering::Relaxed) { 1 => return false, 2 => return true, _ => {} @@ -17,13 +16,19 @@ pub(crate) fn inside_proc_macro() -> bool { } pub(crate) fn force_fallback() { - WORKS.store(1, Ordering::SeqCst); + WORKS.store(1, Ordering::Relaxed); } pub(crate) fn unforce_fallback() { initialize(); } +#[cfg(not(no_is_available))] +fn initialize() { + let available = proc_macro::is_available(); + WORKS.store(available as usize + 1, Ordering::Relaxed); +} + // Swap in a null panic hook to avoid printing "thread panicked" to stderr, // then use catch_unwind to determine whether the compiler's proc_macro is // working. When proc-macro2 is used from outside of a procedural macro all @@ -48,7 +53,10 @@ pub(crate) fn unforce_fallback() { // here. For now, if a user needs to guarantee that this failure mode does // not occur, they need to call e.g. `proc_macro2::Span::call_site()` from // the main thread before launching any other threads. +#[cfg(no_is_available)] fn initialize() { + use std::panic::{self, PanicInfo}; + type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static; let null_hook: Box = Box::new(|_panic_info| { /* ignore */ }); @@ -57,7 +65,7 @@ fn initialize() { panic::set_hook(null_hook); let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok(); - WORKS.store(works as usize + 1, Ordering::SeqCst); + WORKS.store(works as usize + 1, Ordering::Relaxed); let hopefully_null_hook = panic::take_hook(); panic::set_hook(original_hook); diff --git a/src/fallback.rs b/src/fallback.rs index 3d2feae..ac5437d 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -31,7 +31,7 @@ pub fn unforce() { #[derive(Clone)] pub(crate) struct TokenStream { - pub(crate) inner: Vec, + inner: Vec, } #[derive(Debug)] @@ -52,7 +52,7 @@ impl LexError { } impl TokenStream { - pub fn new() -> TokenStream { + pub fn new() -> Self { TokenStream { inner: Vec::new() } } @@ -65,7 +65,7 @@ impl TokenStream { } fn push_token(&mut self, token: TokenTree) { - // https://github.com/alexcrichton/proc-macro2/issues/235 + // https://github.com/dtolnay/proc-macro2/issues/235 match token { #[cfg(not(no_bind_by_move_pattern_guard))] TokenTree::Literal(crate::Literal { @@ -74,7 +74,7 @@ impl TokenStream { #[cfg(not(wrap_proc_macro))] inner: literal, .. - }) if literal.text.starts_with('-') => { + }) if literal.repr.starts_with('-') => { push_negative_literal(self, literal); } #[cfg(no_bind_by_move_pattern_guard)] @@ -85,7 +85,7 @@ impl TokenStream { inner: literal, .. }) => { - if literal.text.starts_with('-') { + if literal.repr.starts_with('-') { push_negative_literal(self, literal); } else { self.inner @@ -97,7 +97,7 @@ impl TokenStream { #[cold] fn push_negative_literal(stream: &mut TokenStream, mut literal: Literal) { - literal.text.remove(0); + literal.repr.remove(0); let mut punct = crate::Punct::new('-', Spacing::Alone); punct.set_span(crate::Span::_new_stable(literal.span)); stream.inner.push(TokenTree::Punct(punct)); @@ -108,6 +108,12 @@ impl TokenStream { } } +impl From> for TokenStream { + fn from(inner: Vec) -> Self { + TokenStream { inner } + } +} + // Nonrecursive to prevent stack overflow. impl Drop for TokenStream { fn drop(&mut self) { @@ -119,7 +125,7 @@ impl Drop for TokenStream { #[cfg(wrap_proc_macro)] let group = match group { crate::imp::Group::Fallback(group) => group, - _ => continue, + crate::imp::Group::Compiler(_) => continue, }; let mut group = group; self.inner.extend(group.stream.take_inner()); @@ -179,7 +185,7 @@ impl Display for TokenStream { Display::fmt(tt, f) } TokenTree::Literal(tt) => Display::fmt(tt, f), - }? + }?; } Ok(()) @@ -417,22 +423,22 @@ pub(crate) struct Span { impl Span { #[cfg(not(span_locations))] - pub fn call_site() -> Span { + pub fn call_site() -> Self { Span {} } #[cfg(span_locations)] - pub fn call_site() -> Span { + pub fn call_site() -> Self { Span { lo: 0, hi: 0 } } - #[cfg(hygiene)] - pub fn mixed_site() -> Span { + #[cfg(not(no_hygiene))] + pub fn mixed_site() -> Self { Span::call_site() } #[cfg(procmacro2_semver_exempt)] - pub fn def_site() -> Span { + pub fn def_site() -> Self { Span::call_site() } @@ -554,7 +560,7 @@ pub(crate) struct Group { } impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { Group { delimiter, stream, @@ -632,7 +638,7 @@ pub(crate) struct Ident { } impl Ident { - fn _new(string: &str, raw: bool, span: Span) -> Ident { + fn _new(string: &str, raw: bool, span: Span) -> Self { validate_ident(string); Ident { @@ -642,11 +648,11 @@ impl Ident { } } - pub fn new(string: &str, span: Span) -> Ident { + pub fn new(string: &str, span: Span) -> Self { Ident::_new(string, false, span) } - pub fn new_raw(string: &str, span: Span) -> Ident { + pub fn new_raw(string: &str, span: Span) -> Self { Ident::_new(string, true, span) } @@ -756,7 +762,7 @@ impl Debug for Ident { #[derive(Clone)] pub(crate) struct Literal { - text: String, + repr: String, span: Span, } @@ -777,13 +783,17 @@ macro_rules! unsuffixed_numbers { } impl Literal { - pub(crate) fn _new(text: String) -> Literal { + pub(crate) fn _new(repr: String) -> Self { Literal { - text, + repr, span: Span::call_site(), } } + pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(repr.to_owned()) + } + suffixed_numbers! { u8_suffixed => u8, u16_suffixed => u16, @@ -834,31 +844,31 @@ impl Literal { } pub fn string(t: &str) -> Literal { - let mut text = String::with_capacity(t.len() + 2); - text.push('"'); + let mut repr = String::with_capacity(t.len() + 2); + repr.push('"'); for c in t.chars() { if c == '\'' { // escape_debug turns this into "\'" which is unnecessary. - text.push(c); + repr.push(c); } else { - text.extend(c.escape_debug()); + repr.extend(c.escape_debug()); } } - text.push('"'); - Literal::_new(text) + repr.push('"'); + Literal::_new(repr) } pub fn character(t: char) -> Literal { - let mut text = String::new(); - text.push('\''); + let mut repr = String::new(); + repr.push('\''); if t == '"' { // escape_debug turns this into '\"' which is unnecessary. - text.push(t); + repr.push(t); } else { - text.extend(t.escape_debug()); + repr.extend(t.escape_debug()); } - text.push('\''); - Literal::_new(text) + repr.push('\''); + Literal::_new(repr) } pub fn byte_string(bytes: &[u8]) -> Literal { @@ -896,10 +906,20 @@ impl Literal { impl FromStr for Literal { type Err = LexError; - fn from_str(repr: &str) -> Result { + fn from_str(mut repr: &str) -> Result { + let negative = repr.starts_with('-'); + if negative { + repr = &repr[1..]; + if !repr.starts_with(|ch: char| ch.is_ascii_digit()) { + return Err(LexError::call_site()); + } + } let cursor = get_cursor(repr); - if let Ok((_rest, literal)) = parse::literal(cursor) { - if literal.text.len() == repr.len() { + if let Ok((_rest, mut literal)) = parse::literal(cursor) { + if literal.repr.len() == repr.len() { + if negative { + literal.repr.insert(0, '-'); + } return Ok(literal); } } @@ -909,14 +929,14 @@ impl FromStr for Literal { impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.text, f) + Display::fmt(&self.repr, f) } } impl Debug for Literal { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let mut debug = fmt.debug_struct("Literal"); - debug.field("lit", &format_args!("{}", self.text)); + debug.field("lit", &format_args!("{}", self.repr)); debug_span_field_if_nontrivial(&mut debug, self.span); debug.finish() } diff --git a/src/lib.rs b/src/lib.rs index 1d35bfd..6edaf42 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,11 @@ +//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate) +//! +//! [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 +//! +//!
+//! //! A wrapper around the procedural macro API of the compiler's [`proc_macro`] //! crate. This library serves two purposes: //! @@ -78,11 +86,34 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.29")] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.36")] #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] -#![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))] +#![cfg_attr(super_unstable, feature(proc_macro_def_site))] #![cfg_attr(doc_cfg, feature(doc_cfg))] -#![allow(clippy::needless_doctest_main, clippy::vec_init_then_push)] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::doc_markdown, + clippy::items_after_statements, + clippy::manual_assert, + clippy::must_use_candidate, + clippy::needless_doctest_main, + clippy::return_self_not_must_use, + clippy::shadow_unrelated, + clippy::trivially_copy_pass_by_ref, + clippy::unnecessary_wraps, + clippy::unused_self, + clippy::used_underscore_binding, + clippy::vec_init_then_push +)] + +#[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))] +compile_error! {"\ + Something is not right. If you've tried to turn on \ + procmacro2_semver_exempt, you need to ensure that it \ + is turned on for the compilation of the proc-macro2 \ + build script as well. +"} #[cfg(use_proc_macro)] extern crate proc_macro; @@ -135,14 +166,14 @@ pub struct LexError { } impl TokenStream { - fn _new(inner: imp::TokenStream) -> TokenStream { + fn _new(inner: imp::TokenStream) -> Self { TokenStream { inner, _marker: Marker, } } - fn _new_stable(inner: fallback::TokenStream) -> TokenStream { + fn _new_stable(inner: fallback::TokenStream) -> Self { TokenStream { inner: inner.into(), _marker: Marker, @@ -150,7 +181,7 @@ impl TokenStream { } /// Returns an empty `TokenStream` containing no token trees. - pub fn new() -> TokenStream { + pub fn new() -> Self { TokenStream::_new(imp::TokenStream::new()) } @@ -210,14 +241,14 @@ impl From for TokenStream { impl Extend for TokenStream { fn extend>(&mut self, streams: I) { - self.inner.extend(streams) + self.inner.extend(streams); } } impl Extend for TokenStream { fn extend>(&mut self, streams: I) { self.inner - .extend(streams.into_iter().map(|stream| stream.inner)) + .extend(streams.into_iter().map(|stream| stream.inner)); } } @@ -273,7 +304,7 @@ impl Error for LexError {} /// The source file of a given `Span`. /// /// This type is semver exempt and not exposed by default. -#[cfg(procmacro2_semver_exempt)] +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] #[derive(Clone, PartialEq, Eq)] pub struct SourceFile { @@ -281,7 +312,7 @@ pub struct SourceFile { _marker: Marker, } -#[cfg(procmacro2_semver_exempt)] +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] impl SourceFile { fn _new(inner: imp::SourceFile) -> Self { SourceFile { @@ -314,7 +345,7 @@ impl SourceFile { } } -#[cfg(procmacro2_semver_exempt)] +#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] impl Debug for SourceFile { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Debug::fmt(&self.inner, f) @@ -360,14 +391,14 @@ pub struct Span { } impl Span { - fn _new(inner: imp::Span) -> Span { + fn _new(inner: imp::Span) -> Self { Span { inner, _marker: Marker, } } - fn _new_stable(inner: fallback::Span) -> Span { + fn _new_stable(inner: fallback::Span) -> Self { Span { inner: inner.into(), _marker: Marker, @@ -379,7 +410,7 @@ impl Span { /// Identifiers created with this span will be resolved as if they were /// written directly at the macro call location (call-site hygiene) and /// other code at the macro call site will be able to refer to them as well. - pub fn call_site() -> Span { + pub fn call_site() -> Self { Span::_new(imp::Span::call_site()) } @@ -388,8 +419,8 @@ impl Span { /// of the macro. This is the same hygiene behavior as `macro_rules`. /// /// This function requires Rust 1.45 or later. - #[cfg(hygiene)] - pub fn mixed_site() -> Span { + #[cfg(not(no_hygiene))] + pub fn mixed_site() -> Self { Span::_new(imp::Span::mixed_site()) } @@ -398,7 +429,7 @@ impl Span { /// This method is semver exempt and not exposed by default. #[cfg(procmacro2_semver_exempt)] #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn def_site() -> Span { + pub fn def_site() -> Self { Span::_new(imp::Span::def_site()) } @@ -439,7 +470,7 @@ impl Span { /// The original source file into which this span points. /// /// This method is semver exempt and not exposed by default. - #[cfg(procmacro2_semver_exempt)] + #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] pub fn source_file(&self) -> SourceFile { SourceFile::_new(self.inner.source_file()) @@ -649,7 +680,7 @@ impl Group { /// This constructor will set the span for this group to /// `Span::call_site()`. To change the span you can use the `set_span` /// method below. - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { Group { inner: imp::Group::new(delimiter, stream.inner), } @@ -706,7 +737,7 @@ impl Group { /// by this group, but rather it will only set the span of the delimiter /// tokens at the level of the `Group`. pub fn set_span(&mut self, span: Span) { - self.inner.set_span(span.inner) + self.inner.set_span(span.inner); } } @@ -757,7 +788,7 @@ impl Punct { /// /// The returned `Punct` will have the default span of `Span::call_site()` /// which can be further configured with the `set_span` method below. - pub fn new(ch: char, spacing: Spacing) -> Punct { + pub fn new(ch: char, spacing: Spacing) -> Self { Punct { ch, spacing, @@ -879,7 +910,7 @@ pub struct Ident { } impl Ident { - fn _new(inner: imp::Ident) -> Ident { + fn _new(inner: imp::Ident) -> Self { Ident { inner, _marker: Marker, @@ -917,7 +948,7 @@ impl Ident { /// style="padding-right:0;">syn::parse_str::<Ident> /// rather than `Ident::new`. - pub fn new(string: &str, span: Span) -> Ident { + pub fn new(string: &str, span: Span) -> Self { Ident::_new(imp::Ident::new(string, span.inner)) } @@ -926,11 +957,11 @@ impl Ident { /// This method is semver exempt and not exposed by default. #[cfg(procmacro2_semver_exempt)] #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn new_raw(string: &str, span: Span) -> Ident { + pub fn new_raw(string: &str, span: Span) -> Self { Ident::_new_raw(string, span) } - fn _new_raw(string: &str, span: Span) -> Ident { + fn _new_raw(string: &str, span: Span) -> Self { Ident::_new(imp::Ident::new_raw(string, span.inner)) } @@ -977,7 +1008,7 @@ impl Ord for Ident { impl Hash for Ident { fn hash(&self, hasher: &mut H) { - self.to_string().hash(hasher) + self.to_string().hash(hasher); } } @@ -1048,14 +1079,14 @@ macro_rules! unsuffixed_int_literals { } impl Literal { - fn _new(inner: imp::Literal) -> Literal { + fn _new(inner: imp::Literal) -> Self { Literal { inner, _marker: Marker, } } - fn _new_stable(inner: fallback::Literal) -> Literal { + fn _new_stable(inner: fallback::Literal) -> Self { Literal { inner: inner.into(), _marker: Marker, @@ -1201,6 +1232,15 @@ impl Literal { pub fn subspan>(&self, range: R) -> Option { self.inner.subspan(range).map(Span::_new) } + + // Intended for the `quote!` macro to use when constructing a proc-macro2 + // token out of a macro_rules $:literal token, which is already known to be + // a valid literal. This avoids reparsing/validating the literal's string + // representation. This is not public API other than for quote. + #[doc(hidden)] + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + Literal::_new(imp::Literal::from_str_unchecked(repr)) + } } impl FromStr for Literal { diff --git a/src/parse.rs b/src/parse.rs index eddb490..f77213a 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -168,7 +168,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result { let first = match input.bytes().next() { Some(first) => first, None => match stack.last() { - None => return Ok(TokenStream { inner: trees }), + None => return Ok(TokenStream::from(trees)), #[cfg(span_locations)] Some((lo, _frame)) => { return Err(LexError { @@ -209,7 +209,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result { return Err(lex_error(input)); } input = input.advance(1); - let mut g = Group::new(open_delimiter, TokenStream { inner: trees }); + let mut g = Group::new(open_delimiter, TokenStream::from(trees)); g.set_span(Span { #[cfg(span_locations)] lo, @@ -621,8 +621,7 @@ fn float_digits(input: Cursor) -> Result { chars.next(); if chars .peek() - .map(|&ch| ch == '.' || is_ident_start(ch)) - .unwrap_or(false) + .map_or(false, |&ch| ch == '.' || is_ident_start(ch)) { return Err(Reject); } @@ -817,12 +816,12 @@ fn doc_comment(input: Cursor) -> PResult> { TokenTree::Punct(Punct::new('=', Spacing::Alone)), TokenTree::Literal(crate::Literal::string(comment)), ]; - for tt in stream.iter_mut() { + for tt in &mut stream { tt.set_span(span); } - let group = Group::new(Delimiter::Bracket, stream.into_iter().collect()); + let group = Group::new(Delimiter::Bracket, TokenStream::from(stream)); trees.push(crate::Group::_new_stable(group).into()); - for tt in trees.iter_mut() { + for tt in &mut trees { tt.set_span(span); } Ok((rest, trees)) diff --git a/src/wrapper.rs b/src/wrapper.rs index dc93873..2ba76cc 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -69,7 +69,7 @@ impl DeferredTokenStream { } impl TokenStream { - pub fn new() -> TokenStream { + pub fn new() -> Self { if inside_proc_macro() { TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) } else { @@ -284,9 +284,9 @@ impl Debug for LexError { impl Display for LexError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - #[cfg(lexerror_display)] + #[cfg(not(no_lexerror_display))] LexError::Compiler(e) => Display::fmt(e, f), - #[cfg(not(lexerror_display))] + #[cfg(no_lexerror_display)] LexError::Compiler(_e) => Display::fmt( &fallback::LexError { span: fallback::Span::call_site(), @@ -408,7 +408,7 @@ pub(crate) enum Span { } impl Span { - pub fn call_site() -> Span { + pub fn call_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::call_site()) } else { @@ -416,8 +416,8 @@ impl Span { } } - #[cfg(hygiene)] - pub fn mixed_site() -> Span { + #[cfg(not(no_hygiene))] + pub fn mixed_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::mixed_site()) } else { @@ -426,7 +426,7 @@ impl Span { } #[cfg(super_unstable)] - pub fn def_site() -> Span { + pub fn def_site() -> Self { if inside_proc_macro() { Span::Compiler(proc_macro::Span::def_site()) } else { @@ -436,11 +436,11 @@ impl Span { pub fn resolved_at(&self, other: Span) -> Span { match (self, other) { - #[cfg(hygiene)] + #[cfg(not(no_hygiene))] (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), // Name resolution affects semantics, but location is only cosmetic - #[cfg(not(hygiene))] + #[cfg(no_hygiene)] (Span::Compiler(_), Span::Compiler(_)) => other, (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), @@ -450,11 +450,11 @@ impl Span { pub fn located_at(&self, other: Span) -> Span { match (self, other) { - #[cfg(hygiene)] + #[cfg(not(no_hygiene))] (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), // Name resolution affects semantics, but location is only cosmetic - #[cfg(not(hygiene))] + #[cfg(no_hygiene)] (Span::Compiler(_), Span::Compiler(_)) => *self, (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), @@ -575,7 +575,7 @@ pub(crate) enum Group { } impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group { + pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { match stream { TokenStream::Compiler(tts) => { let delimiter = match delimiter { @@ -620,9 +620,9 @@ impl Group { pub fn span_open(&self) -> Span { match self { - #[cfg(proc_macro_span)] + #[cfg(not(no_group_open_close))] Group::Compiler(g) => Span::Compiler(g.span_open()), - #[cfg(not(proc_macro_span))] + #[cfg(no_group_open_close)] Group::Compiler(g) => Span::Compiler(g.span()), Group::Fallback(g) => Span::Fallback(g.span_open()), } @@ -630,9 +630,9 @@ impl Group { pub fn span_close(&self) -> Span { match self { - #[cfg(proc_macro_span)] + #[cfg(not(no_group_open_close))] Group::Compiler(g) => Span::Compiler(g.span_close()), - #[cfg(not(proc_macro_span))] + #[cfg(no_group_open_close)] Group::Compiler(g) => Span::Compiler(g.span()), Group::Fallback(g) => Span::Fallback(g.span_close()), } @@ -685,14 +685,14 @@ pub(crate) enum Ident { } impl Ident { - pub fn new(string: &str, span: Span) -> Ident { + pub fn new(string: &str, span: Span) -> Self { match span { Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), Span::Fallback(s) => Ident::Fallback(fallback::Ident::new(string, s)), } } - pub fn new_raw(string: &str, span: Span) -> Ident { + pub fn new_raw(string: &str, span: Span) -> Self { match span { Span::Compiler(s) => { let p: proc_macro::TokenStream = string.parse().unwrap(); @@ -804,6 +804,14 @@ macro_rules! unsuffixed_integers { } impl Literal { + pub unsafe fn from_str_unchecked(repr: &str) -> Self { + if inside_proc_macro() { + Literal::Compiler(compiler_literal_from_str(repr).expect("invalid literal")) + } else { + Literal::Fallback(fallback::Literal::from_str_unchecked(repr)) + } + } + suffixed_numbers! { u8_suffixed => u8, u16_suffixed => u16, @@ -921,25 +929,7 @@ impl FromStr for Literal { fn from_str(repr: &str) -> Result { if inside_proc_macro() { - #[cfg(literal_from_str)] - { - proc_macro::Literal::from_str(repr) - .map(Literal::Compiler) - .map_err(LexError::Compiler) - } - #[cfg(not(literal_from_str))] - { - let tokens = proc_macro_parse(repr)?; - let mut iter = tokens.into_iter(); - if let (Some(proc_macro::TokenTree::Literal(literal)), None) = - (iter.next(), iter.next()) - { - if literal.to_string().len() == repr.len() { - return Ok(Literal::Compiler(literal)); - } - } - Err(LexError::call_site()) - } + compiler_literal_from_str(repr).map(Literal::Compiler) } else { let literal = fallback::Literal::from_str(repr)?; Ok(Literal::Fallback(literal)) @@ -947,6 +937,24 @@ impl FromStr for Literal { } } +fn compiler_literal_from_str(repr: &str) -> Result { + #[cfg(not(no_literal_from_str))] + { + proc_macro::Literal::from_str(repr).map_err(LexError::Compiler) + } + #[cfg(no_literal_from_str)] + { + let tokens = proc_macro_parse(repr)?; + let mut iter = tokens.into_iter(); + if let (Some(proc_macro::TokenTree::Literal(literal)), None) = (iter.next(), iter.next()) { + if literal.to_string().len() == repr.len() { + return Ok(literal); + } + } + Err(LexError::call_site()) + } +} + impl Display for Literal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/tests/comments.rs b/tests/comments.rs index 708cccb..7174108 100644 --- a/tests/comments.rs +++ b/tests/comments.rs @@ -1,16 +1,16 @@ use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree}; // #[doc = "..."] -> "..." -fn lit_of_outer_doc_comment(tokens: TokenStream) -> Literal { +fn lit_of_outer_doc_comment(tokens: &TokenStream) -> Literal { lit_of_doc_comment(tokens, false) } // #![doc = "..."] -> "..." -fn lit_of_inner_doc_comment(tokens: TokenStream) -> Literal { +fn lit_of_inner_doc_comment(tokens: &TokenStream) -> Literal { lit_of_doc_comment(tokens, true) } -fn lit_of_doc_comment(tokens: TokenStream, inner: bool) -> Literal { +fn lit_of_doc_comment(tokens: &TokenStream, inner: bool) -> Literal { let mut iter = tokens.clone().into_iter(); match iter.next().unwrap() { TokenTree::Punct(punct) => { @@ -71,30 +71,30 @@ fn incomplete() { #[test] fn lit() { let stream = "/// doc".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(stream); + let lit = lit_of_outer_doc_comment(&stream); assert_eq!(lit.to_string(), "\" doc\""); let stream = "//! doc".parse::().unwrap(); - let lit = lit_of_inner_doc_comment(stream); + let lit = lit_of_inner_doc_comment(&stream); assert_eq!(lit.to_string(), "\" doc\""); let stream = "/** doc */".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(stream); + let lit = lit_of_outer_doc_comment(&stream); assert_eq!(lit.to_string(), "\" doc \""); let stream = "/*! doc */".parse::().unwrap(); - let lit = lit_of_inner_doc_comment(stream); + let lit = lit_of_inner_doc_comment(&stream); assert_eq!(lit.to_string(), "\" doc \""); } #[test] fn carriage_return() { let stream = "///\r\n".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(stream); + let lit = lit_of_outer_doc_comment(&stream); assert_eq!(lit.to_string(), "\"\""); let stream = "/**\r\n*/".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(stream); + let lit = lit_of_outer_doc_comment(&stream); assert_eq!(lit.to_string(), "\"\\r\\n\""); "///\r".parse::().unwrap_err(); diff --git a/tests/marker.rs b/tests/marker.rs index 70e5767..4fb2beb 100644 --- a/tests/marker.rs +++ b/tests/marker.rs @@ -1,4 +1,6 @@ -use proc_macro2::*; +use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, +}; macro_rules! assert_impl { ($ty:ident is $($marker:ident) and +) => { @@ -51,7 +53,7 @@ assert_impl!(TokenTree is not Send or Sync); #[cfg(procmacro2_semver_exempt)] mod semver_exempt { - use super::*; + use proc_macro2::{LineColumn, SourceFile}; assert_impl!(LineColumn is Send and Sync); @@ -60,7 +62,11 @@ mod semver_exempt { #[cfg(not(no_libprocmacro_unwind_safe))] mod unwind_safe { - use super::*; + use proc_macro2::{ + Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, + }; + #[cfg(procmacro2_semver_exempt)] + use proc_macro2::{LineColumn, SourceFile}; use std::panic::{RefUnwindSafe, UnwindSafe}; macro_rules! assert_unwind_safe { diff --git a/tests/test.rs b/tests/test.rs index 75a880f..ab82390 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,3 +1,5 @@ +#![allow(clippy::non_ascii_literal)] + use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; use std::panic; use std::str::{self, FromStr}; @@ -166,7 +168,11 @@ fn literal_iter_negative() { #[test] fn literal_parse() { assert!("1".parse::().is_ok()); + assert!("-1".parse::().is_ok()); + assert!("-1u12".parse::().is_ok()); assert!("1.0".parse::().is_ok()); + assert!("-1.0".parse::().is_ok()); + assert!("-1.0f12".parse::().is_ok()); assert!("'a'".parse::().is_ok()); assert!("\"\n\"".parse::().is_ok()); assert!("0 1".parse::().is_err()); @@ -175,6 +181,9 @@ fn literal_parse() { assert!("/* comment */0".parse::().is_err()); assert!("0/* comment */".parse::().is_err()); assert!("0// comment".parse::().is_err()); + assert!("- 1".parse::().is_err()); + assert!("- 1.0".parse::().is_err()); + assert!("-\"\"".parse::().is_err()); } #[test] @@ -183,7 +192,7 @@ fn roundtrip() { println!("parse: {}", p); let s = p.parse::().unwrap().to_string(); println!("first: {}", s); - let s2 = s.to_string().parse::().unwrap().to_string(); + let s2 = s.parse::().unwrap().to_string(); assert_eq!(s, s2); } roundtrip("a"); @@ -479,7 +488,7 @@ TokenStream [ #[test] fn default_tokenstream_is_empty() { - let default_token_stream: TokenStream = Default::default(); + let default_token_stream = ::default(); assert!(default_token_stream.is_empty()); } diff --git a/tests/test_fmt.rs b/tests/test_fmt.rs index 99a0aee..93dd19e 100644 --- a/tests/test_fmt.rs +++ b/tests/test_fmt.rs @@ -1,3 +1,5 @@ +#![allow(clippy::from_iter_instead_of_collect)] + use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; use std::iter::{self, FromIterator}; @@ -12,7 +14,7 @@ fn test_fmt_group() { let braces_empty = Group::new(Delimiter::Brace, TokenStream::new()); let braces_nonempty = Group::new(Delimiter::Brace, inner.clone()); let none_empty = Group::new(Delimiter::None, TokenStream::new()); - let none_nonempty = Group::new(Delimiter::None, inner.clone()); + let none_nonempty = Group::new(Delimiter::None, inner); // Matches libproc_macro. assert_eq!("()", parens_empty.to_string()); -- cgit v1.2.3