Upgrade proc-macro2 to 1.0.56 am: c355513437

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/proc-macro2/+/2520717

Change-Id: Ieb6d112f3633e9b565e55497c1e62a95227087c4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 9742e0b..c26dd7c 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "9f9328b7f016d3f7782ee9443dc441d63abe5b09"
+    "sha1": "72ee0b3b0523395e75bf71ae7702e93a7c506f1a"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3e1bbba..1299805 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -97,6 +97,12 @@
       - uses: dtolnay/rust-toolchain@nightly
       - uses: dtolnay/install@cargo-fuzz
       - run: cargo fuzz check
+      - run: cargo check --no-default-features --features afl
+        working-directory: fuzz
+      - uses: dtolnay/install@honggfuzz
+      - run: sudo apt-get install binutils-dev libunwind-dev
+      - run: cargo hfuzz build --no-default-features --features honggfuzz
+        working-directory: fuzz
 
   clippy:
     name: Clippy
diff --git a/Android.bp b/Android.bp
index 9033168..dea1ca2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,7 +41,7 @@
     name: "libproc_macro2",
     crate_name: "proc_macro2",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.54",
+    cargo_pkg_version: "1.0.56",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
@@ -67,7 +67,7 @@
     name: "proc-macro2_test_defaults",
     crate_name: "proc_macro2",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.54",
+    cargo_pkg_version: "1.0.56",
     test_suites: ["general-tests"],
     auto_gen_config: true,
     edition: "2018",
diff --git a/Cargo.toml b/Cargo.toml
index f4269fd..76c0df6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2018"
 rust-version = "1.31"
 name = "proc-macro2"
-version = "1.0.54"
+version = "1.0.56"
 authors = [
     "David Tolnay <dtolnay@gmail.com>",
     "Alex Crichton <alex@alexcrichton.com>",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 385bf0f..791d5e9 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "proc-macro2"
-version = "1.0.54" # remember to update html_root_url
+version = "1.0.56" # remember to update html_root_url
 authors = ["David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>"]
 autobenches = false
 categories = ["development-tools::procedural-macro-helpers"]
diff --git a/METADATA b/METADATA
index cb301c8..66c5a87 100644
--- a/METADATA
+++ b/METADATA
@@ -11,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.54.crate"
+    value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.56.crate"
   }
-  version: "1.0.54"
+  version: "1.0.56"
   license_type: NOTICE
   last_upgrade_date {
     year: 2023
-    month: 3
-    day: 30
+    month: 4
+    day: 3
   }
 }
diff --git a/build.rs b/build.rs
index 59505a5..3ee8a9f 100644
--- a/build.rs
+++ b/build.rs
@@ -72,6 +72,10 @@
         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");
     }
diff --git a/src/convert.rs b/src/convert.rs
new file mode 100644
index 0000000..afc5faf
--- /dev/null
+++ b/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/src/fallback.rs b/src/fallback.rs
index 29d3933..bbea473 100644
--- a/src/fallback.rs
+++ b/src/fallback.rs
@@ -958,12 +958,25 @@
     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('"');
@@ -985,16 +998,21 @@
 
     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);
                 }
@@ -1012,28 +1030,76 @@
         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/src/lib.rs b/src/lib.rs
index 944bc8a..6ce679d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -86,7 +86,7 @@
 //! 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.54")]
+#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.56")]
 #![cfg_attr(
     any(proc_macro_span, super_unstable),
     feature(proc_macro_span, proc_macro_span_shrink)
@@ -143,6 +143,8 @@
 mod imp;
 
 #[cfg(span_locations)]
+mod convert;
+#[cfg(span_locations)]
 mod location;
 
 use crate::extra::DelimSpan;
diff --git a/src/parse.rs b/src/parse.rs
index 82291da..be2425b 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -27,7 +27,18 @@
         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()
     }
 
@@ -756,7 +767,7 @@
 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 +859,7 @@
         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/src/rcvec.rs b/src/rcvec.rs
index 86ca7d8..62298b4 100644
--- a/src/rcvec.rs
+++ b/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 @@
         self.inner.size_hint()
     }
 }
+
+impl<T> RefUnwindSafe for RcVec<T> where T: RefUnwindSafe {}
diff --git a/tests/test.rs b/tests/test.rs
index e0af151..75f69e2 100644
--- a/tests/test.rs
+++ b/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,10 @@
     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\"",
+    );
 }
 
 #[test]
@@ -147,6 +152,10 @@
         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\"",
+    );
 }
 
 #[test]
@@ -265,6 +274,30 @@
 }
 
 #[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);