diff options
Diffstat (limited to 'vendor/proc-macro2')
-rw-r--r-- | vendor/proc-macro2/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/proc-macro2/Cargo.toml | 2 | ||||
-rw-r--r-- | vendor/proc-macro2/build.rs | 39 | ||||
-rw-r--r-- | vendor/proc-macro2/rust-toolchain.toml | 2 | ||||
-rw-r--r-- | vendor/proc-macro2/src/convert.rs | 19 | ||||
-rw-r--r-- | vendor/proc-macro2/src/fallback.rs | 216 | ||||
-rw-r--r-- | vendor/proc-macro2/src/lib.rs | 36 | ||||
-rw-r--r-- | vendor/proc-macro2/src/parse.rs | 276 | ||||
-rw-r--r-- | vendor/proc-macro2/src/rcvec.rs | 3 | ||||
-rw-r--r-- | vendor/proc-macro2/src/wrapper.rs | 28 | ||||
-rw-r--r-- | vendor/proc-macro2/tests/test.rs | 96 |
11 files changed, 480 insertions, 239 deletions
diff --git a/vendor/proc-macro2/.cargo-checksum.json b/vendor/proc-macro2/.cargo-checksum.json index ccf5c1d78..b3e757eb9 100644 --- a/vendor/proc-macro2/.cargo-checksum.json +++ b/vendor/proc-macro2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"d3c6751efd93c8c4b4c37063e03cdf03d87a2e6fbc7928ce97df4cce487aab2a","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"32cbd395594db59ecc43d7866cfa2663f3687bb7df631781d60ae83200dae8a8","build.rs":"6d3f27a11cdddd6681fef0882a68abd7d256de79d87e90bf4632a373f140834e","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"3447c89e4d83a94ebdf3599adb64050b92502da2a1f99a5cf36706e52d2c56dc","src/fallback.rs":"04bf8b1703f84c50997afdfbb506c1ecb53db54c92f808e13ee4a79d6cf4f023","src/lib.rs":"22c3a8849092a1e37ab5990ce79e8a7863c55eb5423d92abea1eea6807009c45","src/location.rs":"f55d2e61f1bb1af65e14ed04c9e91eb1ddbf8430e8c05f2048d1cd538d27368e","src/marker.rs":"344a8394f06a1d43355b514920e7e3c0c6dce507be767e3a590bbe3552edd110","src/parse.rs":"d98e38a2e97d18e1593add3cbb48a48406f1cff21592a1f37ffb6960664d919e","src/rcvec.rs":"49b6784c6ca5f32573cd8a83758b485d8acbfa126e5fb516ae439e429ef4c144","src/wrapper.rs":"be58a1d86bb422e6ff7668fce3244ee8ca39dc9128272cabb4a0f0c739e36794","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"bc86b7260e29dfc8cd3e01b0d3fb9e88f17442dc83235f264e8cacc5ab4fe23d","tests/test.rs":"cf3c944f1c4a09c326b1e639f70c173f0d93d916fb50c085542e44fad691eea7","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0","tests/test_size.rs":"acf05963c1e62052d769d237b50844a2c59b4182b491231b099a4f74e5456ab0"},"package":"ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"}
\ No newline at end of file +{"files":{"Cargo.toml":"2df39557439b577d897c0e14c6221c706e4f0bbd6f8a69034456540f89413a9b","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"32cbd395594db59ecc43d7866cfa2663f3687bb7df631781d60ae83200dae8a8","build.rs":"460c398e94aa491fa8c9242da0c6956fd7565f646a7b5fc6c971adbd79a206aa","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/convert.rs":"0f8e0f472e49e0be79e65654065a752df1ac9ad55da43952ee7c86cb56940171","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"3447c89e4d83a94ebdf3599adb64050b92502da2a1f99a5cf36706e52d2c56dc","src/fallback.rs":"a39b97b39fd3b9b1734767a948b7d2b5e3cf272cebae8c951d25f9124705fbfa","src/lib.rs":"8ff87fffbbd56761735ec0910a10f8f6c48017a1c78f349e02a0eb836d80e727","src/location.rs":"f55d2e61f1bb1af65e14ed04c9e91eb1ddbf8430e8c05f2048d1cd538d27368e","src/marker.rs":"344a8394f06a1d43355b514920e7e3c0c6dce507be767e3a590bbe3552edd110","src/parse.rs":"8f1f3c0bc130f60dcb7a7ed2ed3f46cec6472d2f2abd15e0a1647a8dc33c8e60","src/rcvec.rs":"6233164ae0afc5c74ddc9e27c7869ec523385a3e5bdb83c3662841e78af14982","src/wrapper.rs":"5b98af7cf798641d13fc2c5ff87cbcf3e5628710dbd90db6986fbfb649c7a429","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"bc86b7260e29dfc8cd3e01b0d3fb9e88f17442dc83235f264e8cacc5ab4fe23d","tests/test.rs":"6c1d259c46c8f6d600df4890eee4f494aedeb2df9c979a177e3442a8c88889ac","tests/test_fmt.rs":"9357769945784354909259084ec8b34d2aa52081dd3967cac6dae3a5e3df3bc0","tests/test_size.rs":"acf05963c1e62052d769d237b50844a2c59b4182b491231b099a4f74e5456ab0"},"package":"78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"}
\ No newline at end of file diff --git a/vendor/proc-macro2/Cargo.toml b/vendor/proc-macro2/Cargo.toml index b6f170f20..71c095f66 100644 --- a/vendor/proc-macro2/Cargo.toml +++ b/vendor/proc-macro2/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "proc-macro2" -version = "1.0.53" +version = "1.0.64" authors = [ "David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>", diff --git a/vendor/proc-macro2/build.rs b/vendor/proc-macro2/build.rs index 59505a50c..0f4338dd3 100644 --- a/vendor/proc-macro2/build.rs +++ b/vendor/proc-macro2/build.rs @@ -1,11 +1,5 @@ // rustc-cfg emitted by the build script: // -// "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 -// enabled). On wasm32 we never link to proc_macro even if "proc-macro" cfg -// is enabled. -// // "wrap_proc_macro" // Wrap types from libproc_macro rather than polyfilling the whole API. // Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, @@ -43,14 +37,15 @@ use std::env; use std::process::{self, Command}; use std::str; +use std::u32; fn main() { println!("cargo:rerun-if-changed=build.rs"); - let version = match rustc_version() { - Some(version) => version, - None => return, - }; + let version = rustc_version().unwrap_or(RustcVersion { + minor: u32::MAX, + nightly: false, + }); if version.minor < 31 { eprintln!("Minimum supported rustc version is 1.31"); @@ -72,6 +67,10 @@ fn main() { println!("cargo:rustc-cfg=no_libprocmacro_unwind_safe"); } + if version.minor < 34 { + println!("cargo:rustc-cfg=no_try_from"); + } + if version.minor < 39 { println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard"); } @@ -104,21 +103,15 @@ fn main() { println!("cargo:rustc-cfg=no_source_text"); } - let target = env::var("TARGET").unwrap(); - if !enable_use_proc_macro(&target) { + if !cfg!(feature = "proc-macro") { return; } - println!("cargo:rustc-cfg=use_proc_macro"); - if version.nightly || !semver_exempt { println!("cargo:rustc-cfg=wrap_proc_macro"); } - if version.nightly - && feature_allowed("proc_macro_span") - && feature_allowed("proc_macro_span_shrink") - { + if version.nightly && feature_allowed("proc_macro_span") { println!("cargo:rustc-cfg=proc_macro_span"); } @@ -127,16 +120,6 @@ fn main() { } } -fn enable_use_proc_macro(target: &str) -> bool { - // wasm targets don't have the `proc_macro` crate, disable this feature. - if target.contains("wasm32") { - return false; - } - - // Otherwise, only enable it if our feature is actually enabled. - cfg!(feature = "proc-macro") -} - struct RustcVersion { minor: u32, nightly: bool, diff --git a/vendor/proc-macro2/rust-toolchain.toml b/vendor/proc-macro2/rust-toolchain.toml new file mode 100644 index 000000000..20fe888c3 --- /dev/null +++ b/vendor/proc-macro2/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +components = ["rust-src"] diff --git a/vendor/proc-macro2/src/convert.rs b/vendor/proc-macro2/src/convert.rs new file mode 100644 index 000000000..afc5faf53 --- /dev/null +++ b/vendor/proc-macro2/src/convert.rs @@ -0,0 +1,19 @@ +pub(crate) fn usize_to_u32(u: usize) -> Option<u32> { + #[cfg(not(no_try_from))] + { + use core::convert::TryFrom; + + u32::try_from(u).ok() + } + + #[cfg(no_try_from)] + { + use core::mem; + + if mem::size_of::<usize>() <= mem::size_of::<u32>() || u <= u32::max_value() as usize { + Some(u as u32) + } else { + None + } + } +} diff --git a/vendor/proc-macro2/src/fallback.rs b/vendor/proc-macro2/src/fallback.rs index b0ed7b06f..1b8b12574 100644 --- a/vendor/proc-macro2/src/fallback.rs +++ b/vendor/proc-macro2/src/fallback.rs @@ -3,7 +3,7 @@ use crate::location::LineColumn; use crate::parse::{self, Cursor}; use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; use crate::{Delimiter, Spacing, TokenTree}; -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] use core::cell::RefCell; #[cfg(span_locations)] use core::cmp; @@ -13,8 +13,6 @@ use core::mem::ManuallyDrop; use core::ops::RangeBounds; use core::ptr; use core::str::FromStr; -#[cfg(procmacro2_semver_exempt)] -use std::path::Path; use std::path::PathBuf; /// Force use of proc-macro2's fallback implementation of the API for now, even @@ -162,11 +160,14 @@ impl TokenStreamBuilder { #[cfg(span_locations)] fn get_cursor(src: &str) -> Cursor { + #[cfg(fuzzing)] + return Cursor { rest: src, off: 1 }; + // Create a dummy file & add it to the source map + #[cfg(not(fuzzing))] SOURCE_MAP.with(|cm| { let mut cm = cm.borrow_mut(); - let name = format!("<parsed string {}>", cm.files.len()); - let span = cm.add_file(&name, src); + let span = cm.add_file(src); Cursor { rest: src, off: span.lo, @@ -232,7 +233,7 @@ impl Debug for TokenStream { } } -#[cfg(use_proc_macro)] +#[cfg(feature = "proc-macro")] impl From<proc_macro::TokenStream> for TokenStream { fn from(inner: proc_macro::TokenStream) -> Self { inner @@ -242,7 +243,7 @@ impl From<proc_macro::TokenStream> for TokenStream { } } -#[cfg(use_proc_macro)] +#[cfg(feature = "proc-macro")] impl From<TokenStream> for proc_macro::TokenStream { fn from(inner: TokenStream) -> Self { inner @@ -334,14 +335,12 @@ impl Debug for SourceFile { } } -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] thread_local! { static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap { // NOTE: We start with a single dummy file which all call_site() and // def_site() spans reference. files: vec![FileInfo { - #[cfg(procmacro2_semver_exempt)] - name: "<unspecified>".to_owned(), source_text: String::new(), span: Span { lo: 0, hi: 0 }, lines: vec![0], @@ -349,16 +348,14 @@ thread_local! { }); } -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] struct FileInfo { - #[cfg(procmacro2_semver_exempt)] - name: String, source_text: String, span: Span, lines: Vec<usize>, } -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] impl FileInfo { fn offset_line_column(&self, offset: usize) -> LineColumn { assert!(self.span_within(Span { @@ -391,7 +388,7 @@ impl FileInfo { /// Computes the offsets of each line in the given source string /// and the total number of characters -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] fn lines_offsets(s: &str) -> (usize, Vec<usize>) { let mut lines = vec![0]; let mut total = 0; @@ -406,12 +403,12 @@ fn lines_offsets(s: &str) -> (usize, Vec<usize>) { (total, lines) } -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] struct SourceMap { files: Vec<FileInfo>, } -#[cfg(span_locations)] +#[cfg(all(span_locations, not(fuzzing)))] impl SourceMap { fn next_start_pos(&self) -> u32 { // Add 1 so there's always space between files. @@ -421,7 +418,7 @@ impl SourceMap { self.files.last().unwrap().span.hi + 1 } - fn add_file(&mut self, name: &str, src: &str) -> Span { + fn add_file(&mut self, src: &str) -> Span { let (len, lines) = lines_offsets(src); let lo = self.next_start_pos(); // XXX(nika): Should we bother doing a checked cast or checked add here? @@ -431,26 +428,35 @@ impl SourceMap { }; self.files.push(FileInfo { - #[cfg(procmacro2_semver_exempt)] - name: name.to_owned(), source_text: src.to_owned(), span, lines, }); - #[cfg(not(procmacro2_semver_exempt))] - let _ = name; - span } + #[cfg(procmacro2_semver_exempt)] + fn filepath(&self, span: Span) -> PathBuf { + for (i, file) in self.files.iter().enumerate() { + if file.span_within(span) { + return PathBuf::from(if i == 0 { + "<unspecified>".to_owned() + } else { + format!("<parsed string {}>", i) + }); + } + } + unreachable!("Invalid span with no related FileInfo!"); + } + fn fileinfo(&self, span: Span) -> &FileInfo { for file in &self.files { if file.span_within(span) { return file; } } - panic!("Invalid span with no related FileInfo!"); + unreachable!("Invalid span with no related FileInfo!"); } } @@ -496,17 +502,25 @@ impl Span { #[cfg(procmacro2_semver_exempt)] pub fn source_file(&self) -> SourceFile { + #[cfg(fuzzing)] + return SourceFile { + path: PathBuf::from("<unspecified>"), + }; + + #[cfg(not(fuzzing))] SOURCE_MAP.with(|cm| { let cm = cm.borrow(); - let fi = cm.fileinfo(*self); - SourceFile { - path: Path::new(&fi.name).to_owned(), - } + let path = cm.filepath(*self); + SourceFile { path } }) } #[cfg(span_locations)] pub fn start(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] SOURCE_MAP.with(|cm| { let cm = cm.borrow(); let fi = cm.fileinfo(*self); @@ -516,6 +530,10 @@ impl Span { #[cfg(span_locations)] pub fn end(&self) -> LineColumn { + #[cfg(fuzzing)] + return LineColumn { line: 0, column: 0 }; + + #[cfg(not(fuzzing))] SOURCE_MAP.with(|cm| { let cm = cm.borrow(); let fi = cm.fileinfo(*self); @@ -523,26 +541,6 @@ impl Span { }) } - #[cfg(procmacro2_semver_exempt)] - pub fn before(&self) -> Span { - Span { - #[cfg(span_locations)] - lo: self.lo, - #[cfg(span_locations)] - hi: self.lo, - } - } - - #[cfg(procmacro2_semver_exempt)] - pub fn after(&self) -> Span { - Span { - #[cfg(span_locations)] - lo: self.hi, - #[cfg(span_locations)] - hi: self.hi, - } - } - #[cfg(not(span_locations))] pub fn join(&self, _other: Span) -> Option<Span> { Some(Span {}) @@ -550,6 +548,13 @@ impl Span { #[cfg(span_locations)] pub fn join(&self, other: Span) -> Option<Span> { + #[cfg(fuzzing)] + return { + let _ = other; + None + }; + + #[cfg(not(fuzzing))] SOURCE_MAP.with(|cm| { let cm = cm.borrow(); // If `other` is not within the same FileInfo as us, return None. @@ -570,10 +575,16 @@ impl Span { #[cfg(span_locations)] pub fn source_text(&self) -> Option<String> { - if self.is_call_site() { - None - } else { - Some(SOURCE_MAP.with(|cm| cm.borrow().fileinfo(*self).source_text(*self))) + #[cfg(fuzzing)] + return None; + + #[cfg(not(fuzzing))] + { + if self.is_call_site() { + None + } else { + Some(SOURCE_MAP.with(|cm| cm.borrow().fileinfo(*self).source_text(*self))) + } } } @@ -819,6 +830,7 @@ impl Display for Ident { } } +#[allow(clippy::missing_fields_in_debug)] impl Debug for Ident { // Ident(proc_macro), Ident(r#union) #[cfg(not(span_locations))] @@ -927,12 +939,25 @@ impl Literal { pub fn string(t: &str) -> Literal { let mut repr = String::with_capacity(t.len() + 2); repr.push('"'); - for c in t.chars() { - if c == '\'' { + let mut chars = t.chars(); + while let Some(ch) = chars.next() { + if ch == '\0' { + repr.push_str( + if chars + .as_str() + .starts_with(|next| '0' <= next && next <= '7') + { + // circumvent clippy::octal_escapes lint + "\\x00" + } else { + "\\0" + }, + ); + } else if ch == '\'' { // escape_debug turns this into "\'" which is unnecessary. - repr.push(c); + repr.push(ch); } else { - repr.extend(c.escape_debug()); + repr.extend(ch.escape_debug()); } } repr.push('"'); @@ -954,16 +979,21 @@ impl Literal { pub fn byte_string(bytes: &[u8]) -> Literal { let mut escaped = "b\"".to_string(); - for b in bytes { + let mut bytes = bytes.iter(); + while let Some(&b) = bytes.next() { #[allow(clippy::match_overlapping_arm)] - match *b { - b'\0' => escaped.push_str(r"\0"), + match b { + b'\0' => escaped.push_str(match bytes.as_slice().first() { + // circumvent clippy::octal_escapes lint + Some(b'0'..=b'7') => r"\x00", + _ => r"\0", + }), b'\t' => escaped.push_str(r"\t"), b'\n' => escaped.push_str(r"\n"), 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), _ => { let _ = write!(escaped, "\\x{:02X}", b); } @@ -981,28 +1011,76 @@ impl Literal { self.span = span; } - pub fn subspan<R: RangeBounds<usize>>(&self, _range: R) -> Option<Span> { - None + pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { + #[cfg(not(span_locations))] + { + let _ = range; + None + } + + #[cfg(span_locations)] + { + use crate::convert::usize_to_u32; + use core::ops::Bound; + + let lo = match range.start_bound() { + Bound::Included(start) => { + let start = usize_to_u32(*start)?; + self.span.lo.checked_add(start)? + } + Bound::Excluded(start) => { + let start = usize_to_u32(*start)?; + self.span.lo.checked_add(start)?.checked_add(1)? + } + Bound::Unbounded => self.span.lo, + }; + let hi = match range.end_bound() { + Bound::Included(end) => { + let end = usize_to_u32(*end)?; + self.span.lo.checked_add(end)?.checked_add(1)? + } + Bound::Excluded(end) => { + let end = usize_to_u32(*end)?; + self.span.lo.checked_add(end)? + } + Bound::Unbounded => self.span.hi, + }; + if lo <= hi && hi <= self.span.hi { + Some(Span { lo, hi }) + } else { + None + } + } } } impl FromStr for Literal { type Err = LexError; - fn from_str(mut repr: &str) -> Result<Self, Self::Err> { - let negative = repr.starts_with('-'); + fn from_str(repr: &str) -> Result<Self, Self::Err> { + let mut cursor = get_cursor(repr); + #[cfg(span_locations)] + let lo = cursor.off; + + let negative = cursor.starts_with_char('-'); if negative { - repr = &repr[1..]; - if !repr.starts_with(|ch: char| ch.is_ascii_digit()) { + cursor = cursor.advance(1); + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { return Err(LexError::call_site()); } } - let cursor = get_cursor(repr); - if let Ok((_rest, mut literal)) = parse::literal(cursor) { - if literal.repr.len() == repr.len() { + + if let Ok((rest, mut literal)) = parse::literal(cursor) { + if rest.is_empty() { if negative { literal.repr.insert(0, '-'); } + literal.span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; return Ok(literal); } } diff --git a/vendor/proc-macro2/src/lib.rs b/vendor/proc-macro2/src/lib.rs index 138627a16..aa196be7c 100644 --- a/vendor/proc-macro2/src/lib.rs +++ b/vendor/proc-macro2/src/lib.rs @@ -86,11 +86,8 @@ //! 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.53")] -#![cfg_attr( - any(proc_macro_span, super_unstable), - feature(proc_macro_span, proc_macro_span_shrink) -)] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.64")] +#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] #![cfg_attr(super_unstable, feature(proc_macro_def_site))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow( @@ -102,6 +99,7 @@ clippy::manual_assert, clippy::must_use_candidate, clippy::needless_doctest_main, + clippy::new_without_default, clippy::return_self_not_must_use, clippy::shadow_unrelated, clippy::trivially_copy_pass_by_ref, @@ -119,7 +117,7 @@ compile_error! {"\ build script as well. "} -#[cfg(use_proc_macro)] +#[cfg(feature = "proc-macro")] extern crate proc_macro; mod marker; @@ -143,6 +141,8 @@ use crate::fallback as imp; mod imp; #[cfg(span_locations)] +mod convert; +#[cfg(span_locations)] mod location; use crate::extra::DelimSpan; @@ -233,14 +233,16 @@ impl FromStr for TokenStream { } } -#[cfg(use_proc_macro)] +#[cfg(feature = "proc-macro")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] impl From<proc_macro::TokenStream> for TokenStream { fn from(inner: proc_macro::TokenStream) -> Self { TokenStream::_new(inner.into()) } } -#[cfg(use_proc_macro)] +#[cfg(feature = "proc-macro")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] impl From<TokenStream> for proc_macro::TokenStream { fn from(inner: TokenStream) -> Self { inner.inner.into() @@ -489,24 +491,6 @@ impl Span { self.inner.end() } - /// Creates an empty span pointing to directly before this span. - /// - /// This method is semver exempt and not exposed by default. - #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn before(&self) -> Span { - Span::_new(self.inner.before()) - } - - /// Creates an empty span pointing to directly after this span. - /// - /// This method is semver exempt and not exposed by default. - #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn after(&self) -> Span { - Span::_new(self.inner.after()) - } - /// Create a new span encompassing `self` and `other`. /// /// Returns `None` if `self` and `other` are from different files. diff --git a/vendor/proc-macro2/src/parse.rs b/vendor/proc-macro2/src/parse.rs index 82291da1b..21e324136 100644 --- a/vendor/proc-macro2/src/parse.rs +++ b/vendor/proc-macro2/src/parse.rs @@ -27,7 +27,18 @@ impl<'a> Cursor<'a> { self.rest.starts_with(s) } - fn is_empty(&self) -> bool { + pub fn starts_with_char(&self, ch: char) -> bool { + self.rest.starts_with(ch) + } + + pub fn starts_with_fn<Pattern>(&self, f: Pattern) -> bool + where + Pattern: FnMut(char) -> bool, + { + self.rest.starts_with(f) + } + + pub fn is_empty(&self) -> bool { self.rest.is_empty() } @@ -97,7 +108,7 @@ fn skip_whitespace(input: Cursor) -> Cursor { s = s.advance(1); continue; } - b if b <= 0x7f => {} + b if b.is_ascii() => {} _ => { let ch = s.chars().next().unwrap(); if is_whitespace(ch) { @@ -262,9 +273,11 @@ fn leaf_token(input: Cursor) -> PResult<TokenTree> { } fn ident(input: Cursor) -> PResult<crate::Ident> { - if ["r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#"] - .iter() - .any(|prefix| input.starts_with(prefix)) + if [ + "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#", + ] + .iter() + .any(|prefix| input.starts_with(prefix)) { Err(Reject) } else { @@ -322,6 +335,8 @@ fn literal_nocapture(input: Cursor) -> Result<Cursor, Reject> { Ok(ok) } else if let Ok(ok) = byte_string(input) { Ok(ok) + } else if let Ok(ok) = c_string(input) { + Ok(ok) } else if let Ok(ok) = byte(input) { Ok(ok) } else if let Ok(ok) = character(input) { @@ -352,8 +367,8 @@ fn string(input: Cursor) -> Result<Cursor, Reject> { } } -fn cooked_string(input: Cursor) -> Result<Cursor, Reject> { - let mut chars = input.char_indices().peekable(); +fn cooked_string(mut input: Cursor) -> Result<Cursor, Reject> { + let mut chars = input.char_indices(); while let Some((i, ch)) = chars.next() { match ch { @@ -367,31 +382,17 @@ fn cooked_string(input: Cursor) -> Result<Cursor, Reject> { }, '\\' => match chars.next() { Some((_, 'x')) => { - if !backslash_x_char(&mut chars) { - break; - } + backslash_x_char(&mut chars)?; } Some((_, 'n')) | Some((_, 'r')) | Some((_, 't')) | Some((_, '\\')) | Some((_, '\'')) | Some((_, '"')) | Some((_, '0')) => {} Some((_, 'u')) => { - if !backslash_u(&mut chars) { - break; - } + backslash_u(&mut chars)?; } - Some((_, ch @ '\n')) | Some((_, ch @ '\r')) => { - let mut last = ch; - loop { - if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') { - return Err(Reject); - } - match chars.peek() { - Some((_, ch)) if ch.is_whitespace() => { - last = *ch; - chars.next(); - } - _ => break, - } - } + Some((newline, ch @ '\n')) | Some((newline, ch @ '\r')) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); } _ => break, }, @@ -401,11 +402,30 @@ fn cooked_string(input: Cursor) -> Result<Cursor, Reject> { Err(Reject) } +fn raw_string(input: Cursor) -> Result<Cursor, Reject> { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + _ => {} + } + } + Err(Reject) +} + fn byte_string(input: Cursor) -> Result<Cursor, Reject> { if let Ok(input) = input.parse("b\"") { cooked_byte_string(input) } else if let Ok(input) = input.parse("br") { - raw_string(input) + raw_byte_string(input) } else { Err(Reject) } @@ -425,68 +445,127 @@ fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, Reject> { }, b'\\' => match bytes.next() { Some((_, b'x')) => { - if !backslash_x_byte(&mut bytes) { - break; - } + backslash_x_byte(&mut bytes)?; } Some((_, b'n')) | Some((_, b'r')) | Some((_, b't')) | Some((_, b'\\')) | Some((_, b'0')) | Some((_, b'\'')) | Some((_, b'"')) => {} Some((newline, b @ b'\n')) | Some((newline, b @ b'\r')) => { - let mut last = b as char; - let rest = input.advance(newline + 1); - let mut chars = rest.char_indices(); - loop { - if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') { - return Err(Reject); - } - match chars.next() { - Some((_, ch)) if ch.is_whitespace() => last = ch, - Some((offset, _)) => { - input = rest.advance(offset); - bytes = input.bytes().enumerate(); - break; - } - None => return Err(Reject), - } - } + input = input.advance(newline + 1); + trailing_backslash(&mut input, b)?; + bytes = input.bytes().enumerate(); } _ => break, }, - b if b < 0x80 => {} + b if b.is_ascii() => {} _ => break, } } Err(Reject) } -fn raw_string(input: Cursor) -> Result<Cursor, Reject> { - let mut chars = input.char_indices(); - let mut n = 0; - for (i, ch) in &mut chars { - match ch { - '"' => { - n = i; - break; +fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> { + for (i, byte) in input.bytes().enumerate() { + match byte { + b'"' => { + if i > 255 { + // https://github.com/rust-lang/rust/pull/95251 + return Err(Reject); + } + return Ok((input.advance(i + 1), &input.rest[..i])); } - '#' => {} - _ => return Err(Reject), + b'#' => {} + _ => break, } } - if n > 255 { - // https://github.com/rust-lang/rust/pull/95251 - return Err(Reject); + Err(Reject) +} + +fn raw_byte_string(input: Cursor) -> Result<Cursor, Reject> { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + other => { + if !other.is_ascii() { + break; + } + } + } + } + Err(Reject) +} + +fn c_string(input: Cursor) -> Result<Cursor, Reject> { + if let Ok(input) = input.parse("c\"") { + cooked_c_string(input) + } else if let Ok(input) = input.parse("cr") { + raw_c_string(input) + } else { + Err(Reject) + } +} + +fn raw_c_string(input: Cursor) -> Result<Cursor, Reject> { + let (input, delimiter) = delimiter_of_raw_string(input)?; + let mut bytes = input.bytes().enumerate(); + while let Some((i, byte)) = bytes.next() { + match byte { + b'"' if input.rest[i + 1..].starts_with(delimiter) => { + let rest = input.advance(i + 1 + delimiter.len()); + return Ok(literal_suffix(rest)); + } + b'\r' => match bytes.next() { + Some((_, b'\n')) => {} + _ => break, + }, + b'\0' => break, + _ => {} + } } + Err(Reject) +} + +fn cooked_c_string(mut input: Cursor) -> Result<Cursor, Reject> { + let mut chars = input.char_indices(); + while let Some((i, ch)) = chars.next() { match ch { - '"' if input.rest[i + 1..].starts_with(&input.rest[..n]) => { - let rest = input.advance(i + 1 + n); - return Ok(literal_suffix(rest)); + '"' => { + let input = input.advance(i + 1); + return Ok(literal_suffix(input)); } '\r' => match chars.next() { Some((_, '\n')) => {} _ => break, }, - _ => {} + '\\' => match chars.next() { + Some((_, 'x')) => { + backslash_x_nonzero(&mut chars)?; + } + Some((_, 'n')) | Some((_, 'r')) | Some((_, 't')) | Some((_, '\\')) + | Some((_, '\'')) | Some((_, '"')) => {} + Some((_, 'u')) => { + if backslash_u(&mut chars)? == '\0' { + break; + } + } + Some((newline, ch @ '\n')) | Some((newline, ch @ '\r')) => { + input = input.advance(newline + 1); + trailing_backslash(&mut input, ch as u8)?; + chars = input.char_indices(); + } + _ => break, + }, + '\0' => break, + _ch => {} } } Err(Reject) @@ -497,7 +576,7 @@ fn byte(input: Cursor) -> Result<Cursor, Reject> { let mut bytes = input.bytes().enumerate(); let ok = match bytes.next().map(|(_, b)| b) { Some(b'\\') => match bytes.next().map(|(_, b)| b) { - Some(b'x') => backslash_x_byte(&mut bytes), + Some(b'x') => backslash_x_byte(&mut bytes).is_ok(), Some(b'n') | Some(b'r') | Some(b't') | Some(b'\\') | Some(b'0') | Some(b'\'') | Some(b'"') => true, _ => false, @@ -520,8 +599,8 @@ fn character(input: Cursor) -> Result<Cursor, Reject> { let mut chars = input.char_indices(); let ok = match chars.next().map(|(_, ch)| ch) { Some('\\') => match chars.next().map(|(_, ch)| ch) { - Some('x') => backslash_x_char(&mut chars), - Some('u') => backslash_u(&mut chars), + Some('x') => backslash_x_char(&mut chars).is_ok(), + Some('u') => backslash_u(&mut chars).is_ok(), Some('n') | Some('r') | Some('t') | Some('\\') | Some('0') | Some('\'') | Some('"') => { true } @@ -542,32 +621,45 @@ macro_rules! next_ch { match $chars.next() { Some((_, ch)) => match ch { $pat $(| $rest)* => ch, - _ => return false, + _ => return Err(Reject), }, - None => return false, + None => return Err(Reject), } }; } -fn backslash_x_char<I>(chars: &mut I) -> bool +fn backslash_x_char<I>(chars: &mut I) -> Result<(), Reject> where I: Iterator<Item = (usize, char)>, { next_ch!(chars @ '0'..='7'); next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); - true + Ok(()) } -fn backslash_x_byte<I>(chars: &mut I) -> bool +fn backslash_x_byte<I>(chars: &mut I) -> Result<(), Reject> 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'); - true + Ok(()) } -fn backslash_u<I>(chars: &mut I) -> bool +fn backslash_x_nonzero<I>(chars: &mut I) -> Result<(), Reject> +where + I: Iterator<Item = (usize, char)>, +{ + let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); + if first == '0' && second == '0' { + Err(Reject) + } else { + Ok(()) + } +} + +fn backslash_u<I>(chars: &mut I) -> Result<char, Reject> where I: Iterator<Item = (usize, char)>, { @@ -580,17 +672,37 @@ where 'a'..='f' => 10 + ch as u8 - b'a', 'A'..='F' => 10 + ch as u8 - b'A', '_' if len > 0 => continue, - '}' if len > 0 => return char::from_u32(value).is_some(), - _ => return false, + '}' if len > 0 => return char::from_u32(value).ok_or(Reject), + _ => break, }; if len == 6 { - return false; + break; } value *= 0x10; value += u32::from(digit); len += 1; } - false + Err(Reject) +} + +fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> { + let mut whitespace = input.bytes().enumerate(); + loop { + if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') { + return Err(Reject); + } + match whitespace.next() { + Some((_, b @ b' ')) | Some((_, b @ b'\t')) | Some((_, b @ b'\n')) + | Some((_, b @ b'\r')) => { + last = b; + } + Some((offset, _)) => { + *input = input.advance(offset); + return Ok(()); + } + None => return Err(Reject), + } + } } fn float(input: Cursor) -> Result<Cursor, Reject> { @@ -756,7 +868,7 @@ fn digits(mut input: Cursor) -> Result<Cursor, Reject> { fn punct(input: Cursor) -> PResult<Punct> { let (rest, ch) = punct_char(input)?; if ch == '\'' { - if ident_any(rest)?.0.starts_with("'") { + if ident_any(rest)?.0.starts_with_char('\'') { Err(Reject) } else { Ok((rest, Punct::new('\'', Spacing::Joint))) @@ -848,7 +960,7 @@ fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { Ok((input, (&s[3..s.len() - 2], true))) } else if input.starts_with("///") { let input = input.advance(3); - if input.starts_with("/") { + if input.starts_with_char('/') { return Err(Reject); } let (input, s) = take_until_newline_or_eof(input); diff --git a/vendor/proc-macro2/src/rcvec.rs b/vendor/proc-macro2/src/rcvec.rs index 86ca7d808..62298b42f 100644 --- a/vendor/proc-macro2/src/rcvec.rs +++ b/vendor/proc-macro2/src/rcvec.rs @@ -1,5 +1,6 @@ use core::mem; use core::slice; +use std::panic::RefUnwindSafe; use std::rc::Rc; use std::vec; @@ -140,3 +141,5 @@ impl<T> Iterator for RcVecIntoIter<T> { self.inner.size_hint() } } + +impl<T> RefUnwindSafe for RcVec<T> where T: RefUnwindSafe {} diff --git a/vendor/proc-macro2/src/wrapper.rs b/vendor/proc-macro2/src/wrapper.rs index 00f67cd62..c422e4f0c 100644 --- a/vendor/proc-macro2/src/wrapper.rs +++ b/vendor/proc-macro2/src/wrapper.rs @@ -470,12 +470,6 @@ impl Span { #[cfg(span_locations)] pub fn start(&self) -> LineColumn { match self { - #[cfg(proc_macro_span)] - Span::Compiler(s) => { - let proc_macro::LineColumn { line, column } = s.start(); - LineColumn { line, column } - } - #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => s.start(), } @@ -484,33 +478,11 @@ impl Span { #[cfg(span_locations)] pub fn end(&self) -> LineColumn { match self { - #[cfg(proc_macro_span)] - Span::Compiler(s) => { - let proc_macro::LineColumn { line, column } = s.end(); - LineColumn { line, column } - } - #[cfg(not(proc_macro_span))] Span::Compiler(_) => LineColumn { line: 0, column: 0 }, Span::Fallback(s) => s.end(), } } - #[cfg(super_unstable)] - pub fn before(&self) -> Span { - match self { - Span::Compiler(s) => Span::Compiler(s.before()), - Span::Fallback(s) => Span::Fallback(s.before()), - } - } - - #[cfg(super_unstable)] - pub fn after(&self) -> Span { - match self { - Span::Compiler(s) => Span::Compiler(s.after()), - Span::Fallback(s) => Span::Fallback(s.after()), - } - } - pub fn join(&self, other: Span) -> Option<Span> { let ret = match (self, other) { #[cfg(proc_macro_span)] diff --git a/vendor/proc-macro2/tests/test.rs b/vendor/proc-macro2/tests/test.rs index e0af1512c..7792a0208 100644 --- a/vendor/proc-macro2/tests/test.rs +++ b/vendor/proc-macro2/tests/test.rs @@ -1,7 +1,8 @@ #![allow( clippy::assertions_on_result_states, clippy::items_after_statements, - clippy::non_ascii_literal + clippy::non_ascii_literal, + clippy::octal_escapes )] use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; @@ -114,6 +115,13 @@ fn literal_string() { assert_eq!(Literal::string("foo").to_string(), "\"foo\""); assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); + assert_eq!( + Literal::string("a\00b\07c\08d\0e\0").to_string(), + "\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); + + "\"\\\r\n x\"".parse::<TokenStream>().unwrap(); + "\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err(); } #[test] @@ -147,6 +155,51 @@ fn literal_byte_string() { Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(), "b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"", ); + assert_eq!( + Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), + "b\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); + + "b\"\\\r\n x\"".parse::<TokenStream>().unwrap(); + "b\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err(); + "b\"\\\r\n \u{a0}x\"".parse::<TokenStream>().unwrap_err(); + "br\"\u{a0}\"".parse::<TokenStream>().unwrap_err(); +} + +#[test] +fn literal_c_string() { + let strings = r###" + c"hello\x80我叫\u{1F980}" // from the RFC + cr"\" + cr##"Hello "world"!"## + c"\t\n\r\"\\" + "###; + + let mut tokens = strings.parse::<TokenStream>().unwrap().into_iter(); + + for expected in &[ + r#"c"hello\x80我叫\u{1F980}""#, + r#"cr"\""#, + r###"cr##"Hello "world"!"##"###, + r#"c"\t\n\r\"\\""#, + ] { + match tokens.next().unwrap() { + TokenTree::Literal(literal) => { + assert_eq!(literal.to_string(), *expected); + } + unexpected => panic!("unexpected token: {:?}", unexpected), + } + } + + if let Some(unexpected) = tokens.next() { + panic!("unexpected token: {:?}", unexpected); + } + + for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] { + if let Ok(unexpected) = invalid.parse::<TokenStream>() { + panic!("unexpected token: {:?}", unexpected); + } + } } #[test] @@ -265,6 +318,30 @@ fn literal_parse() { } #[test] +fn literal_span() { + let positive = "0.1".parse::<Literal>().unwrap(); + let negative = "-0.1".parse::<Literal>().unwrap(); + let subspan = positive.subspan(1..2); + + #[cfg(not(span_locations))] + { + let _ = negative; + assert!(subspan.is_none()); + } + + #[cfg(span_locations)] + { + assert_eq!(positive.span().start().column, 0); + assert_eq!(positive.span().end().column, 3); + assert_eq!(negative.span().start().column, 0); + assert_eq!(negative.span().end().column, 4); + assert_eq!(subspan.unwrap().source_text().unwrap(), "."); + } + + assert!(positive.subspan(1..4).is_none()); +} + +#[test] fn roundtrip() { fn roundtrip(p: &str) { println!("parse: {}", p); @@ -603,8 +680,8 @@ fn non_ascii_tokens() { check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]); check_spans(r#""abc""#, &[(1, 0, 1, 5)]); check_spans(r#""ábc""#, &[(1, 0, 1, 5)]); - check_spans(r###"r#"abc"#"###, &[(1, 0, 1, 8)]); - check_spans(r###"r#"ábc"#"###, &[(1, 0, 1, 8)]); + check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]); + check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]); check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]); check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]); check_spans("'a'", &[(1, 0, 1, 3)]); @@ -624,7 +701,6 @@ fn non_ascii_tokens() { check_spans("ábc// foo", &[(1, 0, 1, 3)]); check_spans("ábć// foo", &[(1, 0, 1, 3)]); check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]); - check_spans("b\"a\\\n\u{00a0}c\"", &[(1, 0, 2, 3)]); } #[cfg(span_locations)] @@ -656,6 +732,18 @@ fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usi } #[test] +fn whitespace() { + // space, horizontal tab, vertical tab, form feed, carriage return, line + // feed, non-breaking space, left-to-right mark, right-to-left mark + let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}"; + let tokens = various_spaces.parse::<TokenStream>().unwrap(); + assert_eq!(tokens.into_iter().count(), 0); + + let lone_carriage_returns = " \r \r\r\n "; + lone_carriage_returns.parse::<TokenStream>().unwrap(); +} + +#[test] fn byte_order_mark() { let string = "\u{feff}foo"; let tokens = string.parse::<TokenStream>().unwrap(); |