aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:00:19 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:00:19 +0000
commit4c795e2dfa1793dcc24e9963a800b6f4f84b0da7 (patch)
tree207634b084b5affe542b82e8e7ef309ecba81fcf
parentcd698d20322edc35e7438a67699a98e6d1588cfc (diff)
parent8e4d2330aa4e28e0a5bf78fc3f75d615832d46a7 (diff)
downloadquote-android14-mainline-extservices-release.tar.gz
Change-Id: I1f1b7a31e522fc768d786447bdf54462ae3c04b7
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--.github/workflows/ci.yml42
-rw-r--r--Android.bp4
-rw-r--r--Cargo.toml17
-rw-r--r--Cargo.toml.orig20
-rw-r--r--LICENSE-MIT2
-rw-r--r--METADATA14
-rw-r--r--README.md4
-rw-r--r--TEST_MAPPING152
-rw-r--r--build.rs38
-rw-r--r--src/ext.rs4
-rw-r--r--src/format.rs11
-rw-r--r--src/ident_fragment.rs2
-rw-r--r--src/lib.rs559
-rw-r--r--src/runtime.rs64
-rw-r--r--src/spanned.rs7
-rw-r--r--src/to_tokens.rs6
-rw-r--r--tests/compiletest.rs1
-rw-r--r--tests/test.rs18
-rw-r--r--tests/ui/does-not-have-iter-interpolated-dup.stderr2
-rw-r--r--tests/ui/does-not-have-iter-interpolated.stderr2
-rw-r--r--tests/ui/does-not-have-iter-separated.stderr2
-rw-r--r--tests/ui/does-not-have-iter.stderr2
-rw-r--r--tests/ui/not-quotable.rs2
-rw-r--r--tests/ui/not-quotable.stderr21
-rw-r--r--tests/ui/not-repeatable.rs2
-rw-r--r--tests/ui/not-repeatable.stderr78
27 files changed, 596 insertions, 482 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index a0fb259..88ac651 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "278057d0d2e59c7de95d79d42e4934783d013e83"
+ "sha1": "550af67f9e0be89897902031f153fb3d40360017"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b7f0028..5e67515 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,8 +5,11 @@ on:
pull_request:
schedule: [cron: "40 1 * * *"]
+permissions:
+ contents: read
+
env:
- RUSTFLAGS: '-Dwarnings'
+ RUSTFLAGS: -Dwarnings
jobs:
test:
@@ -15,19 +18,22 @@ jobs:
strategy:
fail-fast: false
matrix:
- rust: [stable, beta, 1.36.0]
+ rust: [stable, beta, 1.56.0]
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
+ components: rust-src
- run: cargo test
nightly:
name: Rust nightly
runs-on: ubuntu-latest
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src
@@ -38,25 +44,43 @@ jobs:
msrv:
name: Rust 1.31.0
runs-on: ubuntu-latest
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@1.31.0
+ with:
+ components: rust-src
- run: cargo check
clippy:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
- - uses: dtolnay/rust-toolchain@clippy
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@nightly
+ with:
+ components: clippy, rust-src
- run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
+ miri:
+ name: Miri
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@miri
+ - run: cargo miri test
+ env:
+ MIRIFLAGS: -Zmiri-strict-provenance
+
outdated:
name: Outdated
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/install@cargo-outdated
- - run: cargo outdated --exit-code 1
+ - run: cargo outdated --workspace --exit-code 1
diff --git a/Android.bp b/Android.bp
index 2ce1823..4709e22 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,7 +41,7 @@ rust_library_host {
name: "libquote",
crate_name: "quote",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.15",
+ cargo_pkg_version: "1.0.23",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
@@ -52,4 +52,6 @@ rust_library_host {
"libproc_macro2",
],
compile_multilib: "first",
+ product_available: true,
+ vendor_available: true,
}
diff --git a/Cargo.toml b/Cargo.toml
index c06ec0c..4d6b326 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,26 +13,35 @@
edition = "2018"
rust-version = "1.31"
name = "quote"
-version = "1.0.15"
+version = "1.0.23"
authors = ["David Tolnay <dtolnay@gmail.com>"]
autobenches = false
description = "Quasi-quoting macro quote!(...)"
documentation = "https://docs.rs/quote/"
readme = "README.md"
-keywords = ["syn"]
+keywords = [
+ "macros",
+ "syn",
+]
categories = ["development-tools::procedural-macro-helpers"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/quote"
+
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
[dependencies.proc-macro2]
-version = "1.0.36"
+version = "1.0.40"
default-features = false
+
[dev-dependencies.rustversion]
version = "1.0"
[dev-dependencies.trybuild]
-version = "1.0.52"
+version = "1.0.66"
features = ["diff"]
[features]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 9dd4c77..f99b48f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,24 +1,23 @@
[package]
name = "quote"
-version = "1.0.15" # don't forget to update html_root_url, version in readme for breaking changes
+version = "1.0.23" # 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"
+autobenches = false
+categories = ["development-tools::procedural-macro-helpers"]
description = "Quasi-quoting macro quote!(...)"
-repository = "https://github.com/dtolnay/quote"
documentation = "https://docs.rs/quote/"
-keywords = ["syn"]
-categories = ["development-tools::procedural-macro-helpers"]
-readme = "README.md"
edition = "2018"
-autobenches = false
+keywords = ["macros", "syn"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/quote"
rust-version = "1.31"
[dependencies]
-proc-macro2 = { version = "1.0.36", default-features = false }
+proc-macro2 = { version = "1.0.40", default-features = false }
[dev-dependencies]
rustversion = "1.0"
-trybuild = { version = "1.0.52", features = ["diff"] }
+trybuild = { version = "1.0.66", features = ["diff"] }
[features]
default = ["proc-macro"]
@@ -26,6 +25,9 @@ default = ["proc-macro"]
# libproc_macro in the rustc compiler.
proc-macro = ["proc-macro2/proc-macro"]
+[lib]
+doc-scrape-examples = false
+
[workspace]
members = ["benches"]
diff --git a/LICENSE-MIT b/LICENSE-MIT
index 40b8817..31aa793 100644
--- a/LICENSE-MIT
+++ b/LICENSE-MIT
@@ -1,5 +1,3 @@
-Copyright (c) 2016 The Rust Project Developers
-
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
diff --git a/METADATA b/METADATA
index f788fb6..3297eb7 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/quote
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "quote"
description: "Quasi-quoting macro quote!(...)"
third_party {
@@ -7,13 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/quote/quote-1.0.15.crate"
+ value: "https://static.crates.io/crates/quote/quote-1.0.23.crate"
}
- version: "1.0.15"
+ version: "1.0.23"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 3
- day: 1
+ year: 2023
+ month: 2
+ day: 6
}
}
diff --git a/README.md b/README.md
index 57b2a62..74e99ce 100644
--- a/README.md
+++ b/README.md
@@ -3,8 +3,8 @@ Rust Quasi-Quoting
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/quote-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/quote)
[<img alt="crates.io" src="https://img.shields.io/crates/v/quote.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/quote)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-quote-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/quote)
-[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/quote/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/quote/actions?query=branch%3Amaster)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-quote-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/quote)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/quote/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/quote/actions?query=branch%3Amaster)
This crate provides the [`quote!`] macro for turning Rust syntax tree data
structures into tokens of source code.
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 76a8253..7c46892 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -11,6 +11,9 @@
"path": "external/rust/crates/argh"
},
{
+ "path": "external/rust/crates/async-stream"
+ },
+ {
"path": "external/rust/crates/base64"
},
{
@@ -20,12 +23,30 @@
"path": "external/rust/crates/bytes"
},
{
+ "path": "external/rust/crates/coset"
+ },
+ {
"path": "external/rust/crates/either"
},
{
+ "path": "external/rust/crates/futures-channel"
+ },
+ {
+ "path": "external/rust/crates/futures-executor"
+ },
+ {
+ "path": "external/rust/crates/futures-test"
+ },
+ {
"path": "external/rust/crates/futures-util"
},
{
+ "path": "external/rust/crates/hashbrown"
+ },
+ {
+ "path": "external/rust/crates/hashlink"
+ },
+ {
"path": "external/rust/crates/jni"
},
{
@@ -72,160 +93,75 @@
},
{
"path": "external/rust/crates/url"
- }
- ],
- "presubmit": [
- {
- "name": "ZipFuseTest"
- },
- {
- "name": "apkdmverity.test"
- },
- {
- "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": "keystore2_test_utils_test"
- },
- {
- "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"
- }
- ],
- "presubmit-rust": [
- {
- "name": "ZipFuseTest"
- },
- {
- "name": "apkdmverity.test"
},
{
- "name": "authfs_device_test_src_lib"
+ "path": "external/rust/crates/virtio-drivers"
},
{
- "name": "diced_open_dice_cbor_test"
+ "path": "external/rust/crates/zerocopy"
},
{
- "name": "diced_sample_inputs_test"
+ "path": "external/rust/crates/zeroize"
},
{
- "name": "diced_test"
+ "path": "external/uwb/src"
},
{
- "name": "diced_utils_test"
+ "path": "packages/modules/DnsResolver"
},
{
- "name": "diced_vendor_test"
+ "path": "packages/modules/Virtualization/apkdmverity"
},
{
- "name": "doh_unit_test"
+ "path": "packages/modules/Virtualization/authfs"
},
{
- "name": "keystore2_crypto_test_rust"
+ "path": "packages/modules/Virtualization/avmd"
},
{
- "name": "keystore2_km_compat_test"
+ "path": "packages/modules/Virtualization/encryptedstore"
},
{
- "name": "keystore2_selinux_concurrency_test"
+ "path": "packages/modules/Virtualization/libs/apexutil"
},
{
- "name": "keystore2_selinux_test"
+ "path": "packages/modules/Virtualization/libs/apkverify"
},
{
- "name": "keystore2_test"
+ "path": "packages/modules/Virtualization/libs/devicemapper"
},
{
- "name": "keystore2_test_utils_test"
+ "path": "packages/modules/Virtualization/microdroid_manager"
},
{
- "name": "keystore2_vintf_test"
+ "path": "packages/modules/Virtualization/virtualizationmanager"
},
{
- "name": "legacykeystore_test"
+ "path": "packages/modules/Virtualization/vm"
},
{
- "name": "libapkverify.integration_test"
+ "path": "packages/modules/Virtualization/zipfuse"
},
{
- "name": "libapkverify.test"
+ "path": "system/keymint/derive"
},
{
- "name": "libcert_request_validator_tests"
+ "path": "system/keymint/hal"
},
{
- "name": "libidsig.test"
+ "path": "system/security/diced"
},
{
- "name": "librustutils_test"
+ "path": "system/security/keystore2"
},
{
- "name": "microdroid_manager_test"
+ "path": "system/security/keystore2/legacykeystore"
},
{
- "name": "rustBinderTest"
+ "path": "system/security/keystore2/selinux"
},
{
- "name": "virtualizationservice_device_test"
+ "path": "system/security/keystore2/src/crypto"
}
]
}
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..a7e6b2c
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,38 @@
+use std::env;
+use std::process::{self, Command};
+use std::str;
+
+fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+
+ let version = match rustc_version() {
+ Some(version) => version,
+ None => return,
+ };
+
+ if version.minor < 31 {
+ eprintln!("Minimum supported rustc version is 1.31");
+ process::exit(1);
+ }
+
+ if version.minor < 53 {
+ // https://github.com/rust-lang/rust/issues/43081
+ println!("cargo:rustc-cfg=needs_invalid_span_workaround");
+ }
+}
+
+struct RustcVersion {
+ minor: u32,
+}
+
+fn rustc_version() -> Option<RustcVersion> {
+ let rustc = env::var_os("RUSTC")?;
+ let output = Command::new(rustc).arg("--version").output().ok()?;
+ let version = str::from_utf8(&output.stdout).ok()?;
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return None;
+ }
+ let minor = pieces.next()?.parse().ok()?;
+ Some(RustcVersion { minor })
+}
diff --git a/src/ext.rs b/src/ext.rs
index 9e9b4a5..92c2315 100644
--- a/src/ext.rs
+++ b/src/ext.rs
@@ -1,7 +1,5 @@
use super::ToTokens;
-
-use std::iter;
-
+use core::iter;
use proc_macro2::{TokenStream, TokenTree};
/// TokenStream extension trait with methods for appending tokens.
diff --git a/src/format.rs b/src/format.rs
index 5e44b01..3cddbd2 100644
--- a/src/format.rs
+++ b/src/format.rs
@@ -111,14 +111,14 @@
macro_rules! format_ident {
($fmt:expr) => {
$crate::format_ident_impl!([
- ::std::option::Option::None,
+ $crate::__private::Option::None,
$fmt
])
};
($fmt:expr, $($rest:tt)*) => {
$crate::format_ident_impl!([
- ::std::option::Option::None,
+ $crate::__private::Option::None,
$fmt
] $($rest)*)
};
@@ -129,7 +129,10 @@ macro_rules! format_ident {
macro_rules! format_ident_impl {
// Final state
([$span:expr, $($fmt:tt)*]) => {
- $crate::__private::mk_ident(&format!($($fmt)*), $span)
+ $crate::__private::mk_ident(
+ &$crate::__private::format!($($fmt)*),
+ $span,
+ )
};
// Span argument
@@ -138,7 +141,7 @@ macro_rules! format_ident_impl {
};
([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
$crate::format_ident_impl!([
- ::std::option::Option::Some::<$crate::__private::Span>($span),
+ $crate::__private::Option::Some::<$crate::__private::Span>($span),
$($fmt)*
] $($rest)*)
};
diff --git a/src/ident_fragment.rs b/src/ident_fragment.rs
index 67e2e33..cf74024 100644
--- a/src/ident_fragment.rs
+++ b/src/ident_fragment.rs
@@ -1,6 +1,6 @@
+use core::fmt;
use proc_macro2::{Ident, Span};
use std::borrow::Cow;
-use std::fmt;
/// Specialized formatting trait used by `format_ident!`.
///
diff --git a/src/lib.rs b/src/lib.rs
index 02f6532..adc14c5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
@@ -81,7 +81,7 @@
//! ```
// Quote types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/quote/1.0.15")]
+#![doc(html_root_url = "https://docs.rs/quote/1.0.23")]
#![allow(
clippy::doc_markdown,
clippy::missing_errors_doc,
@@ -389,14 +389,6 @@ pub mod spanned;
/// }
/// ```
///
-/// Macro calls in a doc attribute are not valid syntax:
-///
-/// ```compile_fail
-/// quote! {
-/// #[doc = concat!("try to interpolate: ", stringify!(#ident))]
-/// }
-/// ```
-///
/// Instead the best way to build doc comments that involve variables is by
/// formatting the doc string literal outside of quote.
///
@@ -476,14 +468,45 @@ pub mod spanned;
/// # }
/// # }
/// ```
+#[cfg(doc)]
+#[macro_export]
+macro_rules! quote {
+ ($($tt:tt)*) => {
+ ...
+ };
+}
+
+#[cfg(not(doc))]
#[macro_export]
macro_rules! quote {
() => {
$crate::__private::TokenStream::new()
};
+
+ // Special case rule for a single tt, for performance.
+ ($tt:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::quote_token!{$tt _s}
+ _s
+ }};
+
+ // Special case rules for two tts, for performance.
+ (# $var:ident) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::ToTokens::to_tokens(&$var, &mut _s);
+ _s
+ }};
+ ($tt1:tt $tt2:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::quote_token!{$tt1 _s}
+ $crate::quote_token!{$tt2 _s}
+ _s
+ }};
+
+ // Rule for any other number of tokens.
($($tt:tt)*) => {{
let mut _s = $crate::__private::TokenStream::new();
- $crate::quote_each_token!(_s $($tt)*);
+ $crate::quote_each_token!{_s $($tt)*}
_s
}};
}
@@ -584,16 +607,50 @@ macro_rules! quote {
/// In this example it is important for the where-clause to be spanned with the
/// line/column information of the user's input type so that error messages are
/// placed appropriately by the compiler.
+#[cfg(doc)]
+#[macro_export]
+macro_rules! quote_spanned {
+ ($span:expr=> $($tt:tt)*) => {
+ ...
+ };
+}
+
+#[cfg(not(doc))]
#[macro_export]
macro_rules! quote_spanned {
($span:expr=>) => {{
let _: $crate::__private::Span = $span;
$crate::__private::TokenStream::new()
}};
+
+ // Special case rule for a single tt, for performance.
+ ($span:expr=> $tt:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _span: $crate::__private::Span = $span;
+ $crate::quote_token_spanned!{$tt _s _span}
+ _s
+ }};
+
+ // Special case rules for two tts, for performance.
+ ($span:expr=> # $var:ident) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _: $crate::__private::Span = $span;
+ $crate::ToTokens::to_tokens(&$var, &mut _s);
+ _s
+ }};
+ ($span:expr=> $tt1:tt $tt2:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _span: $crate::__private::Span = $span;
+ $crate::quote_token_spanned!{$tt1 _s _span}
+ $crate::quote_token_spanned!{$tt2 _s _span}
+ _s
+ }};
+
+ // Rule for any other number of tokens.
($span:expr=> $($tt:tt)*) => {{
let mut _s = $crate::__private::TokenStream::new();
let _span: $crate::__private::Span = $span;
- $crate::quote_each_token_spanned!(_s _span $($tt)*);
+ $crate::quote_each_token_spanned!{_s _span $($tt)*}
_s
}};
}
@@ -608,10 +665,10 @@ macro_rules! quote_spanned {
#[doc(hidden)]
macro_rules! pounded_var_names {
($call:ident! $extra:tt $($tts:tt)*) => {
- $crate::pounded_var_names_with_context!($call! $extra
+ $crate::pounded_var_names_with_context!{$call! $extra
(@ $($tts)*)
($($tts)* @)
- )
+ }
};
}
@@ -620,7 +677,7 @@ macro_rules! pounded_var_names {
macro_rules! pounded_var_names_with_context {
($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
$(
- $crate::pounded_var_with_context!($call! $extra $b1 $curr);
+ $crate::pounded_var_with_context!{$call! $extra $b1 $curr}
)*
};
}
@@ -629,15 +686,15 @@ macro_rules! pounded_var_names_with_context {
#[doc(hidden)]
macro_rules! pounded_var_with_context {
($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
};
($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
};
($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
};
($call:ident!($($extra:tt)*) # $var:ident) => {
@@ -669,11 +726,79 @@ macro_rules! quote_bind_next_or_break {
};
}
+// The obvious way to write this macro is as a tt muncher. This implementation
+// does something more complex for two reasons.
+//
+// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which
+// this implementation avoids because it isn't tail recursive.
+//
+// - Compile times for a tt muncher are quadratic relative to the length of
+// the input. This implementation is linear, so it will be faster
+// (potentially much faster) for big inputs. However, the constant factors
+// of this implementation are higher than that of a tt muncher, so it is
+// somewhat slower than a tt muncher if there are many invocations with
+// short inputs.
+//
+// An invocation like this:
+//
+// quote_each_token!(_s a b c d e f g h i j);
+//
+// expands to this:
+//
+// quote_tokens_with_context!(_s
+// (@ @ @ @ @ @ a b c d e f g h i j)
+// (@ @ @ @ @ a b c d e f g h i j @)
+// (@ @ @ @ a b c d e f g h i j @ @)
+// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @)
+// (@ @ a b c d e f g h i j @ @ @ @)
+// (@ a b c d e f g h i j @ @ @ @ @)
+// (a b c d e f g h i j @ @ @ @ @ @)
+// );
+//
+// which gets transposed and expanded to this:
+//
+// quote_token_with_context!(_s @ @ @ @ @ @ a);
+// quote_token_with_context!(_s @ @ @ @ @ a b);
+// quote_token_with_context!(_s @ @ @ @ a b c);
+// quote_token_with_context!(_s @ @ @ (a) b c d);
+// quote_token_with_context!(_s @ @ a (b) c d e);
+// quote_token_with_context!(_s @ a b (c) d e f);
+// quote_token_with_context!(_s a b c (d) e f g);
+// quote_token_with_context!(_s b c d (e) f g h);
+// quote_token_with_context!(_s c d e (f) g h i);
+// quote_token_with_context!(_s d e f (g) h i j);
+// quote_token_with_context!(_s e f g (h) i j @);
+// quote_token_with_context!(_s f g h (i) j @ @);
+// quote_token_with_context!(_s g h i (j) @ @ @);
+// quote_token_with_context!(_s h i j @ @ @ @);
+// quote_token_with_context!(_s i j @ @ @ @ @);
+// quote_token_with_context!(_s j @ @ @ @ @ @);
+//
+// Without having used muncher-style recursion, we get one invocation of
+// quote_token_with_context for each original tt, with three tts of context on
+// either side. This is enough for the longest possible interpolation form (a
+// repetition with separator, as in `# (#var) , *`) to be fully represented with
+// the first or last tt in the middle.
+//
+// The middle tt (surrounded by parentheses) is the tt being processed.
+//
+// - When it is a `#`, quote_token_with_context can do an interpolation. The
+// interpolation kind will depend on the three subsequent tts.
+//
+// - When it is within a later part of an interpolation, it can be ignored
+// because the interpolation has already been done.
+//
+// - When it is not part of an interpolation it can be pushed as a single
+// token into the output.
+//
+// - When the middle token is an unparenthesized `@`, that call is one of the
+// first 3 or last 3 calls of quote_token_with_context and does not
+// correspond to one of the original input tokens, so turns into nothing.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_each_token {
($tokens:ident $($tts:tt)*) => {
- $crate::quote_tokens_with_context!($tokens
+ $crate::quote_tokens_with_context!{$tokens
(@ @ @ @ @ @ $($tts)*)
(@ @ @ @ @ $($tts)* @)
(@ @ @ @ $($tts)* @ @)
@@ -681,15 +806,16 @@ macro_rules! quote_each_token {
(@ @ $($tts)* @ @ @ @)
(@ $($tts)* @ @ @ @ @)
($($tts)* @ @ @ @ @ @)
- );
+ }
};
}
+// See the explanation on quote_each_token.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_each_token_spanned {
($tokens:ident $span:ident $($tts:tt)*) => {
- $crate::quote_tokens_with_context_spanned!($tokens $span
+ $crate::quote_tokens_with_context_spanned!{$tokens $span
(@ @ @ @ @ @ $($tts)*)
(@ @ @ @ @ $($tts)* @)
(@ @ @ @ $($tts)* @ @)
@@ -697,10 +823,11 @@ macro_rules! quote_each_token_spanned {
(@ @ $($tts)* @ @ @ @)
(@ $($tts)* @ @ @ @ @)
($($tts)* @ @ @ @ @ @)
- );
+ }
};
}
+// See the explanation on quote_each_token.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_tokens_with_context {
@@ -710,11 +837,12 @@ macro_rules! quote_tokens_with_context {
($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
) => {
$(
- $crate::quote_token_with_context!($tokens $b3 $b2 $b1 $curr $a1 $a2 $a3);
+ $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3}
)*
};
}
+// See the explanation on quote_each_token.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_tokens_with_context_spanned {
@@ -724,20 +852,24 @@ macro_rules! quote_tokens_with_context_spanned {
($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
) => {
$(
- $crate::quote_token_with_context_spanned!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3);
+ $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3}
)*
};
}
+// See the explanation on quote_each_token.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_token_with_context {
+ // Unparenthesized `@` indicates this call does not correspond to one of the
+ // original input tokens. Ignore it.
($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
+ // A repetition with no separator.
($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
use $crate::__private::ext::*;
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
let _: $crate::__private::HasIterator = has_iter;
// This is `while true` instead of `loop` because if there are no
// iterators used inside of this repetition then the body would not
@@ -745,55 +877,60 @@ macro_rules! quote_token_with_context {
// 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.
- //
- // 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;
- }
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ $crate::quote_each_token!{$tokens $($inner)*}
}
}};
+ // ... and one step later.
($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
+ // ... and one step later.
($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
+ // A repetition with separator.
($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
use $crate::__private::ext::*;
let mut _i = 0usize;
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
let _: $crate::__private::HasIterator = has_iter;
- loop {
- $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
if _i > 0 {
- $crate::quote_token!($tokens $sep);
+ $crate::quote_token!{$sep $tokens}
}
_i += 1;
- $crate::quote_each_token!($tokens $($inner)*);
- if false {
- break;
- }
+ $crate::quote_each_token!{$tokens $($inner)*}
}
}};
+ // ... and one step later.
($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
+ // ... and one step later.
($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
+ // (A special case for `#(var)**`, where the first `*` is treated as the
+ // repetition symbol and the second `*` is treated as an ordinary token.)
($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
// https://github.com/dtolnay/quote/issues/130
- $crate::quote_token!($tokens *);
+ $crate::quote_token!{* $tokens}
};
+ // ... and one step later.
($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
+ // A non-repetition interpolation.
($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
$crate::ToTokens::to_tokens(&$var, &mut $tokens);
};
+ // ... and one step later.
($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
+
+ // An ordinary token, not part of any interpolation.
($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
- $crate::quote_token!($tokens $curr);
+ $crate::quote_token!{$curr $tokens}
};
}
+// See the explanation on quote_each_token, and on the individual rules of
+// quote_token_with_context.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_token_with_context_spanned {
@@ -802,23 +939,11 @@ macro_rules! quote_token_with_context_spanned {
($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
use $crate::__private::ext::*;
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
let _: $crate::__private::HasIterator = has_iter;
- // This is `while true` instead of `loop` because if there are no
- // iterators used inside of this repetition then the body would not
- // contain any `break`, so the compiler would emit unreachable code
- // 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.
- //
- // 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;
- }
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
}
}};
($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
@@ -828,25 +953,22 @@ macro_rules! quote_token_with_context_spanned {
use $crate::__private::ext::*;
let mut _i = 0usize;
let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
let _: $crate::__private::HasIterator = has_iter;
- loop {
- $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
if _i > 0 {
- $crate::quote_token_spanned!($tokens $span $sep);
+ $crate::quote_token_spanned!{$sep $tokens $span}
}
_i += 1;
- $crate::quote_each_token_spanned!($tokens $span $($inner)*);
- if false {
- break;
- }
+ $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
}
}};
($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
// https://github.com/dtolnay/quote/issues/130
- $crate::quote_token_spanned!($tokens $span *);
+ $crate::quote_token_spanned!{* $tokens $span}
};
($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
@@ -854,15 +976,31 @@ macro_rules! quote_token_with_context_spanned {
$crate::ToTokens::to_tokens(&$var, &mut $tokens);
};
($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
+
($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
- $crate::quote_token_spanned!($tokens $span $curr);
+ $crate::quote_token_spanned!{$curr $tokens $span}
};
}
+// These rules are ordered by approximate token frequency, at least for the
+// first 10 or so, to improve compile times. Having `ident` first is by far the
+// most important because it's typically 2-3x more common than the next most
+// common token.
+//
+// Separately, we put the token being matched in the very front so that failing
+// rules may fail to match as quickly as possible.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_token {
- ($tokens:ident ( $($inner:tt)* )) => {
+ ($ident:ident $tokens:ident) => {
+ $crate::__private::push_ident(&mut $tokens, stringify!($ident));
+ };
+
+ (:: $tokens:ident) => {
+ $crate::__private::push_colon2(&mut $tokens);
+ };
+
+ (( $($inner:tt)* ) $tokens:ident) => {
$crate::__private::push_group(
&mut $tokens,
$crate::__private::Delimiter::Parenthesis,
@@ -870,7 +1008,7 @@ macro_rules! quote_token {
);
};
- ($tokens:ident [ $($inner:tt)* ]) => {
+ ([ $($inner:tt)* ] $tokens:ident) => {
$crate::__private::push_group(
&mut $tokens,
$crate::__private::Delimiter::Bracket,
@@ -878,7 +1016,7 @@ macro_rules! quote_token {
);
};
- ($tokens:ident { $($inner:tt)* }) => {
+ ({ $($inner:tt)* } $tokens:ident) => {
$crate::__private::push_group(
&mut $tokens,
$crate::__private::Delimiter::Brace,
@@ -886,203 +1024,204 @@ macro_rules! quote_token {
);
};
- ($tokens:ident +) => {
+ (# $tokens:ident) => {
+ $crate::__private::push_pound(&mut $tokens);
+ };
+
+ (, $tokens:ident) => {
+ $crate::__private::push_comma(&mut $tokens);
+ };
+
+ (. $tokens:ident) => {
+ $crate::__private::push_dot(&mut $tokens);
+ };
+
+ (; $tokens:ident) => {
+ $crate::__private::push_semi(&mut $tokens);
+ };
+
+ (: $tokens:ident) => {
+ $crate::__private::push_colon(&mut $tokens);
+ };
+
+ (+ $tokens:ident) => {
$crate::__private::push_add(&mut $tokens);
};
- ($tokens:ident +=) => {
+ (+= $tokens:ident) => {
$crate::__private::push_add_eq(&mut $tokens);
};
- ($tokens:ident &) => {
+ (& $tokens:ident) => {
$crate::__private::push_and(&mut $tokens);
};
- ($tokens:ident &&) => {
+ (&& $tokens:ident) => {
$crate::__private::push_and_and(&mut $tokens);
};
- ($tokens:ident &=) => {
+ (&= $tokens:ident) => {
$crate::__private::push_and_eq(&mut $tokens);
};
- ($tokens:ident @) => {
+ (@ $tokens:ident) => {
$crate::__private::push_at(&mut $tokens);
};
- ($tokens:ident !) => {
+ (! $tokens:ident) => {
$crate::__private::push_bang(&mut $tokens);
};
- ($tokens:ident ^) => {
+ (^ $tokens:ident) => {
$crate::__private::push_caret(&mut $tokens);
};
- ($tokens:ident ^=) => {
+ (^= $tokens:ident) => {
$crate::__private::push_caret_eq(&mut $tokens);
};
- ($tokens:ident :) => {
- $crate::__private::push_colon(&mut $tokens);
- };
-
- ($tokens:ident ::) => {
- $crate::__private::push_colon2(&mut $tokens);
- };
-
- ($tokens:ident ,) => {
- $crate::__private::push_comma(&mut $tokens);
- };
-
- ($tokens:ident /) => {
+ (/ $tokens:ident) => {
$crate::__private::push_div(&mut $tokens);
};
- ($tokens:ident /=) => {
+ (/= $tokens:ident) => {
$crate::__private::push_div_eq(&mut $tokens);
};
- ($tokens:ident .) => {
- $crate::__private::push_dot(&mut $tokens);
- };
-
- ($tokens:ident ..) => {
+ (.. $tokens:ident) => {
$crate::__private::push_dot2(&mut $tokens);
};
- ($tokens:ident ...) => {
+ (... $tokens:ident) => {
$crate::__private::push_dot3(&mut $tokens);
};
- ($tokens:ident ..=) => {
+ (..= $tokens:ident) => {
$crate::__private::push_dot_dot_eq(&mut $tokens);
};
- ($tokens:ident =) => {
+ (= $tokens:ident) => {
$crate::__private::push_eq(&mut $tokens);
};
- ($tokens:ident ==) => {
+ (== $tokens:ident) => {
$crate::__private::push_eq_eq(&mut $tokens);
};
- ($tokens:ident >=) => {
+ (>= $tokens:ident) => {
$crate::__private::push_ge(&mut $tokens);
};
- ($tokens:ident >) => {
+ (> $tokens:ident) => {
$crate::__private::push_gt(&mut $tokens);
};
- ($tokens:ident <=) => {
+ (<= $tokens:ident) => {
$crate::__private::push_le(&mut $tokens);
};
- ($tokens:ident <) => {
+ (< $tokens:ident) => {
$crate::__private::push_lt(&mut $tokens);
};
- ($tokens:ident *=) => {
+ (*= $tokens:ident) => {
$crate::__private::push_mul_eq(&mut $tokens);
};
- ($tokens:ident !=) => {
+ (!= $tokens:ident) => {
$crate::__private::push_ne(&mut $tokens);
};
- ($tokens:ident |) => {
+ (| $tokens:ident) => {
$crate::__private::push_or(&mut $tokens);
};
- ($tokens:ident |=) => {
+ (|= $tokens:ident) => {
$crate::__private::push_or_eq(&mut $tokens);
};
- ($tokens:ident ||) => {
+ (|| $tokens:ident) => {
$crate::__private::push_or_or(&mut $tokens);
};
- ($tokens:ident #) => {
- $crate::__private::push_pound(&mut $tokens);
- };
-
- ($tokens:ident ?) => {
+ (? $tokens:ident) => {
$crate::__private::push_question(&mut $tokens);
};
- ($tokens:ident ->) => {
+ (-> $tokens:ident) => {
$crate::__private::push_rarrow(&mut $tokens);
};
- ($tokens:ident <-) => {
+ (<- $tokens:ident) => {
$crate::__private::push_larrow(&mut $tokens);
};
- ($tokens:ident %) => {
+ (% $tokens:ident) => {
$crate::__private::push_rem(&mut $tokens);
};
- ($tokens:ident %=) => {
+ (%= $tokens:ident) => {
$crate::__private::push_rem_eq(&mut $tokens);
};
- ($tokens:ident =>) => {
+ (=> $tokens:ident) => {
$crate::__private::push_fat_arrow(&mut $tokens);
};
- ($tokens:ident ;) => {
- $crate::__private::push_semi(&mut $tokens);
- };
-
- ($tokens:ident <<) => {
+ (<< $tokens:ident) => {
$crate::__private::push_shl(&mut $tokens);
};
- ($tokens:ident <<=) => {
+ (<<= $tokens:ident) => {
$crate::__private::push_shl_eq(&mut $tokens);
};
- ($tokens:ident >>) => {
+ (>> $tokens:ident) => {
$crate::__private::push_shr(&mut $tokens);
};
- ($tokens:ident >>=) => {
+ (>>= $tokens:ident) => {
$crate::__private::push_shr_eq(&mut $tokens);
};
- ($tokens:ident *) => {
+ (* $tokens:ident) => {
$crate::__private::push_star(&mut $tokens);
};
- ($tokens:ident -) => {
+ (- $tokens:ident) => {
$crate::__private::push_sub(&mut $tokens);
};
- ($tokens:ident -=) => {
+ (-= $tokens:ident) => {
$crate::__private::push_sub_eq(&mut $tokens);
};
- ($tokens:ident $ident:ident) => {
- $crate::__private::push_ident(&mut $tokens, stringify!($ident));
- };
-
- ($tokens:ident $lifetime:lifetime) => {
+ ($lifetime:lifetime $tokens:ident) => {
$crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
};
- ($tokens:ident _) => {
+ (_ $tokens:ident) => {
$crate::__private::push_underscore(&mut $tokens);
};
- ($tokens:ident $other:tt) => {
+ ($other:tt $tokens:ident) => {
$crate::__private::parse(&mut $tokens, stringify!($other));
};
}
+// See the comment above `quote_token!` about the rule ordering.
#[macro_export]
#[doc(hidden)]
macro_rules! quote_token_spanned {
- ($tokens:ident $span:ident ( $($inner:tt)* )) => {
+ ($ident:ident $tokens:ident $span:ident) => {
+ $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
+ };
+
+ (:: $tokens:ident $span:ident) => {
+ $crate::__private::push_colon2_spanned(&mut $tokens, $span);
+ };
+
+ (( $($inner:tt)* ) $tokens:ident $span:ident) => {
$crate::__private::push_group_spanned(
&mut $tokens,
$span,
@@ -1091,7 +1230,7 @@ macro_rules! quote_token_spanned {
);
};
- ($tokens:ident $span:ident [ $($inner:tt)* ]) => {
+ ([ $($inner:tt)* ] $tokens:ident $span:ident) => {
$crate::__private::push_group_spanned(
&mut $tokens,
$span,
@@ -1100,7 +1239,7 @@ macro_rules! quote_token_spanned {
);
};
- ($tokens:ident $span:ident { $($inner:tt)* }) => {
+ ({ $($inner:tt)* } $tokens:ident $span:ident) => {
$crate::__private::push_group_spanned(
&mut $tokens,
$span,
@@ -1109,195 +1248,187 @@ macro_rules! quote_token_spanned {
);
};
- ($tokens:ident $span:ident +) => {
+ (# $tokens:ident $span:ident) => {
+ $crate::__private::push_pound_spanned(&mut $tokens, $span);
+ };
+
+ (, $tokens:ident $span:ident) => {
+ $crate::__private::push_comma_spanned(&mut $tokens, $span);
+ };
+
+ (. $tokens:ident $span:ident) => {
+ $crate::__private::push_dot_spanned(&mut $tokens, $span);
+ };
+
+ (; $tokens:ident $span:ident) => {
+ $crate::__private::push_semi_spanned(&mut $tokens, $span);
+ };
+
+ (: $tokens:ident $span:ident) => {
+ $crate::__private::push_colon_spanned(&mut $tokens, $span);
+ };
+
+ (+ $tokens:ident $span:ident) => {
$crate::__private::push_add_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident +=) => {
+ (+= $tokens:ident $span:ident) => {
$crate::__private::push_add_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident &) => {
+ (& $tokens:ident $span:ident) => {
$crate::__private::push_and_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident &&) => {
+ (&& $tokens:ident $span:ident) => {
$crate::__private::push_and_and_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident &=) => {
+ (&= $tokens:ident $span:ident) => {
$crate::__private::push_and_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident @) => {
+ (@ $tokens:ident $span:ident) => {
$crate::__private::push_at_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident !) => {
+ (! $tokens:ident $span:ident) => {
$crate::__private::push_bang_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ^) => {
+ (^ $tokens:ident $span:ident) => {
$crate::__private::push_caret_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ^=) => {
+ (^= $tokens:ident $span:ident) => {
$crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident :) => {
- $crate::__private::push_colon_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ::) => {
- $crate::__private::push_colon2_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ,) => {
- $crate::__private::push_comma_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident /) => {
+ (/ $tokens:ident $span:ident) => {
$crate::__private::push_div_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident /=) => {
+ (/= $tokens:ident $span:ident) => {
$crate::__private::push_div_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident .) => {
- $crate::__private::push_dot_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ..) => {
+ (.. $tokens:ident $span:ident) => {
$crate::__private::push_dot2_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ...) => {
+ (... $tokens:ident $span:ident) => {
$crate::__private::push_dot3_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ..=) => {
+ (..= $tokens:ident $span:ident) => {
$crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident =) => {
+ (= $tokens:ident $span:ident) => {
$crate::__private::push_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ==) => {
+ (== $tokens:ident $span:ident) => {
$crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident >=) => {
+ (>= $tokens:ident $span:ident) => {
$crate::__private::push_ge_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident >) => {
+ (> $tokens:ident $span:ident) => {
$crate::__private::push_gt_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident <=) => {
+ (<= $tokens:ident $span:ident) => {
$crate::__private::push_le_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident <) => {
+ (< $tokens:ident $span:ident) => {
$crate::__private::push_lt_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident *=) => {
+ (*= $tokens:ident $span:ident) => {
$crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident !=) => {
+ (!= $tokens:ident $span:ident) => {
$crate::__private::push_ne_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident |) => {
+ (| $tokens:ident $span:ident) => {
$crate::__private::push_or_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident |=) => {
+ (|= $tokens:ident $span:ident) => {
$crate::__private::push_or_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ||) => {
+ (|| $tokens:ident $span:ident) => {
$crate::__private::push_or_or_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident #) => {
- $crate::__private::push_pound_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ?) => {
+ (? $tokens:ident $span:ident) => {
$crate::__private::push_question_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ->) => {
+ (-> $tokens:ident $span:ident) => {
$crate::__private::push_rarrow_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident <-) => {
+ (<- $tokens:ident $span:ident) => {
$crate::__private::push_larrow_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident %) => {
+ (% $tokens:ident $span:ident) => {
$crate::__private::push_rem_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident %=) => {
+ (%= $tokens:ident $span:ident) => {
$crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident =>) => {
+ (=> $tokens:ident $span:ident) => {
$crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident ;) => {
- $crate::__private::push_semi_spanned(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <<) => {
+ (<< $tokens:ident $span:ident) => {
$crate::__private::push_shl_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident <<=) => {
+ (<<= $tokens:ident $span:ident) => {
$crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident >>) => {
+ (>> $tokens:ident $span:ident) => {
$crate::__private::push_shr_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident >>=) => {
+ (>>= $tokens:ident $span:ident) => {
$crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident *) => {
+ (* $tokens:ident $span:ident) => {
$crate::__private::push_star_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident -) => {
+ (- $tokens:ident $span:ident) => {
$crate::__private::push_sub_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident -=) => {
+ (-= $tokens:ident $span:ident) => {
$crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident $ident:ident) => {
- $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
- };
-
- ($tokens:ident $span:ident $lifetime:lifetime) => {
+ ($lifetime:lifetime $tokens:ident $span:ident) => {
$crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
};
- ($tokens:ident $span:ident _) => {
+ (_ $tokens:ident $span:ident) => {
$crate::__private::push_underscore_spanned(&mut $tokens, $span);
};
- ($tokens:ident $span:ident $other:tt) => {
+ ($other:tt $tokens:ident $span:ident) => {
$crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
};
}
diff --git a/src/runtime.rs b/src/runtime.rs
index 52955cb..f3cdded 100644
--- a/src/runtime.rs
+++ b/src/runtime.rs
@@ -1,9 +1,11 @@
use crate::{IdentFragment, ToTokens, TokenStreamExt};
-use std::fmt;
-use std::iter;
-use std::ops::BitOr;
+use core::fmt;
+use core::iter;
+use core::ops::BitOr;
+pub use core::option::Option;
pub use proc_macro2::*;
+pub use std::format;
pub struct HasIterator; // True
pub struct ThereIsNoIteratorInRepetition; // False
@@ -46,8 +48,8 @@ pub mod ext {
use super::RepInterp;
use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
use crate::ToTokens;
+ use core::slice;
use std::collections::btree_set::{self, BTreeSet};
- use std::slice;
/// Extension trait providing the `quote_into_iter` method on iterators.
pub trait RepIteratorExt: Iterator + Sized {
@@ -205,27 +207,12 @@ fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
}
pub fn push_ident(tokens: &mut TokenStream, s: &str) {
- // Optimization over `mk_ident`, as `s` is guaranteed to be a valid ident.
- //
- // FIXME: When `Ident::new_raw` becomes stable, this method should be
- // updated to call it when available.
- if s.starts_with("r#") {
- parse(tokens, s);
- } else {
- tokens.append(Ident::new(s, Span::call_site()));
- }
+ let span = Span::call_site();
+ push_ident_spanned(tokens, span, s);
}
pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) {
- // Optimization over `mk_ident`, as `s` is guaranteed to be a valid ident.
- //
- // FIXME: When `Ident::new_raw` becomes stable, this method should be
- // updated to call it when available.
- if s.starts_with("r#") {
- parse_spanned(tokens, span, s);
- } else {
- tokens.append(Ident::new(s, span));
- }
+ tokens.append(ident_maybe_raw(s, span));
}
pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) {
@@ -392,36 +379,17 @@ pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) {
// Helper method for constructing identifiers from the `format_ident!` macro,
// handling `r#` prefixes.
-//
-// Directly parsing the input string may produce a valid identifier,
-// although the input string was invalid, due to ignored characters such as
-// whitespace and comments. Instead, we always create a non-raw identifier
-// to validate that the string is OK, and only parse again if needed.
pub fn mk_ident(id: &str, span: Option<Span>) -> Ident {
let span = span.unwrap_or_else(Span::call_site);
+ ident_maybe_raw(id, span)
+}
- let is_raw = id.starts_with("r#");
- let unraw = Ident::new(if is_raw { &id[2..] } else { id }, span);
- if !is_raw {
- return unraw;
- }
-
- // At this point, the identifier is raw, and the unraw-ed version of it was
- // successfully converted into an identifier. Try to produce a valid raw
- // identifier by running the `TokenStream` parser, and unwrapping the first
- // token as an `Ident`.
- //
- // FIXME: When `Ident::new_raw` becomes stable, this method should be
- // updated to call it when available.
- if let Ok(ts) = id.parse::<TokenStream>() {
- let mut iter = ts.into_iter();
- if let (Some(TokenTree::Ident(mut id)), None) = (iter.next(), iter.next()) {
- id.set_span(span);
- return id;
- }
+fn ident_maybe_raw(id: &str, span: Span) -> Ident {
+ if id.starts_with("r#") {
+ Ident::new_raw(&id[2..], span)
+ } else {
+ Ident::new(id, span)
}
-
- panic!("not allowed as a raw identifier: `{}`", id);
}
// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!`
diff --git a/src/spanned.rs b/src/spanned.rs
index 55168bd..f64c8f5 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -18,10 +18,11 @@ impl<T: ?Sized + ToTokens> Spanned for T {
}
fn join_spans(tokens: TokenStream) -> Span {
+ #[cfg(not(needs_invalid_span_workaround))]
+ let mut iter = tokens.into_iter().map(|tt| tt.span());
+
+ #[cfg(needs_invalid_span_workaround)]
let mut iter = tokens.into_iter().filter_map(|tt| {
- // FIXME: This shouldn't be required, since optimally spans should
- // never be invalid. This filter_map can probably be removed when
- // https://github.com/rust-lang/rust/issues/43081 is resolved.
let span = tt.span();
let debug = format!("{:?}", span);
if debug.ends_with("bytes(0..0)") {
diff --git a/src/to_tokens.rs b/src/to_tokens.rs
index dbb8dfc..5748721 100644
--- a/src/to_tokens.rs
+++ b/src/to_tokens.rs
@@ -1,11 +1,9 @@
use super::TokenStreamExt;
-
+use core::iter;
+use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
use std::borrow::Cow;
-use std::iter;
use std::rc::Rc;
-use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
-
/// Types that can be interpolated inside a `quote!` invocation.
///
/// [`quote!`]: macro.quote.html
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index f9aea23..7974a62 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,4 +1,5 @@
#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
let t = trybuild::TestCases::new();
diff --git a/tests/test.rs b/tests/test.rs
index 11f8a31..52ec7bc 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,6 +1,5 @@
#![allow(
- clippy::blacklisted_name,
- clippy::let_underscore_drop,
+ clippy::disallowed_names,
clippy::shadow_unrelated,
clippy::unseparated_literal_suffix,
clippy::used_underscore_binding
@@ -180,7 +179,8 @@ fn test_integer() {
#ii8 #ii16 #ii32 #ii64 #ii128 #iisize
#uu8 #uu16 #uu32 #uu64 #uu128 #uusize
};
- let expected = "1 1i32 1u256 - 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());
}
@@ -200,7 +200,7 @@ fn test_floating() {
#[test]
fn test_char() {
- let zero = '\0';
+ let zero = '\u{1}';
let pound = '#';
let quote = '"';
let apost = '\'';
@@ -210,23 +210,23 @@ fn test_char() {
let tokens = quote! {
#zero #pound #quote #apost #newline #heart
};
- let expected = "'\\u{0}' '#' '\"' '\\'' '\\n' '\u{2764}'";
+ let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'";
assert_eq!(expected, tokens.to_string());
}
#[test]
fn test_str() {
- let s = "\0 a 'b \" c";
+ let s = "\u{1} a 'b \" c";
let tokens = quote!(#s);
- let expected = "\"\\u{0} a 'b \\\" c\"";
+ let expected = "\"\\u{1} a 'b \\\" c\"";
assert_eq!(expected, tokens.to_string());
}
#[test]
fn test_string() {
- let s = "\0 a 'b \" c".to_string();
+ let s = "\u{1} a 'b \" c".to_string();
let tokens = quote!(#s);
- let expected = "\"\\u{0} a 'b \\\" c\"";
+ let expected = "\"\\u{1} a 'b \\\" c\"";
assert_eq!(expected, tokens.to_string());
}
diff --git a/tests/ui/does-not-have-iter-interpolated-dup.stderr b/tests/ui/does-not-have-iter-interpolated-dup.stderr
index bcd631d..8087879 100644
--- a/tests/ui/does-not-have-iter-interpolated-dup.stderr
+++ b/tests/ui/does-not-have-iter-interpolated-dup.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| 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)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (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
index 799837b..2dcf206 100644
--- a/tests/ui/does-not-have-iter-interpolated.stderr
+++ b/tests/ui/does-not-have-iter-interpolated.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| 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)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (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
index aa2e693..87a19fe 100644
--- a/tests/ui/does-not-have-iter-separated.stderr
+++ b/tests/ui/does-not-have-iter-separated.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| 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)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (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
index c2692fe..32aa62d 100644
--- a/tests/ui/does-not-have-iter.stderr
+++ b/tests/ui/does-not-have-iter.stderr
@@ -7,4 +7,4 @@ error[E0308]: mismatched types
| 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)
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/not-quotable.rs b/tests/ui/not-quotable.rs
index f991c18..220542d 100644
--- a/tests/ui/not-quotable.rs
+++ b/tests/ui/not-quotable.rs
@@ -3,5 +3,5 @@ use std::net::Ipv4Addr;
fn main() {
let ip = Ipv4Addr::LOCALHOST;
- let _ = quote! { #ip };
+ _ = quote! { #ip };
}
diff --git a/tests/ui/not-quotable.stderr b/tests/ui/not-quotable.stderr
index 5dd13bf..c323d99 100644
--- a/tests/ui/not-quotable.stderr
+++ b/tests/ui/not-quotable.stderr
@@ -1,7 +1,20 @@
error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
- --> tests/ui/not-quotable.rs:6:13
+ --> tests/ui/not-quotable.rs:6:9
|
-6 | let _ = quote! { #ip };
- | ^^^^^^^^^^^^^^ the trait `ToTokens` is not implemented for `Ipv4Addr`
+6 | _ = quote! { #ip };
+ | ^^^^^^^^^^^^^^
+ | |
+ | the trait `ToTokens` is not implemented for `Ipv4Addr`
+ | required by a bound introduced by this call
|
- = note: this error originates in the macro `$crate::quote_token_with_context` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = help: the following other types implement trait `ToTokens`:
+ &'a T
+ &'a mut T
+ Box<T>
+ Cow<'a, T>
+ Option<T>
+ Rc<T>
+ RepInterp<T>
+ String
+ and 23 others
+ = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/not-repeatable.rs b/tests/ui/not-repeatable.rs
index a8f0fe7..c1debf5 100644
--- a/tests/ui/not-repeatable.rs
+++ b/tests/ui/not-repeatable.rs
@@ -4,5 +4,5 @@ struct Ipv4Addr;
fn main() {
let ip = Ipv4Addr;
- let _ = quote! { #(#ip)* };
+ _ = quote! { #(#ip)* };
}
diff --git a/tests/ui/not-repeatable.stderr b/tests/ui/not-repeatable.stderr
index cd5a1e4..264a89f 100644
--- a/tests/ui/not-repeatable.stderr
+++ b/tests/ui/not-repeatable.stderr
@@ -1,47 +1,35 @@
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`
+ --> tests/ui/not-repeatable.rs:7:9
+ |
+3 | struct Ipv4Addr;
+ | ---------------
+ | |
+ | method `quote_into_iter` not found for this struct
+ | doesn't satisfy `Ipv4Addr: Iterator`
+ | doesn't satisfy `Ipv4Addr: ToTokens`
+ | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt`
+ | doesn't satisfy `Ipv4Addr: 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)
+7 | _ = 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: ext::RepIteratorExt`
+ `&Ipv4Addr: Iterator`
+ which is required by `&Ipv4Addr: ext::RepIteratorExt`
+ `Ipv4Addr: ToTokens`
+ which is required by `Ipv4Addr: ext::RepToTokensExt`
+ `&mut Ipv4Addr: Iterator`
+ which is required by `&mut Ipv4Addr: ext::RepIteratorExt`
+note: the traits `ToTokens` and `Iterator` must be implemented
+ --> src/to_tokens.rs
+ |
+ | pub trait ToTokens {
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ ::: $RUST/core/src/iter/traits/iterator.rs
+ |
+ | pub trait Iterator {
+ | ^^^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)