Snap for 8358640 from d45246884c4b836bf9554e7421ce0b978eed562a to mainline-go-cellbroadcast-release
Change-Id: Ifcfe3a99ee79d39bb71895ea3c814ae091665617
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index e15e24e..a0fb259 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
{
"git": {
- "sha1": "68ebadbc1b4242531c5a78fbba01c648bd58c8e7"
- }
-}
+ "sha1": "278057d0d2e59c7de95d79d42e4934783d013e83"
+ },
+ "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/.clippy.toml b/.clippy.toml
new file mode 100644
index 0000000..3d30690
--- /dev/null
+++ b/.clippy.toml
@@ -0,0 +1 @@
+msrv = "1.31.0"
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..7507077
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: dtolnay
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..b7f0028
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,62 @@
+name: CI
+
+on:
+ push:
+ pull_request:
+ schedule: [cron: "40 1 * * *"]
+
+env:
+ RUSTFLAGS: '-Dwarnings'
+
+jobs:
+ test:
+ name: Rust ${{matrix.rust}}
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ rust: [stable, beta, 1.36.0]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: ${{matrix.rust}}
+ - run: cargo test
+
+ nightly:
+ name: Rust nightly
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: dtolnay/rust-toolchain@nightly
+ with:
+ components: rust-src
+ - run: cargo test
+ - run: cargo update -Z minimal-versions
+ - run: cargo build
+
+ msrv:
+ name: Rust 1.31.0
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: dtolnay/rust-toolchain@1.31.0
+ - run: cargo check
+
+ clippy:
+ name: Clippy
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: dtolnay/rust-toolchain@clippy
+ - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
+
+ outdated:
+ name: Outdated
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: actions/checkout@v2
+ - uses: dtolnay/install@cargo-outdated
+ - run: cargo outdated --exit-code 1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4fffb2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/target
+/Cargo.lock
diff --git a/Android.bp b/Android.bp
index c894868..2ce1823 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
-// This file is generated by cargo2android.py --run --dependencies --host-first-multilib.
+// This file is generated by cargo2android.py --config cargo2android.json.
+// Do not modify this file as changes will be overridden on upgrade.
package {
default_applicable_licenses: ["external_rust_crates_quote_license"],
@@ -39,6 +40,8 @@
rust_library_host {
name: "libquote",
crate_name: "quote",
+ cargo_env_compat: true,
+ cargo_pkg_version: "1.0.15",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
@@ -50,7 +53,3 @@
],
compile_multilib: "first",
}
-
-// dependent_library ["feature_list"]
-// proc-macro2-1.0.24 "default,proc-macro"
-// unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index 411f943..c06ec0c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,19 +3,19 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
+rust-version = "1.31"
name = "quote"
-version = "1.0.9"
+version = "1.0.15"
authors = ["David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+autobenches = false
description = "Quasi-quoting macro quote!(...)"
documentation = "https://docs.rs/quote/"
readme = "README.md"
@@ -26,13 +26,13 @@
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies.proc-macro2]
-version = "1.0.20"
+version = "1.0.36"
default-features = false
[dev-dependencies.rustversion]
version = "1.0"
[dev-dependencies.trybuild]
-version = "1.0.19"
+version = "1.0.52"
features = ["diff"]
[features]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index b95c6c5..9dd4c77 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "quote"
-version = "1.0.9" # don't forget to update html_root_url, version in readme for breaking changes
+version = "1.0.15" # don't forget to update html_root_url, version in readme for breaking changes
authors = ["David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "Quasi-quoting macro quote!(...)"
@@ -9,15 +9,16 @@
keywords = ["syn"]
categories = ["development-tools::procedural-macro-helpers"]
readme = "README.md"
-include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
edition = "2018"
+autobenches = false
+rust-version = "1.31"
[dependencies]
-proc-macro2 = { version = "1.0.20", default-features = false }
+proc-macro2 = { version = "1.0.36", default-features = false }
[dev-dependencies]
rustversion = "1.0"
-trybuild = { version = "1.0.19", features = ["diff"] }
+trybuild = { version = "1.0.52", features = ["diff"] }
[features]
default = ["proc-macro"]
@@ -25,5 +26,8 @@
# libproc_macro in the rustc compiler.
proc-macro = ["proc-macro2/proc-macro"]
+[workspace]
+members = ["benches"]
+
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
diff --git a/METADATA b/METADATA
index ee587f2..f788fb6 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/quote/quote-1.0.9.crate"
+ value: "https://static.crates.io/crates/quote/quote-1.0.15.crate"
}
- version: "1.0.9"
+ version: "1.0.15"
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 2
- day: 12
+ year: 2022
+ month: 3
+ day: 1
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index a1620b5..76a8253 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,68 +1,231 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
+ "imports": [
+ {
+ "path": "external/rust/crates/anyhow"
+ },
+ {
+ "path": "external/rust/crates/arbitrary"
+ },
+ {
+ "path": "external/rust/crates/argh"
+ },
+ {
+ "path": "external/rust/crates/base64"
+ },
+ {
+ "path": "external/rust/crates/bitflags"
+ },
+ {
+ "path": "external/rust/crates/bytes"
+ },
+ {
+ "path": "external/rust/crates/either"
+ },
+ {
+ "path": "external/rust/crates/futures-util"
+ },
+ {
+ "path": "external/rust/crates/jni"
+ },
+ {
+ "path": "external/rust/crates/libm"
+ },
+ {
+ "path": "external/rust/crates/libsqlite3-sys"
+ },
+ {
+ "path": "external/rust/crates/oid-registry"
+ },
+ {
+ "path": "external/rust/crates/rand_chacha"
+ },
+ {
+ "path": "external/rust/crates/serde"
+ },
+ {
+ "path": "external/rust/crates/serde-xml-rs"
+ },
+ {
+ "path": "external/rust/crates/serde_cbor"
+ },
+ {
+ "path": "external/rust/crates/slab"
+ },
+ {
+ "path": "external/rust/crates/tinytemplate"
+ },
+ {
+ "path": "external/rust/crates/tinyvec"
+ },
+ {
+ "path": "external/rust/crates/tokio"
+ },
+ {
+ "path": "external/rust/crates/tokio-test"
+ },
+ {
+ "path": "external/rust/crates/unicode-bidi"
+ },
+ {
+ "path": "external/rust/crates/unicode-xid"
+ },
+ {
+ "path": "external/rust/crates/url"
+ }
+ ],
"presubmit": [
{
- "name": "url_device_test_src_lib"
+ "name": "ZipFuseTest"
},
{
- "name": "anyhow_device_test_tests_test_downcast"
+ "name": "apkdmverity.test"
},
{
- "name": "anyhow_device_test_tests_test_repr"
+ "name": "authfs_device_test_src_lib"
+ },
+ {
+ "name": "diced_open_dice_cbor_test"
+ },
+ {
+ "name": "diced_sample_inputs_test"
+ },
+ {
+ "name": "diced_test"
+ },
+ {
+ "name": "diced_utils_test"
+ },
+ {
+ "name": "diced_vendor_test"
+ },
+ {
+ "name": "doh_unit_test"
+ },
+ {
+ "name": "keystore2_crypto_test_rust"
+ },
+ {
+ "name": "keystore2_km_compat_test"
+ },
+ {
+ "name": "keystore2_selinux_concurrency_test"
},
{
"name": "keystore2_selinux_test"
},
{
- "name": "anyhow_device_test_tests_test_fmt"
+ "name": "keystore2_test"
},
{
- "name": "libm_device_test_src_lib"
+ "name": "keystore2_test_utils_test"
},
{
- "name": "anyhow_device_test_tests_test_convert"
+ "name": "keystore2_vintf_test"
},
{
- "name": "libsqlite3-sys_device_test_src_lib"
+ "name": "legacykeystore_test"
},
{
- "name": "anyhow_device_test_tests_test_source"
+ "name": "libapkverify.integration_test"
},
{
- "name": "unicode-bidi_device_test_src_lib"
+ "name": "libapkverify.test"
},
{
- "name": "anyhow_device_test_src_lib"
+ "name": "libcert_request_validator_tests"
},
{
- "name": "anyhow_device_test_tests_test_autotrait"
+ "name": "libidsig.test"
},
{
- "name": "anyhow_device_test_tests_test_context"
+ "name": "librustutils_test"
},
{
- "name": "anyhow_device_test_tests_test_macros"
+ "name": "microdroid_manager_test"
},
{
- "name": "anyhow_device_test_tests_test_chain"
+ "name": "rustBinderTest"
},
{
- "name": "anyhow_device_test_tests_test_ffi"
+ "name": "virtualizationservice_device_test"
+ }
+ ],
+ "presubmit-rust": [
+ {
+ "name": "ZipFuseTest"
},
{
- "name": "serde_test_device_test_src_lib"
+ "name": "apkdmverity.test"
},
{
- "name": "futures-util_device_test_src_lib"
+ "name": "authfs_device_test_src_lib"
+ },
+ {
+ "name": "diced_open_dice_cbor_test"
+ },
+ {
+ "name": "diced_sample_inputs_test"
+ },
+ {
+ "name": "diced_test"
+ },
+ {
+ "name": "diced_utils_test"
+ },
+ {
+ "name": "diced_vendor_test"
+ },
+ {
+ "name": "doh_unit_test"
+ },
+ {
+ "name": "keystore2_crypto_test_rust"
+ },
+ {
+ "name": "keystore2_km_compat_test"
+ },
+ {
+ "name": "keystore2_selinux_concurrency_test"
+ },
+ {
+ "name": "keystore2_selinux_test"
},
{
"name": "keystore2_test"
},
{
- "name": "anyhow_device_test_tests_test_boxed"
+ "name": "keystore2_test_utils_test"
},
{
- "name": "keystore2_crypto_test_rust"
+ "name": "keystore2_vintf_test"
+ },
+ {
+ "name": "legacykeystore_test"
+ },
+ {
+ "name": "libapkverify.integration_test"
+ },
+ {
+ "name": "libapkverify.test"
+ },
+ {
+ "name": "libcert_request_validator_tests"
+ },
+ {
+ "name": "libidsig.test"
+ },
+ {
+ "name": "librustutils_test"
+ },
+ {
+ "name": "microdroid_manager_test"
+ },
+ {
+ "name": "rustBinderTest"
+ },
+ {
+ "name": "virtualizationservice_device_test"
}
]
}
diff --git a/cargo2android.json b/cargo2android.json
new file mode 100644
index 0000000..bb77633
--- /dev/null
+++ b/cargo2android.json
@@ -0,0 +1,4 @@
+{
+ "host-first-multilib": true,
+ "run": true
+}
\ No newline at end of file
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..20fe888
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+components = ["rust-src"]
diff --git a/src/format.rs b/src/format.rs
index 745cb5d..5e44b01 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -11,10 +11,10 @@
/// of format types to traits is:
///
/// * `{}` ⇒ [`IdentFragment`]
-/// * `{:o}` ⇒ [`Octal`](`std::fmt::Octal`)
-/// * `{:x}` ⇒ [`LowerHex`](`std::fmt::LowerHex`)
-/// * `{:X}` ⇒ [`UpperHex`](`std::fmt::UpperHex`)
-/// * `{:b}` ⇒ [`Binary`](`std::fmt::Binary`)
+/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
+/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
+/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
+/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
///
/// See [`std::fmt`] for more information.
///
@@ -29,7 +29,8 @@
/// unsigned integers and strings.
/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
///
-/// [`Ident`]: `proc_macro2::Ident`
+/// [`IdentFragment`]: crate::IdentFragment
+/// [`Ident`]: proc_macro2::Ident
///
/// <br>
///
@@ -59,8 +60,8 @@
/// format_ident!("MyIdent", span = my_span);
/// ```
///
-/// [`Span`]: `proc_macro2::Span`
-/// [`Span::call_site`]: `proc_macro2::Span::call_site`
+/// [`Span`]: proc_macro2::Span
+/// [`Span::call_site`]: proc_macro2::Span::call_site
///
/// <p><br></p>
///
diff --git a/src/ident_fragment.rs b/src/ident_fragment.rs
index e7472fe..67e2e33 100644
--- a/src/ident_fragment.rs
+++ b/src/ident_fragment.rs
@@ -79,7 +79,7 @@
}
}
)*
- }
+ };
}
ident_fragment_display!(bool, str, String, char);
diff --git a/src/lib.rs b/src/lib.rs
index 356e43a..02f6532 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -81,12 +81,14 @@
//! ```
// Quote types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/quote/1.0.9")]
+#![doc(html_root_url = "https://docs.rs/quote/1.0.15")]
#![allow(
clippy::doc_markdown,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
- clippy::module_name_repetitions
+ clippy::module_name_repetitions,
+ // false positive https://github.com/rust-lang/rust-clippy/issues/6983
+ clippy::wrong_self_convention,
)]
#[cfg(all(
@@ -743,9 +745,15 @@
// warnings on anything below the loop. We use has_iter to detect and
// fail to compile when there are no iterators, so here we just work
// around the unneeded extra warning.
- while true {
+ //
+ // FIXME: temporariliy working around Clippy regression.
+ // https://github.com/rust-lang/rust-clippy/issues/7768
+ loop {
$crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
$crate::quote_each_token!($tokens $($inner)*);
+ if false {
+ break;
+ }
}
}};
($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
@@ -757,13 +765,16 @@
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
$crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
let _: $crate::__private::HasIterator = has_iter;
- while true {
+ loop {
$crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
if _i > 0 {
$crate::quote_token!($tokens $sep);
}
_i += 1;
$crate::quote_each_token!($tokens $($inner)*);
+ if false {
+ break;
+ }
}
}};
($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
@@ -799,9 +810,15 @@
// warnings on anything below the loop. We use has_iter to detect and
// fail to compile when there are no iterators, so here we just work
// around the unneeded extra warning.
- while true {
+ //
+ // FIXME: temporariliy working around Clippy regression.
+ // https://github.com/rust-lang/rust-clippy/issues/7768
+ loop {
$crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
$crate::quote_each_token_spanned!($tokens $span $($inner)*);
+ if false {
+ break;
+ }
}
}};
($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
@@ -813,13 +830,16 @@
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
$crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
let _: $crate::__private::HasIterator = has_iter;
- while true {
+ loop {
$crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
if _i > 0 {
$crate::quote_token_spanned!($tokens $span $sep);
}
_i += 1;
$crate::quote_each_token_spanned!($tokens $span $($inner)*);
+ if false {
+ break;
+ }
}
}};
($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
@@ -1046,6 +1066,14 @@
$crate::__private::push_ident(&mut $tokens, stringify!($ident));
};
+ ($tokens:ident $lifetime:lifetime) => {
+ $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
+ };
+
+ ($tokens:ident _) => {
+ $crate::__private::push_underscore(&mut $tokens);
+ };
+
($tokens:ident $other:tt) => {
$crate::__private::parse(&mut $tokens, stringify!($other));
};
@@ -1261,6 +1289,14 @@
$crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
};
+ ($tokens:ident $span:ident $lifetime:lifetime) => {
+ $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
+ };
+
+ ($tokens:ident $span:ident _) => {
+ $crate::__private::push_underscore_spanned(&mut $tokens, $span);
+ };
+
($tokens:ident $span:ident $other:tt) => {
$crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
};
diff --git a/src/runtime.rs b/src/runtime.rs
index db3b6a9..52955cb 100644
--- a/src/runtime.rs
+++ b/src/runtime.rs
@@ -1,5 +1,6 @@
use crate::{IdentFragment, ToTokens, TokenStreamExt};
use std::fmt;
+use std::iter;
use std::ops::BitOr;
pub use proc_macro2::*;
@@ -123,25 +124,6 @@
}
}
- macro_rules! array_rep_slice {
- ($($l:tt)*) => {
- $(
- impl<'q, T: 'q> RepAsIteratorExt<'q> for [T; $l] {
- type Iter = slice::Iter<'q, T>;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- (self.iter(), HasIter)
- }
- }
- )*
- }
- }
-
- array_rep_slice!(
- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
- );
-
impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp<T> {
type Iter = T::Iter;
@@ -197,15 +179,29 @@
pub fn parse(tokens: &mut TokenStream, s: &str) {
let s: TokenStream = s.parse().expect("invalid token stream");
- tokens.extend(s);
+ tokens.extend(iter::once(s));
}
pub fn parse_spanned(tokens: &mut TokenStream, span: Span, s: &str) {
let s: TokenStream = s.parse().expect("invalid token stream");
- tokens.extend(s.into_iter().map(|mut t| {
- t.set_span(span);
- t
- }));
+ tokens.extend(s.into_iter().map(|t| respan_token_tree(t, span)));
+}
+
+// Token tree with every span replaced by the given one.
+fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
+ match &mut token {
+ TokenTree::Group(g) => {
+ let stream = g
+ .stream()
+ .into_iter()
+ .map(|token| respan_token_tree(token, span))
+ .collect();
+ *g = Group::new(g.delimiter(), stream);
+ g.set_span(span);
+ }
+ other => other.set_span(span),
+ }
+ token
}
pub fn push_ident(tokens: &mut TokenStream, s: &str) {
@@ -232,6 +228,70 @@
}
}
+pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) {
+ struct Lifetime<'a> {
+ name: &'a str,
+ state: u8,
+ }
+
+ impl<'a> Iterator for Lifetime<'a> {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.state {
+ 0 => {
+ self.state = 1;
+ Some(TokenTree::Punct(Punct::new('\'', Spacing::Joint)))
+ }
+ 1 => {
+ self.state = 2;
+ Some(TokenTree::Ident(Ident::new(self.name, Span::call_site())))
+ }
+ _ => None,
+ }
+ }
+ }
+
+ tokens.extend(Lifetime {
+ name: &lifetime[1..],
+ state: 0,
+ });
+}
+
+pub fn push_lifetime_spanned(tokens: &mut TokenStream, span: Span, lifetime: &str) {
+ struct Lifetime<'a> {
+ name: &'a str,
+ span: Span,
+ state: u8,
+ }
+
+ impl<'a> Iterator for Lifetime<'a> {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.state {
+ 0 => {
+ self.state = 1;
+ let mut apostrophe = Punct::new('\'', Spacing::Joint);
+ apostrophe.set_span(self.span);
+ Some(TokenTree::Punct(apostrophe))
+ }
+ 1 => {
+ self.state = 2;
+ Some(TokenTree::Ident(Ident::new(self.name, self.span)))
+ }
+ _ => None,
+ }
+ }
+ }
+
+ tokens.extend(Lifetime {
+ name: &lifetime[1..],
+ span,
+ state: 0,
+ });
+}
+
macro_rules! push_punct {
($name:ident $spanned:ident $char1:tt) => {
pub fn $name(tokens: &mut TokenStream) {
@@ -322,6 +382,14 @@
push_punct!(push_sub push_sub_spanned '-');
push_punct!(push_sub_eq push_sub_eq_spanned '-' '=');
+pub fn push_underscore(tokens: &mut TokenStream) {
+ push_underscore_spanned(tokens, Span::call_site());
+}
+
+pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) {
+ tokens.append(Ident::new("_", span));
+}
+
// Helper method for constructing identifiers from the `format_ident!` macro,
// handling `r#` prefixes.
//
diff --git a/src/to_tokens.rs b/src/to_tokens.rs
index 7f98083..dbb8dfc 100644
--- a/src/to_tokens.rs
+++ b/src/to_tokens.rs
@@ -127,13 +127,15 @@
}
macro_rules! primitive {
- ($($t:ident => $name:ident)*) => ($(
- impl ToTokens for $t {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(Literal::$name(*self));
+ ($($t:ident => $name:ident)*) => {
+ $(
+ impl ToTokens for $t {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Literal::$name(*self));
+ }
}
- }
- )*)
+ )*
+ };
}
primitive! {
diff --git a/tests/test.rs b/tests/test.rs
index d5a3490..11f8a31 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,4 +1,10 @@
-#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
+#![allow(
+ clippy::blacklisted_name,
+ clippy::let_underscore_drop,
+ clippy::shadow_unrelated,
+ clippy::unseparated_literal_suffix,
+ clippy::used_underscore_binding
+)]
use std::borrow::Cow;
use std::collections::BTreeSet;
@@ -79,6 +85,27 @@
}
#[test]
+fn test_array() {
+ let array: [u8; 40] = [0; 40];
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[u8; 40] = &[0; 40];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[u8] = &[0; 40];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+
+ let array: [X; 2] = [X, X]; // !Copy
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[X; 2] = &[X, X];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[X] = &[X, X];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+}
+
+#[test]
fn test_advanced() {
let generics = quote!( <'a, T> );
@@ -149,10 +176,11 @@
let uusize = 1usize;
let tokens = quote! {
+ 1 1i32 1u256
#ii8 #ii16 #ii32 #ii64 #ii128 #iisize
#uu8 #uu16 #uu32 #uu64 #uu128 #uusize
};
- let expected = "- 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";
+ let expected = "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";
assert_eq!(expected, tokens.to_string());
}
@@ -203,6 +231,31 @@
}
#[test]
+fn test_interpolated_literal() {
+ macro_rules! m {
+ ($literal:literal) => {
+ quote!($literal)
+ };
+ }
+
+ let tokens = m!(1);
+ let expected = "1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-1);
+ let expected = "- 1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(true);
+ let expected = "true";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-true);
+ let expected = "- true";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
fn test_ident() {
let foo = Ident::new("Foo", Span::call_site());
let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
@@ -212,6 +265,13 @@
}
#[test]
+fn test_underscore() {
+ let tokens = quote!(let _;);
+ let expected = "let _ ;";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
fn test_duplicate() {
let ch = 'x';
diff --git a/tests/ui/does-not-have-iter-interpolated-dup.stderr b/tests/ui/does-not-have-iter-interpolated-dup.stderr
new file mode 100644
index 0000000..bcd631d
--- /dev/null
+++ b/tests/ui/does-not-have-iter-interpolated-dup.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5
+ |
+8 | quote!(#(#nonrep #nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/does-not-have-iter-interpolated.stderr b/tests/ui/does-not-have-iter-interpolated.stderr
new file mode 100644
index 0000000..799837b
--- /dev/null
+++ b/tests/ui/does-not-have-iter-interpolated.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated.rs:8:5
+ |
+8 | quote!(#(#nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/does-not-have-iter-separated.stderr b/tests/ui/does-not-have-iter-separated.stderr
new file mode 100644
index 0000000..aa2e693
--- /dev/null
+++ b/tests/ui/does-not-have-iter-separated.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-separated.rs:4:5
+ |
+4 | quote!(#(a b),*);
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/does-not-have-iter.stderr b/tests/ui/does-not-have-iter.stderr
new file mode 100644
index 0000000..c2692fe
--- /dev/null
+++ b/tests/ui/does-not-have-iter.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter.rs:4:5
+ |
+4 | quote!(#(a b)*);
+ | ^^^^^^^^^^^^^^^
+ | |
+ | expected struct `HasIterator`, found struct `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/not-quotable.stderr b/tests/ui/not-quotable.stderr
new file mode 100644
index 0000000..5dd13bf
--- /dev/null
+++ b/tests/ui/not-quotable.stderr
@@ -0,0 +1,7 @@
+error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
+ --> tests/ui/not-quotable.rs:6:13
+ |
+6 | let _ = quote! { #ip };
+ | ^^^^^^^^^^^^^^ the trait `ToTokens` is not implemented for `Ipv4Addr`
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/not-repeatable.stderr b/tests/ui/not-repeatable.stderr
new file mode 100644
index 0000000..cd5a1e4
--- /dev/null
+++ b/tests/ui/not-repeatable.stderr
@@ -0,0 +1,47 @@
+error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
+ --> tests/ui/not-repeatable.rs:7:13
+ |
+3 | struct Ipv4Addr;
+ | ----------------
+ | |
+ | method `quote_into_iter` not found for this
+ | doesn't satisfy `Ipv4Addr: Iterator`
+ | doesn't satisfy `Ipv4Addr: ToTokens`
+ | doesn't satisfy `Ipv4Addr: quote::__private::ext::RepIteratorExt`
+ | doesn't satisfy `Ipv4Addr: quote::__private::ext::RepToTokensExt`
+...
+7 | let _ = quote! { #(#ip)* };
+ | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `Ipv4Addr: Iterator`
+ which is required by `Ipv4Addr: quote::__private::ext::RepIteratorExt`
+ `&Ipv4Addr: Iterator`
+ which is required by `&Ipv4Addr: quote::__private::ext::RepIteratorExt`
+ `Ipv4Addr: ToTokens`
+ which is required by `Ipv4Addr: quote::__private::ext::RepToTokensExt`
+ `&mut Ipv4Addr: Iterator`
+ which is required by `&mut Ipv4Addr: quote::__private::ext::RepIteratorExt`
+note: the following traits must be implemented
+ --> $RUST/core/src/iter/traits/iterator.rs
+ |
+ | / pub trait Iterator {
+ | | /// The type of the elements being iterated over.
+ | | #[stable(feature = "rust1", since = "1.0.0")]
+ | | type Item;
+... |
+ | | }
+ | | }
+ | |__^
+ |
+ ::: src/to_tokens.rs
+ |
+ | / pub trait ToTokens {
+ | | /// Write `self` to the given `TokenStream`.
+ | | ///
+ | | /// The token append methods provided by the [`TokenStreamExt`] extension
+... |
+ | | }
+ | | }
+ | |_^
+ = note: this error originates in the macro `$crate::quote_bind_into_iter` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/wrong-type-span.rs b/tests/ui/wrong-type-span.rs
index 1ce391c..d5601c8 100644
--- a/tests/ui/wrong-type-span.rs
+++ b/tests/ui/wrong-type-span.rs
@@ -2,6 +2,6 @@
fn main() {
let span = "";
- let x = 0;
+ let x = 0i32;
quote_spanned!(span=> #x);
}
diff --git a/tests/ui/wrong-type-span.stderr b/tests/ui/wrong-type-span.stderr
new file mode 100644
index 0000000..c774a4c
--- /dev/null
+++ b/tests/ui/wrong-type-span.stderr
@@ -0,0 +1,8 @@
+error[E0308]: mismatched types
+ --> tests/ui/wrong-type-span.rs:6:20
+ |
+6 | quote_spanned!(span=> #x);
+ | ---------------^^^^------
+ | | |
+ | | expected struct `Span`, found `&str`
+ | expected due to this