aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2019-09-30 10:08:21 -0700
committerChih-Hung Hsieh <chh@google.com>2019-09-30 10:58:41 -0700
commit1c4237a4269e453146942dcd7a2fbf57e2f0cbdd (patch)
tree531d0f7a9203b847f5c71df2f9e37c1ee18dd5dc
parent8379c689d8dff544f9104c55942ad8d6a39c19ac (diff)
parentbdac3732544a3cfb73afe4548f550c369e906856 (diff)
downloadproc-macro2-1c4237a4269e453146942dcd7a2fbf57e2f0cbdd.tar.gz
Merge aosp/upstream-master to release 1.0.4
* Enable deny_warnings. * Upgrade to edition 2018. Test: mm in projects with Rust modules Change-Id: I13d86d546afa2f5f39c69409d41dc9cd41b3a474
-rw-r--r--.travis.yml2
-rw-r--r--Android.bp3
-rw-r--r--Cargo.toml18
-rw-r--r--README.md39
-rw-r--r--build.rs52
-rw-r--r--src/fallback.rs173
-rw-r--r--src/lib.rs171
-rw-r--r--src/strnom.rs6
-rw-r--r--src/wrapper.rs98
-rw-r--r--tests/features.rs8
-rw-r--r--tests/marker.rs2
-rw-r--r--tests/test.rs24
12 files changed, 297 insertions, 299 deletions
diff --git a/.travis.yml b/.travis.yml
index 8f17d02..acddb57 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,6 @@ sudo: false
matrix:
include:
- - rust: 1.15.0
- rust: 1.31.0
- rust: stable
- rust: beta
@@ -11,6 +10,7 @@ matrix:
script:
- cargo test
- cargo test --no-default-features
+ - cargo test --no-default-features -- --ignored # run the ignored test to make sure the `proc-macro` feature is disabled
- cargo test --features span-locations
- RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test
- RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo test --no-default-features
diff --git a/Android.bp b/Android.bp
index 51daa20..5d03a89 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,6 +1,5 @@
rust_library_rlib {
name: "libproc_macro2",
- deny_warnings: false,
host_supported: true,
crate_name: "proc_macro2",
srcs: ["src/lib.rs"],
@@ -14,5 +13,5 @@ rust_library_rlib {
"default",
"proc-macro",
],
- edition: "2015",
+ edition: "2018",
}
diff --git a/Cargo.toml b/Cargo.toml
index f173c9c..fd5ee70 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,29 +1,32 @@
[package]
name = "proc-macro2"
-version = "0.4.30" # remember to update html_root_url
+version = "1.0.4" # remember to update html_root_url
authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
readme = "README.md"
keywords = ["macros"]
repository = "https://github.com/alexcrichton/proc-macro2"
homepage = "https://github.com/alexcrichton/proc-macro2"
documentation = "https://docs.rs/proc-macro2"
-build = "build.rs"
+edition = "2018"
description = """
A stable implementation of the upcoming new `proc_macro` API. Comes with an
option, off by default, to also reimplement itself in terms of the upstream
unstable API.
"""
+[lib]
+name = "proc_macro2"
+
[package.metadata.docs.rs]
rustc-args = ["--cfg", "procmacro2_semver_exempt"]
rustdoc-args = ["--cfg", "procmacro2_semver_exempt"]
[dependencies]
-unicode-xid = "0.1"
+unicode-xid = "0.2"
[dev-dependencies]
-quote = "0.6"
+quote = { version = "1.0", default_features = false }
[features]
proc-macro = []
@@ -46,11 +49,6 @@ travis-ci = { repository = "alexcrichton/proc-macro2" }
# meaning impls would be missing when tested against types from the local
# proc-macro2.
#
-# When publishing proc-macro2, Cargo will forbid publishing with a patch
-# section. You need to delete this section and then publish with --allow-dirty.
-# A PR https://github.com/rust-lang/cargo/pull/6535 proposes to make it no
-# longer an error to publish with a patch section.
-#
# Travis builds that are in progress at the time that you publish may spuriously
# fail. This is because they'll be building a local proc-macro2 which carries
# the second-most-recent version number, pulling in quote which resolves to a
diff --git a/README.md b/README.md
index 67d523d..19b0c3b 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/proc-macro2)
A wrapper around the procedural macro API of the compiler's `proc_macro` crate.
-This library serves three purposes:
+This library serves two purposes:
- **Bring proc-macro-like functionality to other contexts like build.rs and
main.rs.** Types from `proc_macro` are entirely specific to procedural macros
@@ -21,13 +21,6 @@ This library serves three purposes:
unit test. In order for helper libraries or components of a macro to be
testable in isolation, they must be implemented using `proc_macro2`.
-- **Provide the latest and greatest APIs across all compiler versions.**
- Procedural macros were first introduced to Rust in 1.15.0 with an extremely
- minimal interface. Since then, many improvements have landed to make macros
- more flexible and easier to write. This library tracks the procedural macro
- API of the most recent stable compiler but employs a polyfill to provide that
- API consistently across any compiler since 1.15.0.
-
[syn]: https://github.com/dtolnay/syn
[quote]: https://github.com/dtolnay/quote
@@ -35,7 +28,7 @@ This library serves three purposes:
```toml
[dependencies]
-proc-macro2 = "0.4"
+proc-macro2 = "1.0"
```
The skeleton of a typical procedural macro typically looks like this:
@@ -58,7 +51,7 @@ pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate
parse errors correctly back to the compiler when parsing fails.
-[`parse_macro_input!`]: https://docs.rs/syn/0.15/syn/macro.parse_macro_input.html
+[`parse_macro_input!`]: https://docs.rs/syn/1.0/syn/macro.parse_macro_input.html
## Unstable features
@@ -67,10 +60,10 @@ API. Functionality in `proc_macro` that is not yet stable is not exposed by
proc-macro2 by default.
To opt into the additional APIs available in the most recent nightly compiler,
-the `procmacro2_semver_exempt` config flag must be passed to rustc. As usual, we
-will polyfill those nightly-only APIs all the way back to Rust 1.15.0. As these
-are unstable APIs that track the nightly compiler, minor versions of proc-macro2
-may make breaking changes to them at any time.
+the `procmacro2_semver_exempt` config flag must be passed to rustc. We will
+polyfill those nightly-only APIs back to Rust 1.31.0. As these are unstable APIs
+that track the nightly compiler, minor versions of proc-macro2 may make breaking
+changes to them at any time.
```
RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
@@ -82,19 +75,19 @@ reminder that you are outside of the normal semver guarantees.
Semver exempt methods are marked as such in the proc-macro2 documentation.
-# License
-
-This project is licensed under either of
+<br>
- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
- http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or
- http://opensource.org/licenses/MIT)
+#### License
-at your option.
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
-### Contribution
+<br>
+<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/build.rs b/build.rs
index 187255f..deb9b92 100644
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,5 @@
// rustc-cfg emitted by the build script:
//
-// "u128"
-// Include u128 and i128 constructors for proc_macro2::Literal. Enabled on
-// any compiler 1.26+.
-//
// "use_proc_macro"
// Link to extern crate proc_macro. Available on any compiler and any target
// except wasm32. Requires "proc-macro" Cargo cfg to be enabled (default is
@@ -18,11 +14,6 @@
// procmacro2_semver_exempt surface area is implemented by using the
// nightly-only proc_macro API.
//
-// "slow_extend"
-// Fallback when `impl Extend for TokenStream` is not available. These impls
-// were added one version later than the rest of the proc_macro token API.
-// Enabled on rustc 1.29 only.
-//
// "proc_macro_span"
// Enable non-dummy behavior of Span::start and Span::end methods which
// requires an unstable compiler feature. Enabled when building with
@@ -40,21 +31,20 @@
// location inside spans is a performance hit.
use std::env;
-use std::process::Command;
+use std::process::{self, Command};
use std::str;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
- let target = env::var("TARGET").unwrap();
-
let version = match rustc_version() {
Some(version) => version,
None => return,
};
- if version.minor >= 26 {
- println!("cargo:rustc-cfg=u128");
+ if version.minor < 31 {
+ eprintln!("Minimum supported rustc version is 1.31");
+ process::exit(1);
}
let semver_exempt = cfg!(procmacro2_semver_exempt);
@@ -67,21 +57,17 @@ fn main() {
println!("cargo:rustc-cfg=span_locations");
}
+ let target = env::var("TARGET").unwrap();
if !enable_use_proc_macro(&target) {
return;
}
println!("cargo:rustc-cfg=use_proc_macro");
- // Rust 1.29 stabilized the necessary APIs in the `proc_macro` crate
- if version.nightly || version.minor >= 29 && !semver_exempt {
+ if version.nightly || !semver_exempt {
println!("cargo:rustc-cfg=wrap_proc_macro");
}
- if version.minor == 29 {
- println!("cargo:rustc-cfg=slow_extend");
- }
-
if version.nightly && feature_allowed("proc_macro_span") {
println!("cargo:rustc-cfg=proc_macro_span");
}
@@ -107,30 +93,16 @@ struct RustcVersion {
}
fn rustc_version() -> Option<RustcVersion> {
- macro_rules! otry {
- ($e:expr) => {
- match $e {
- Some(e) => e,
- None => return None,
- }
- };
- }
-
- let rustc = otry!(env::var_os("RUSTC"));
- let output = otry!(Command::new(rustc).arg("--version").output().ok());
- let version = otry!(str::from_utf8(&output.stdout).ok());
- let nightly = version.contains("nightly");
+ let rustc = env::var_os("RUSTC")?;
+ let output = Command::new(rustc).arg("--version").output().ok()?;
+ let version = str::from_utf8(&output.stdout).ok()?;
+ let nightly = version.contains("nightly") || version.contains("dev");
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
- let minor = otry!(pieces.next());
- let minor = otry!(minor.parse().ok());
-
- Some(RustcVersion {
- minor: minor,
- nightly: nightly,
- })
+ let minor = pieces.next()?.parse().ok()?;
+ Some(RustcVersion { minor, nightly })
}
fn feature_allowed(feature: &str) -> bool {
diff --git a/src/fallback.rs b/src/fallback.rs
index f40a874..fe582b3 100644
--- a/src/fallback.rs
+++ b/src/fallback.rs
@@ -1,20 +1,20 @@
#[cfg(span_locations)]
use std::cell::RefCell;
-#[cfg(procmacro2_semver_exempt)]
+#[cfg(span_locations)]
use std::cmp;
use std::fmt;
use std::iter;
+use std::ops::RangeBounds;
#[cfg(procmacro2_semver_exempt)]
use std::path::Path;
use std::path::PathBuf;
use std::str::FromStr;
use std::vec;
-use strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
+use crate::strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
+use crate::{Delimiter, Punct, Spacing, TokenTree};
use unicode_xid::UnicodeXID;
-use {Delimiter, Punct, Spacing, TokenTree};
-
#[derive(Clone)]
pub struct TokenStream {
inner: Vec<TokenTree>,
@@ -118,8 +118,8 @@ impl fmt::Debug for TokenStream {
}
#[cfg(use_proc_macro)]
-impl From<::proc_macro::TokenStream> for TokenStream {
- fn from(inner: ::proc_macro::TokenStream) -> TokenStream {
+impl From<proc_macro::TokenStream> for TokenStream {
+ fn from(inner: proc_macro::TokenStream) -> TokenStream {
inner
.to_string()
.parse()
@@ -128,8 +128,8 @@ impl From<::proc_macro::TokenStream> for TokenStream {
}
#[cfg(use_proc_macro)]
-impl From<TokenStream> for ::proc_macro::TokenStream {
- fn from(inner: TokenStream) -> ::proc_macro::TokenStream {
+impl From<TokenStream> for proc_macro::TokenStream {
+ fn from(inner: TokenStream) -> proc_macro::TokenStream {
inner
.to_string()
.parse()
@@ -314,22 +314,19 @@ impl SourceMap {
let lo = self.next_start_pos();
// XXX(nika): Shouild we bother doing a checked cast or checked add here?
let span = Span {
- lo: lo,
+ lo,
hi: lo + (src.len() as u32),
};
#[cfg(procmacro2_semver_exempt)]
self.files.push(FileInfo {
name: name.to_owned(),
- span: span,
- lines: lines,
+ span,
+ lines,
});
#[cfg(not(procmacro2_semver_exempt))]
- self.files.push(FileInfo {
- span: span,
- lines: lines,
- });
+ self.files.push(FileInfo { span, lines });
let _ = name;
span
@@ -411,7 +408,12 @@ impl Span {
})
}
- #[cfg(procmacro2_semver_exempt)]
+ #[cfg(not(span_locations))]
+ pub fn join(&self, _other: Span) -> Option<Span> {
+ Some(Span {})
+ }
+
+ #[cfg(span_locations)]
pub fn join(&self, other: Span) -> Option<Span> {
SOURCE_MAP.with(|cm| {
let cm = cm.borrow();
@@ -453,8 +455,8 @@ pub struct Group {
impl Group {
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
Group {
- delimiter: delimiter,
- stream: stream,
+ delimiter,
+ stream,
span: Span::call_site(),
}
}
@@ -471,12 +473,10 @@ impl Group {
self.span
}
- #[cfg(procmacro2_semver_exempt)]
pub fn span_open(&self) -> Span {
self.span
}
- #[cfg(procmacro2_semver_exempt)]
pub fn span_close(&self) -> Span {
self.span
}
@@ -527,8 +527,8 @@ impl Ident {
Ident {
sym: string.to_owned(),
- span: span,
- raw: raw,
+ span,
+ raw,
}
}
@@ -671,7 +671,7 @@ macro_rules! unsuffixed_numbers {
impl Literal {
fn _new(text: String) -> Literal {
Literal {
- text: text,
+ text,
span: Span::call_site(),
}
}
@@ -681,40 +681,32 @@ impl Literal {
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
+ u128_suffixed => u128,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
+ i128_suffixed => i128,
isize_suffixed => isize,
f32_suffixed => f32,
f64_suffixed => f64,
}
- #[cfg(u128)]
- suffixed_numbers! {
- u128_suffixed => u128,
- i128_suffixed => i128,
- }
-
unsuffixed_numbers! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
- isize_unsuffixed => isize,
- }
-
- #[cfg(u128)]
- unsuffixed_numbers! {
- u128_unsuffixed => u128,
i128_unsuffixed => i128,
+ isize_unsuffixed => isize,
}
pub fn f32_unsuffixed(f: f32) -> Literal {
@@ -771,7 +763,7 @@ impl Literal {
b'\r' => escaped.push_str(r"\r"),
b'"' => escaped.push_str("\\\""),
b'\\' => escaped.push_str("\\\\"),
- b'\x20'...b'\x7E' => escaped.push(*b as char),
+ b'\x20'..=b'\x7E' => escaped.push(*b as char),
_ => escaped.push_str(&format!("\\x{:02X}", b)),
}
}
@@ -786,6 +778,10 @@ impl Literal {
pub fn set_span(&mut self, span: Span) {
self.span = span;
}
+
+ pub fn subspan<R: RangeBounds<usize>>(&self, _range: R) -> Option<Span> {
+ None
+ }
}
impl fmt::Display for Literal {
@@ -831,21 +827,21 @@ fn token_stream(mut input: Cursor) -> PResult<TokenStream> {
fn spanned<'a, T>(
input: Cursor<'a>,
f: fn(Cursor<'a>) -> PResult<'a, T>,
-) -> PResult<'a, (T, ::Span)> {
+) -> PResult<'a, (T, crate::Span)> {
let (a, b) = f(skip_whitespace(input))?;
- Ok((a, ((b, ::Span::_new_stable(Span::call_site())))))
+ Ok((a, ((b, crate::Span::_new_stable(Span::call_site())))))
}
#[cfg(span_locations)]
fn spanned<'a, T>(
input: Cursor<'a>,
f: fn(Cursor<'a>) -> PResult<'a, T>,
-) -> PResult<'a, (T, ::Span)> {
+) -> PResult<'a, (T, crate::Span)> {
let input = skip_whitespace(input);
let lo = input.off;
let (a, b) = f(input)?;
let hi = a.off;
- let span = ::Span::_new_stable(Span { lo: lo, hi: hi });
+ let span = crate::Span::_new_stable(Span { lo, hi });
Ok((a, (b, span)))
}
@@ -856,9 +852,9 @@ fn token_tree(input: Cursor) -> PResult<TokenTree> {
}
named!(token_kind -> TokenTree, alt!(
- map!(group, |g| TokenTree::Group(::Group::_new_stable(g)))
+ map!(group, |g| TokenTree::Group(crate::Group::_new_stable(g)))
|
- map!(literal, |l| TokenTree::Literal(::Literal::_new_stable(l))) // must be before symbol
+ map!(literal, |l| TokenTree::Literal(crate::Literal::_new_stable(l))) // must be before symbol
|
map!(op, TokenTree::Punct)
|
@@ -890,14 +886,27 @@ fn symbol_leading_ws(input: Cursor) -> PResult<TokenTree> {
}
fn symbol(input: Cursor) -> PResult<TokenTree> {
- let mut chars = input.char_indices();
-
let raw = input.starts_with("r#");
- if raw {
- chars.next();
- chars.next();
+ let rest = input.advance((raw as usize) << 1);
+
+ let (rest, sym) = symbol_not_raw(rest)?;
+
+ if !raw {
+ let ident = crate::Ident::new(sym, crate::Span::call_site());
+ return Ok((rest, ident.into()));
+ }
+
+ if sym == "_" {
+ return Err(LexError);
}
+ let ident = crate::Ident::_new_raw(sym, crate::Span::call_site());
+ Ok((rest, ident.into()))
+}
+
+fn symbol_not_raw(input: Cursor) -> PResult<&str> {
+ let mut chars = input.char_indices();
+
match chars.next() {
Some((_, ch)) if is_ident_start(ch) => {}
_ => return Err(LexError),
@@ -911,17 +920,7 @@ fn symbol(input: Cursor) -> PResult<TokenTree> {
}
}
- let a = &input.rest[..end];
- if a == "r#_" {
- Err(LexError)
- } else {
- let ident = if raw {
- ::Ident::_new_raw(&a[2..], ::Span::call_site())
- } else {
- ::Ident::new(a, ::Span::call_site())
- };
- Ok((input.advance(end), ident.into()))
- }
+ Ok((input.advance(end), &input.rest[..end]))
}
fn literal(input: Cursor) -> PResult<Literal> {
@@ -961,10 +960,12 @@ named!(string -> (), alt!(
) => { |_| () }
));
-named!(quoted_string -> (), delimited!(
- punct!("\""),
- cooked_string,
- tag!("\"")
+named!(quoted_string -> (), do_parse!(
+ punct!("\"") >>
+ cooked_string >>
+ tag!("\"") >>
+ option!(symbol_not_raw) >>
+ (())
));
fn cooked_string(input: Cursor) -> PResult<()> {
@@ -1173,8 +1174,8 @@ fn backslash_x_char<I>(chars: &mut I) -> bool
where
I: Iterator<Item = (usize, char)>,
{
- next_ch!(chars @ '0'...'7');
- next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
+ next_ch!(chars @ '0'..='7');
+ next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F');
true
}
@@ -1182,8 +1183,8 @@ fn backslash_x_byte<I>(chars: &mut I) -> bool
where
I: Iterator<Item = (usize, u8)>,
{
- next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
- next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
+ next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F');
+ next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F');
true
}
@@ -1192,9 +1193,9 @@ where
I: Iterator<Item = (usize, char)>,
{
next_ch!(chars @ '{');
- next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
+ next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F');
loop {
- let c = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '_' | '}');
+ let c = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F' | '_' | '}');
if c == '}' {
return true;
}
@@ -1202,10 +1203,10 @@ where
}
fn float(input: Cursor) -> PResult<()> {
- let (rest, ()) = float_digits(input)?;
- for suffix in &["f32", "f64"] {
- if rest.starts_with(suffix) {
- return word_break(rest.advance(suffix.len()));
+ let (mut rest, ()) = float_digits(input)?;
+ if let Some(ch) = rest.chars().next() {
+ if is_ident_start(ch) {
+ rest = symbol_not_raw(rest)?.0;
}
}
word_break(rest)
@@ -1223,7 +1224,7 @@ fn float_digits(input: Cursor) -> PResult<()> {
let mut has_exp = false;
while let Some(&ch) = chars.peek() {
match ch {
- '0'...'9' | '_' => {
+ '0'..='9' | '_' => {
chars.next();
len += 1;
}
@@ -1234,7 +1235,7 @@ fn float_digits(input: Cursor) -> PResult<()> {
chars.next();
if chars
.peek()
- .map(|&ch| ch == '.' || UnicodeXID::is_xid_start(ch))
+ .map(|&ch| ch == '.' || is_ident_start(ch))
.unwrap_or(false)
{
return Err(LexError);
@@ -1268,7 +1269,7 @@ fn float_digits(input: Cursor) -> PResult<()> {
chars.next();
len += 1;
}
- '0'...'9' => {
+ '0'..='9' => {
chars.next();
len += 1;
has_exp_value = true;
@@ -1289,12 +1290,10 @@ fn float_digits(input: Cursor) -> PResult<()> {
}
fn int(input: Cursor) -> PResult<()> {
- let (rest, ()) = digits(input)?;
- for suffix in &[
- "isize", "i8", "i16", "i32", "i64", "i128", "usize", "u8", "u16", "u32", "u64", "u128",
- ] {
- if rest.starts_with(suffix) {
- return word_break(rest.advance(suffix.len()));
+ let (mut rest, ()) = digits(input)?;
+ if let Some(ch) = rest.chars().next() {
+ if is_ident_start(ch) {
+ rest = symbol_not_raw(rest)?.0;
}
}
word_break(rest)
@@ -1318,9 +1317,9 @@ fn digits(mut input: Cursor) -> PResult<()> {
let mut empty = true;
for b in input.bytes() {
let digit = match b {
- b'0'...b'9' => (b - b'0') as u64,
- b'a'...b'f' => 10 + (b - b'a') as u64,
- b'A'...b'F' => 10 + (b - b'A') as u64,
+ b'0'..=b'9' => (b - b'0') as u64,
+ b'a'..=b'f' => 10 + (b - b'a') as u64,
+ b'A'..=b'F' => 10 + (b - b'A') as u64,
b'_' => {
if empty && base == 10 {
return Err(LexError);
@@ -1390,15 +1389,15 @@ fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
trees.push(Punct::new('!', Spacing::Alone).into());
}
let mut stream = vec![
- TokenTree::Ident(::Ident::new("doc", span)),
+ TokenTree::Ident(crate::Ident::new("doc", span)),
TokenTree::Punct(Punct::new('=', Spacing::Alone)),
- TokenTree::Literal(::Literal::string(comment)),
+ TokenTree::Literal(crate::Literal::string(comment)),
];
for tt in stream.iter_mut() {
tt.set_span(span);
}
let group = Group::new(Delimiter::Bracket, stream.into_iter().collect());
- trees.push(::Group::_new_stable(group).into());
+ trees.push(crate::Group::_new_stable(group).into());
for tt in trees.iter_mut() {
tt.set_span(span);
}
diff --git a/src/lib.rs b/src/lib.rs
index 7181455..ad9e301 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,5 @@
//! A wrapper around the procedural macro API of the compiler's [`proc_macro`]
-//! crate. This library serves three purposes:
+//! crate. This library serves two purposes:
//!
//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
//!
@@ -18,14 +18,6 @@
//! a macro to be testable in isolation, they must be implemented using
//! `proc_macro2`.
//!
-//! - **Provide the latest and greatest APIs across all compiler versions.**
-//! Procedural macros were first introduced to Rust in 1.15.0 with an
-//! extremely minimal interface. Since then, many improvements have landed to
-//! make macros more flexible and easier to write. This library tracks the
-//! procedural macro API of the most recent stable compiler but employs a
-//! polyfill to provide that API consistently across any compiler since
-//! 1.15.0.
-//!
//! [syn]: https://github.com/dtolnay/syn
//! [quote]: https://github.com/dtolnay/quote
//!
@@ -33,12 +25,13 @@
//!
//! The skeleton of a typical procedural macro typically looks like this:
//!
-//! ```edition2018
+//! ```
//! extern crate proc_macro;
//!
//! # const IGNORE: &str = stringify! {
//! #[proc_macro_derive(MyDerive)]
//! # };
+//! # #[cfg(wrap_proc_macro)]
//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
//! let input = proc_macro2::TokenStream::from(input);
//!
@@ -54,7 +47,7 @@
//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to
//! propagate parse errors correctly back to the compiler when parsing fails.
//!
-//! [`parse_macro_input!`]: https://docs.rs/syn/0.15/syn/macro.parse_macro_input.html
+//! [`parse_macro_input!`]: https://docs.rs/syn/1.0/syn/macro.parse_macro_input.html
//!
//! # Unstable features
//!
@@ -64,9 +57,9 @@
//!
//! To opt into the additional APIs available in the most recent nightly
//! compiler, the `procmacro2_semver_exempt` config flag must be passed to
-//! rustc. As usual, we will polyfill those nightly-only APIs all the way back
-//! to Rust 1.15.0. As these are unstable APIs that track the nightly compiler,
-//! minor versions of proc-macro2 may make breaking changes to them at any time.
+//! rustc. We will polyfill those nightly-only APIs back to Rust 1.31.0. As
+//! these are unstable APIs that track the nightly compiler, minor versions of
+//! proc-macro2 may make breaking changes to them at any time.
//!
//! ```sh
//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
@@ -77,21 +70,27 @@
//! as a reminder that you are outside of the normal semver guarantees.
//!
//! Semver exempt methods are marked as such in the proc-macro2 documentation.
+//!
+//! # Thread-Safety
+//!
+//! Most types in this crate are `!Sync` because the underlying compiler
+//! types make use of thread-local memory, meaning they cannot be accessed from
+//! a different thread.
// Proc-macro2 types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.30")]
+#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.4")]
#![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(use_proc_macro)]
extern crate proc_macro;
-extern crate unicode_xid;
use std::cmp::Ordering;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::marker;
+use std::ops::RangeBounds;
#[cfg(procmacro2_semver_exempt)]
use std::path::PathBuf;
use std::rc::Rc;
@@ -102,7 +101,7 @@ mod strnom;
mod fallback;
#[cfg(not(wrap_proc_macro))]
-use fallback as imp;
+use crate::fallback as imp;
#[path = "wrapper.rs"]
#[cfg(wrap_proc_macro)]
mod imp;
@@ -129,7 +128,7 @@ pub struct LexError {
impl TokenStream {
fn _new(inner: imp::TokenStream) -> TokenStream {
TokenStream {
- inner: inner,
+ inner,
_marker: marker::PhantomData,
}
}
@@ -146,11 +145,6 @@ impl TokenStream {
TokenStream::_new(imp::TokenStream::new())
}
- #[deprecated(since = "0.4.4", note = "please use TokenStream::new")]
- pub fn empty() -> TokenStream {
- TokenStream::new()
- }
-
/// Checks if this `TokenStream` is empty.
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
@@ -199,6 +193,12 @@ impl From<TokenStream> for proc_macro::TokenStream {
}
}
+impl From<TokenTree> for TokenStream {
+ fn from(token: TokenTree) -> Self {
+ TokenStream::_new(imp::TokenStream::from(token))
+ }
+}
+
impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
self.inner.extend(streams)
@@ -261,7 +261,7 @@ pub struct SourceFile {
impl SourceFile {
fn _new(inner: imp::SourceFile) -> Self {
SourceFile {
- inner: inner,
+ inner,
_marker: marker::PhantomData,
}
}
@@ -321,7 +321,7 @@ pub struct Span {
impl Span {
fn _new(inner: imp::Span) -> Span {
Span {
- inner: inner,
+ inner,
_marker: marker::PhantomData,
}
}
@@ -404,10 +404,7 @@ impl Span {
#[cfg(span_locations)]
pub fn start(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.start();
- LineColumn {
- line: line,
- column: column,
- }
+ LineColumn { line, column }
}
/// Get the ending line/column in the source file for this span.
@@ -416,23 +413,23 @@ impl Span {
#[cfg(span_locations)]
pub fn end(&self) -> LineColumn {
let imp::LineColumn { line, column } = self.inner.end();
- LineColumn {
- line: line,
- column: column,
- }
+ LineColumn { line, column }
}
/// Create a new span encompassing `self` and `other`.
///
/// Returns `None` if `self` and `other` are from different files.
///
- /// This method is semver exempt and not exposed by default.
- #[cfg(procmacro2_semver_exempt)]
+ /// Warning: the underlying [`proc_macro::Span::join`] method is
+ /// nightly-only. When called from within a procedural macro not using a
+ /// nightly compiler, this method will always return `None`.
+ ///
+ /// [`proc_macro::Span::join`]: https://doc.rust-lang.org/proc_macro/struct.Span.html#method.join
pub fn join(&self, other: Span) -> Option<Span> {
self.inner.join(other.inner).map(Span::_new)
}
- /// Compares to spans to see if they're equal.
+ /// Compares two spans to see if they're equal.
///
/// This method is semver exempt and not exposed by default.
#[cfg(procmacro2_semver_exempt)]
@@ -576,7 +573,7 @@ pub enum Delimiter {
impl Group {
fn _new(inner: imp::Group) -> Self {
- Group { inner: inner }
+ Group { inner }
}
fn _new_stable(inner: fallback::Group) -> Self {
@@ -626,7 +623,6 @@ impl Group {
/// pub fn span_open(&self) -> Span {
/// ^
/// ```
- #[cfg(procmacro2_semver_exempt)]
pub fn span_open(&self) -> Span {
Span::_new(self.inner.span_open())
}
@@ -637,7 +633,6 @@ impl Group {
/// pub fn span_close(&self) -> Span {
/// ^
/// ```
- #[cfg(procmacro2_semver_exempt)]
pub fn span_close(&self) -> Span {
Span::_new(self.inner.span_close())
}
@@ -685,7 +680,7 @@ pub struct Punct {
pub enum Spacing {
/// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
Alone,
- /// E.g. `+` is `Joint` in `+=` or `'#`.
+ /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`.
///
/// Additionally, single quote `'` can join with identifiers to form
/// lifetimes `'ident`.
@@ -702,8 +697,8 @@ impl Punct {
/// which can be further configured with the `set_span` method below.
pub fn new(op: char, spacing: Spacing) -> Punct {
Punct {
- op: op,
- spacing: spacing,
+ op,
+ spacing,
span: Span::call_site(),
}
}
@@ -765,7 +760,7 @@ impl fmt::Debug for Punct {
/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the
/// behaviour of `Ident::new`.
///
-/// [`Parse`]: https://docs.rs/syn/0.15/syn/parse/trait.Parse.html
+/// [`Parse`]: https://docs.rs/syn/1.0/syn/parse/trait.Parse.html
///
/// # Examples
///
@@ -773,7 +768,7 @@ impl fmt::Debug for Punct {
/// A span must be provided explicitly which governs the name resolution
/// behavior of the resulting identifier.
///
-/// ```edition2018
+/// ```
/// use proc_macro2::{Ident, Span};
///
/// fn main() {
@@ -785,7 +780,7 @@ impl fmt::Debug for Punct {
///
/// An ident can be interpolated into a token stream using the `quote!` macro.
///
-/// ```edition2018
+/// ```
/// use proc_macro2::{Ident, Span};
/// use quote::quote;
///
@@ -804,7 +799,7 @@ impl fmt::Debug for Punct {
/// A string representation of the ident is available through the `to_string()`
/// method.
///
-/// ```edition2018
+/// ```
/// # use proc_macro2::{Ident, Span};
/// #
/// # let ident = Ident::new("another_identifier", Span::call_site());
@@ -824,7 +819,7 @@ pub struct Ident {
impl Ident {
fn _new(inner: imp::Ident) -> Ident {
Ident {
- inner: inner,
+ inner,
_marker: marker::PhantomData,
}
}
@@ -856,7 +851,7 @@ impl Ident {
/// Panics if the input string is neither a keyword nor a legal variable
/// name. If you are not sure whether the string contains an identifier and
/// need to handle an error case, use
- /// <a href="https://docs.rs/syn/0.15/syn/fn.parse_str.html"><code
+ /// <a href="https://docs.rs/syn/1.0/syn/fn.parse_str.html"><code
/// style="padding-right:0;">syn::parse_str</code></a><code
/// style="padding-left:0;">::&lt;Ident&gt;</code>
/// rather than `Ident::new`.
@@ -992,7 +987,7 @@ macro_rules! unsuffixed_int_literals {
impl Literal {
fn _new(inner: imp::Literal) -> Literal {
Literal {
- inner: inner,
+ inner,
_marker: marker::PhantomData,
}
}
@@ -1009,18 +1004,14 @@ impl Literal {
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
+ u128_suffixed => u128,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
- isize_suffixed => isize,
- }
-
- #[cfg(u128)]
- suffixed_int_literals! {
- u128_suffixed => u128,
i128_suffixed => i128,
+ isize_suffixed => isize,
}
unsuffixed_int_literals! {
@@ -1028,25 +1019,47 @@ impl Literal {
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
- isize_unsuffixed => isize,
- }
-
- #[cfg(u128)]
- unsuffixed_int_literals! {
- u128_unsuffixed => u128,
i128_unsuffixed => i128,
+ isize_unsuffixed => isize,
}
+ /// Creates a new unsuffixed floating-point literal.
+ ///
+ /// This constructor is similar to those like `Literal::i8_unsuffixed` where
+ /// the float's value is emitted directly into the token but no suffix is
+ /// used, so it may be inferred to be a `f64` later in the compiler.
+ /// Literals created from negative numbers may not survive rountrips through
+ /// `TokenStream` or strings and may be broken into two tokens (`-` and
+ /// positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
pub fn f64_unsuffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_unsuffixed(f))
}
+ /// Creates a new suffixed floating-point literal.
+ ///
+ /// This constructor will create a literal like `1.0f64` where the value
+ /// specified is the preceding part of the token and `f64` is the suffix of
+ /// the token. This token will always be inferred to be an `f64` in the
+ /// compiler. Literals created from negative numbers may not survive
+ /// rountrips through `TokenStream` or strings and may be broken into two
+ /// tokens (`-` and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
pub fn f64_suffixed(f: f64) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f64_suffixed(f))
@@ -1070,30 +1083,61 @@ impl Literal {
Literal::_new(imp::Literal::f32_unsuffixed(f))
}
+ /// Creates a new suffixed floating-point literal.
+ ///
+ /// This constructor will create a literal like `1.0f32` where the value
+ /// specified is the preceding part of the token and `f32` is the suffix of
+ /// the token. This token will always be inferred to be an `f32` in the
+ /// compiler. Literals created from negative numbers may not survive
+ /// rountrips through `TokenStream` or strings and may be broken into two
+ /// tokens (`-` and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
pub fn f32_suffixed(f: f32) -> Literal {
assert!(f.is_finite());
Literal::_new(imp::Literal::f32_suffixed(f))
}
+ /// String literal.
pub fn string(string: &str) -> Literal {
Literal::_new(imp::Literal::string(string))
}
+ /// Character literal.
pub fn character(ch: char) -> Literal {
Literal::_new(imp::Literal::character(ch))
}
+ /// Byte string literal.
pub fn byte_string(s: &[u8]) -> Literal {
Literal::_new(imp::Literal::byte_string(s))
}
+ /// Returns the span encompassing this literal.
pub fn span(&self) -> Span {
Span::_new(self.inner.span())
}
+ /// Configures the span associated for this literal.
pub fn set_span(&mut self, span: Span) {
self.inner.set_span(span.inner);
}
+
+ /// Returns a `Span` that is a subset of `self.span()` containing only
+ /// the source bytes in range `range`. Returns `None` if the would-be
+ /// trimmed span is outside the bounds of `self`.
+ ///
+ /// Warning: the underlying [`proc_macro::Literal::subspan`] method is
+ /// nightly-only. When called from within a procedural macro not using a
+ /// nightly compiler, this method will always return `None`.
+ ///
+ /// [`proc_macro::Literal::subspan`]: https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.subspan
+ pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+ self.inner.subspan(range).map(Span::_new)
+ }
}
impl fmt::Debug for Literal {
@@ -1114,9 +1158,8 @@ pub mod token_stream {
use std::marker;
use std::rc::Rc;
- use imp;
- pub use TokenStream;
- use TokenTree;
+ pub use crate::TokenStream;
+ use crate::{imp, TokenTree};
/// An iterator over `TokenStream`'s `TokenTree`s.
///
diff --git a/src/strnom.rs b/src/strnom.rs
index 96789d5..eb7d0b8 100644
--- a/src/strnom.rs
+++ b/src/strnom.rs
@@ -1,11 +1,9 @@
//! Adapted from [`nom`](https://github.com/Geal/nom).
+use crate::fallback::LexError;
use std::str::{Bytes, CharIndices, Chars};
-
use unicode_xid::UnicodeXID;
-use fallback::LexError;
-
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Cursor<'a> {
pub rest: &'a str,
@@ -95,7 +93,7 @@ pub fn whitespace(input: Cursor) -> PResult<()> {
}
}
match bytes[i] {
- b' ' | 0x09...0x0d => {
+ b' ' | 0x09..=0x0d => {
i += 1;
continue;
}
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 994ed24..c3b6e3a 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -1,14 +1,12 @@
use std::fmt;
use std::iter;
+use std::ops::RangeBounds;
use std::panic::{self, PanicInfo};
#[cfg(super_unstable)]
use std::path::PathBuf;
use std::str::FromStr;
-use fallback;
-use proc_macro;
-
-use {Delimiter, Punct, Spacing, TokenTree};
+use crate::{fallback, Delimiter, Punct, Spacing, TokenTree};
#[derive(Clone)]
pub enum TokenStream {
@@ -25,8 +23,7 @@ fn nightly_works() -> bool {
use std::sync::atomic::*;
use std::sync::Once;
- #[allow(deprecated)]
- static WORKS: AtomicUsize = ATOMIC_USIZE_INIT;
+ static WORKS: AtomicUsize = AtomicUsize::new(0);
static INIT: Once = Once::new();
match WORKS.load(Ordering::SeqCst) {
@@ -60,7 +57,7 @@ fn nightly_works() -> bool {
// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from
// the main thread before launching any other threads.
INIT.call_once(|| {
- type PanicHook = Fn(&PanicInfo) + Sync + Send + 'static;
+ type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static;
let null_hook: Box<PanicHook> = Box::new(|_panic_info| { /* ignore */ });
let sanity_check = &*null_hook as *const PanicHook;
@@ -200,17 +197,6 @@ impl iter::FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let mut streams = streams.into_iter();
match streams.next() {
- #[cfg(slow_extend)]
- Some(TokenStream::Compiler(first)) => {
- let stream = iter::once(first)
- .chain(streams.map(|s| match s {
- TokenStream::Compiler(s) => s,
- TokenStream::Fallback(_) => mismatch(),
- }))
- .collect();
- TokenStream::Compiler(stream)
- }
- #[cfg(not(slow_extend))]
Some(TokenStream::Compiler(mut first)) => {
first.extend(streams.map(|s| match s {
TokenStream::Compiler(s) => s,
@@ -234,27 +220,11 @@ impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
match self {
TokenStream::Compiler(tts) => {
- #[cfg(not(slow_extend))]
- {
- tts.extend(
- streams
- .into_iter()
- .map(|t| TokenStream::from(t).unwrap_nightly()),
- );
- }
- #[cfg(slow_extend)]
- {
- *tts =
- tts.clone()
- .into_iter()
- .chain(streams.into_iter().map(TokenStream::from).flat_map(
- |t| match t {
- TokenStream::Compiler(tts) => tts.into_iter(),
- _ => mismatch(),
- },
- ))
- .collect();
- }
+ tts.extend(
+ streams
+ .into_iter()
+ .map(|t| TokenStream::from(t).unwrap_nightly()),
+ );
}
TokenStream::Fallback(tts) => tts.extend(streams),
}
@@ -345,18 +315,18 @@ impl Iterator for TokenTreeIter {
TokenTreeIter::Fallback(iter) => return iter.next(),
};
Some(match token {
- proc_macro::TokenTree::Group(tt) => ::Group::_new(Group::Compiler(tt)).into(),
+ proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
proc_macro::TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
proc_macro::Spacing::Joint => Spacing::Joint,
proc_macro::Spacing::Alone => Spacing::Alone,
};
let mut o = Punct::new(tt.as_char(), spacing);
- o.set_span(::Span::_new(Span::Compiler(tt.span())));
+ o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
o.into()
}
- proc_macro::TokenTree::Ident(s) => ::Ident::_new(Ident::Compiler(s)).into(),
- proc_macro::TokenTree::Literal(l) => ::Literal::_new(Literal::Compiler(l)).into(),
+ proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
+ proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
})
}
@@ -510,9 +480,9 @@ impl Span {
}
}
- #[cfg(super_unstable)]
pub fn join(&self, other: Span) -> Option<Span> {
let ret = match (self, other) {
+ #[cfg(proc_macro_span)]
(Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?),
(Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?),
_ => return None,
@@ -537,9 +507,9 @@ impl Span {
}
}
-impl From<proc_macro::Span> for ::Span {
- fn from(proc_span: proc_macro::Span) -> ::Span {
- ::Span::_new(Span::Compiler(proc_span))
+impl From<proc_macro::Span> for crate::Span {
+ fn from(proc_span: proc_macro::Span) -> crate::Span {
+ crate::Span::_new(Span::Compiler(proc_span))
}
}
@@ -617,18 +587,22 @@ impl Group {
}
}
- #[cfg(super_unstable)]
pub fn span_open(&self) -> Span {
match self {
+ #[cfg(proc_macro_span)]
Group::Compiler(g) => Span::Compiler(g.span_open()),
+ #[cfg(not(proc_macro_span))]
+ Group::Compiler(g) => Span::Compiler(g.span()),
Group::Fallback(g) => Span::Fallback(g.span_open()),
}
}
- #[cfg(super_unstable)]
pub fn span_close(&self) -> Span {
match self {
+ #[cfg(proc_macro_span)]
Group::Compiler(g) => Span::Compiler(g.span_close()),
+ #[cfg(not(proc_macro_span))]
+ Group::Compiler(g) => Span::Compiler(g.span()),
Group::Fallback(g) => Span::Fallback(g.span_close()),
}
}
@@ -804,40 +778,32 @@ impl Literal {
u16_suffixed => u16,
u32_suffixed => u32,
u64_suffixed => u64,
+ u128_suffixed => u128,
usize_suffixed => usize,
i8_suffixed => i8,
i16_suffixed => i16,
i32_suffixed => i32,
i64_suffixed => i64,
+ i128_suffixed => i128,
isize_suffixed => isize,
f32_suffixed => f32,
f64_suffixed => f64,
}
- #[cfg(u128)]
- suffixed_numbers! {
- i128_suffixed => i128,
- u128_suffixed => u128,
- }
-
unsuffixed_integers! {
u8_unsuffixed => u8,
u16_unsuffixed => u16,
u32_unsuffixed => u32,
u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
usize_unsuffixed => usize,
i8_unsuffixed => i8,
i16_unsuffixed => i16,
i32_unsuffixed => i32,
i64_unsuffixed => i64,
- isize_unsuffixed => isize,
- }
-
- #[cfg(u128)]
- unsuffixed_integers! {
i128_unsuffixed => i128,
- u128_unsuffixed => u128,
+ isize_unsuffixed => isize,
}
pub fn f32_unsuffixed(f: f32) -> Literal {
@@ -895,6 +861,16 @@ impl Literal {
}
}
+ pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+ match self {
+ #[cfg(proc_macro_span)]
+ Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler),
+ #[cfg(not(proc_macro_span))]
+ Literal::Compiler(_lit) => None,
+ Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback),
+ }
+ }
+
fn unwrap_nightly(self) -> proc_macro::Literal {
match self {
Literal::Compiler(s) => s,
diff --git a/tests/features.rs b/tests/features.rs
new file mode 100644
index 0000000..073f6e6
--- /dev/null
+++ b/tests/features.rs
@@ -0,0 +1,8 @@
+#[test]
+#[ignore]
+fn make_sure_no_proc_macro() {
+ assert!(
+ !cfg!(feature = "proc-macro"),
+ "still compiled with proc_macro?"
+ );
+}
diff --git a/tests/marker.rs b/tests/marker.rs
index 7bb5027..7af2539 100644
--- a/tests/marker.rs
+++ b/tests/marker.rs
@@ -1,5 +1,3 @@
-extern crate proc_macro2;
-
use proc_macro2::*;
macro_rules! assert_impl {
diff --git a/tests/test.rs b/tests/test.rs
index 370392b..7528388 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,5 +1,3 @@
-extern crate proc_macro2;
-
use std::str::{self, FromStr};
use proc_macro2::{Ident, Literal, Spacing, Span, TokenStream, TokenTree};
@@ -99,6 +97,22 @@ fn literal_float() {
}
#[test]
+fn literal_suffix() {
+ fn token_count(p: &str) -> usize {
+ p.parse::<TokenStream>().unwrap().into_iter().count()
+ }
+
+ assert_eq!(token_count("999u256"), 1);
+ assert_eq!(token_count("999r#u256"), 3);
+ assert_eq!(token_count("1."), 1);
+ assert_eq!(token_count("1.f32"), 3);
+ assert_eq!(token_count("1.0_0"), 1);
+ assert_eq!(token_count("1._0"), 3);
+ assert_eq!(token_count("1._m"), 3);
+ assert_eq!(token_count("\"\"s"), 1);
+}
+
+#[test]
fn roundtrip() {
fn roundtrip(p: &str) {
println!("parse: {}", p);
@@ -125,6 +139,9 @@ fn roundtrip() {
9
0
0xffffffffffffffffffffffffffffffff
+ 1x
+ 1u80
+ 1f320
",
);
roundtrip("'a");
@@ -141,9 +158,6 @@ fn fail() {
panic!("should have failed to parse: {}\n{:#?}", p, s);
}
}
- fail("1x");
- fail("1u80");
- fail("1f320");
fail("' static");
fail("r#1");
fail("r#_");