aboutsummaryrefslogtreecommitdiff
path: root/quote
diff options
context:
space:
mode:
Diffstat (limited to 'quote')
-rw-r--r--quote/.gitignore2
-rw-r--r--quote/.travis.yml18
-rw-r--r--quote/Cargo.toml32
-rw-r--r--quote/LICENSE-APACHE201
-rw-r--r--quote/LICENSE-MIT25
-rw-r--r--quote/README.md237
-rw-r--r--quote/benches/bench.rs193
-rw-r--r--quote/src/ext.rs112
-rw-r--r--quote/src/format.rs164
-rw-r--r--quote/src/ident_fragment.rs72
-rw-r--r--quote/src/lib.rs948
-rw-r--r--quote/src/runtime.rs373
-rw-r--r--quote/src/spanned.rs42
-rw-r--r--quote/src/to_tokens.rs209
-rw-r--r--quote/tests/compiletest.rs6
-rw-r--r--quote/tests/test.rs429
-rw-r--r--quote/tests/ui/does-not-have-iter-interpolated-dup.rs9
-rw-r--r--quote/tests/ui/does-not-have-iter-interpolated-dup.stderr11
-rw-r--r--quote/tests/ui/does-not-have-iter-interpolated.rs9
-rw-r--r--quote/tests/ui/does-not-have-iter-interpolated.stderr11
-rw-r--r--quote/tests/ui/does-not-have-iter-separated.rs5
-rw-r--r--quote/tests/ui/does-not-have-iter-separated.stderr11
-rw-r--r--quote/tests/ui/does-not-have-iter.rs5
-rw-r--r--quote/tests/ui/does-not-have-iter.stderr11
-rw-r--r--quote/tests/ui/not-quotable.rs7
-rw-r--r--quote/tests/ui/not-quotable.stderr10
-rw-r--r--quote/tests/ui/not-repeatable.rs7
-rw-r--r--quote/tests/ui/not-repeatable.stderr14
-rw-r--r--quote/tests/ui/wrong-type-span.rs7
-rw-r--r--quote/tests/ui/wrong-type-span.stderr10
30 files changed, 0 insertions, 3190 deletions
diff --git a/quote/.gitignore b/quote/.gitignore
deleted file mode 100644
index 4fffb2f..0000000
--- a/quote/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/target
-/Cargo.lock
diff --git a/quote/.travis.yml b/quote/.travis.yml
deleted file mode 100644
index 7182d9b..0000000
--- a/quote/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-sudo: false
-
-language: rust
-
-rust:
- - stable
- - 1.31.0
- - beta
-
-script:
- - cargo test
-
-matrix:
- include:
- - rust: nightly
- script:
- - cargo test
- - cargo update -Z minimal-versions && cargo build
diff --git a/quote/Cargo.toml b/quote/Cargo.toml
deleted file mode 100644
index c052022..0000000
--- a/quote/Cargo.toml
+++ /dev/null
@@ -1,32 +0,0 @@
-[package]
-name = "quote"
-version = "1.0.2" # 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!(...)"
-repository = "https://github.com/dtolnay/quote"
-documentation = "https://docs.rs/quote/"
-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"
-
-[lib]
-name = "quote"
-
-[dependencies]
-proc-macro2 = { version = "1.0", default-features = false }
-
-[dev-dependencies]
-rustversion = "0.1"
-trybuild = "1.0"
-
-[features]
-default = ["proc-macro"]
-# Disabling the proc-macro feature removes the dynamic library dependency on
-# libproc_macro in the rustc compiler.
-proc-macro = ["proc-macro2/proc-macro"]
-
-[badges]
-travis-ci = { repository = "dtolnay/quote" }
diff --git a/quote/LICENSE-APACHE b/quote/LICENSE-APACHE
deleted file mode 100644
index 16fe87b..0000000
--- a/quote/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/quote/LICENSE-MIT b/quote/LICENSE-MIT
deleted file mode 100644
index 40b8817..0000000
--- a/quote/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-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
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/quote/README.md b/quote/README.md
deleted file mode 100644
index 7c7f743..0000000
--- a/quote/README.md
+++ /dev/null
@@ -1,237 +0,0 @@
-Rust Quasi-Quoting
-==================
-
-[![Build Status](https://api.travis-ci.org/dtolnay/quote.svg?branch=master)](https://travis-ci.org/dtolnay/quote)
-[![Latest Version](https://img.shields.io/crates/v/quote.svg)](https://crates.io/crates/quote)
-[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/quote/)
-
-This crate provides the [`quote!`] macro for turning Rust syntax tree data
-structures into tokens of source code.
-
-[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html
-
-Procedural macros in Rust receive a stream of tokens as input, execute arbitrary
-Rust code to determine how to manipulate those tokens, and produce a stream of
-tokens to hand back to the compiler to compile into the caller's crate.
-Quasi-quoting is a solution to one piece of that &mdash; producing tokens to
-return to the compiler.
-
-The idea of quasi-quoting is that we write *code* that we treat as *data*.
-Within the `quote!` macro, we can write what looks like code to our text editor
-or IDE. We get all the benefits of the editor's brace matching, syntax
-highlighting, indentation, and maybe autocompletion. But rather than compiling
-that as code into the current crate, we can treat it as data, pass it around,
-mutate it, and eventually hand it back to the compiler as tokens to compile into
-the macro caller's crate.
-
-This crate is motivated by the procedural macro use case, but is a
-general-purpose Rust quasi-quoting library and is not specific to procedural
-macros.
-
-*Version requirement: Quote supports any compiler version back to Rust's very
-first support for procedural macros in Rust 1.15.0.*
-
-[*Release notes*](https://github.com/dtolnay/quote/releases)
-
-```toml
-[dependencies]
-quote = "1.0"
-```
-
-## Syntax
-
-The quote crate provides a [`quote!`] macro within which you can write Rust code
-that gets packaged into a [`TokenStream`] and can be treated as data. You should
-think of `TokenStream` as representing a fragment of Rust source code.
-
-[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
-
-Within the `quote!` macro, interpolation is done with `#var`. Any type
-implementing the [`quote::ToTokens`] trait can be interpolated. This includes
-most Rust primitive types as well as most of the syntax tree types from [`syn`].
-
-[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html
-[`syn`]: https://github.com/dtolnay/syn
-
-```rust
-let tokens = quote! {
- struct SerializeWith #generics #where_clause {
- value: &'a #field_ty,
- phantom: core::marker::PhantomData<#item_ty>,
- }
-
- impl #generics serde::Serialize for SerializeWith #generics #where_clause {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- #path(self.value, serializer)
- }
- }
-
- SerializeWith {
- value: #value,
- phantom: core::marker::PhantomData::<#item_ty>,
- }
-};
-```
-
-## Repetition
-
-Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This
-iterates through the elements of any variable interpolated within the repetition
-and inserts a copy of the repetition body for each one. The variables in an
-interpolation may be anything that implements `IntoIterator`, including `Vec` or
-a pre-existing iterator.
-
-- `#(#var)*` — no separators
-- `#(#var),*` — the character before the asterisk is used as a separator
-- `#( struct #var; )*` — the repetition can contain other things
-- `#( #k => println!("{}", #v), )*` — even multiple interpolations
-
-Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter
-does not produce a trailing comma. This matches the behavior of delimiters in
-`macro_rules!`.
-
-## Returning tokens to the compiler
-
-The `quote!` macro evaluates to an expression of type
-`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to
-return the type `proc_macro::TokenStream`.
-
-The difference between the two types is that `proc_macro` types are entirely
-specific to procedural macros and cannot ever exist in code outside of a
-procedural macro, while `proc_macro2` types may exist anywhere including tests
-and non-macro code like main.rs and build.rs. This is why even the procedural
-macro ecosystem is largely built around `proc_macro2`, because that ensures the
-libraries are unit testable and accessible in non-macro contexts.
-
-There is a [`From`]-conversion in both directions so returning the output of
-`quote!` from a procedural macro usually looks like `tokens.into()` or
-`proc_macro::TokenStream::from(tokens)`.
-
-[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
-
-## Examples
-
-### Combining quoted fragments
-
-Usually you don't end up constructing an entire final `TokenStream` in one
-piece. Different parts may come from different helper functions. The tokens
-produced by `quote!` themselves implement `ToTokens` and so can be interpolated
-into later `quote!` invocations to build up a final result.
-
-```rust
-let type_definition = quote! {...};
-let methods = quote! {...};
-
-let tokens = quote! {
- #type_definition
- #methods
-};
-```
-
-### Constructing identifiers
-
-Suppose we have an identifier `ident` which came from somewhere in a macro
-input and we need to modify it in some way for the macro output. Let's consider
-prepending the identifier with an underscore.
-
-Simply interpolating the identifier next to an underscore will not have the
-behavior of concatenating them. The underscore and the identifier will continue
-to be two separate tokens as if you had written `_ x`.
-
-```rust
-// incorrect
-quote! {
- let mut _#ident = 0;
-}
-```
-
-The solution is to build a new identifier token with the correct value. As this
-is such a common case, the `format_ident!` macro provides a convenient utility
-for doing so correctly.
-
-```rust
-let varname = format_ident!("_{}", ident);
-quote! {
- let mut #varname = 0;
-}
-```
-
-Alternatively, the APIs provided by Syn and proc-macro2 can be used to directly
-build the identifier. This is roughly equivalent to the above, but will not
-handle `ident` being a raw identifier.
-
-```rust
-let concatenated = format!("_{}", ident);
-let varname = syn::Ident::new(&concatenated, ident.span());
-quote! {
- let mut #varname = 0;
-}
-```
-
-### Making method calls
-
-Let's say our macro requires some type specified in the macro input to have a
-constructor called `new`. We have the type in a variable called `field_type` of
-type `syn::Type` and want to invoke the constructor.
-
-```rust
-// incorrect
-quote! {
- let value = #field_type::new();
-}
-```
-
-This works only sometimes. If `field_type` is `String`, the expanded code
-contains `String::new()` which is fine. But if `field_type` is something like
-`Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid syntax.
-Ordinarily in handwritten Rust we would write `Vec::<i32>::new()` but for macros
-often the following is more convenient.
-
-```rust
-quote! {
- let value = <#field_type>::new();
-}
-```
-
-This expands to `<Vec<i32>>::new()` which behaves correctly.
-
-A similar pattern is appropriate for trait methods.
-
-```rust
-quote! {
- let value = <#field_type as core::default::Default>::default();
-}
-```
-
-## Hygiene
-
-Any interpolated tokens preserve the `Span` information provided by their
-`ToTokens` implementation. Tokens that originate within a `quote!` invocation
-are spanned with [`Span::call_site()`].
-
-[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
-
-A different span can be provided explicitly through the [`quote_spanned!`]
-macro.
-
-[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html
-
-<br>
-
-#### License
-
-<sup>
-Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
-2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
-</sup>
-
-<br>
-
-<sub>
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
-be dual licensed as above, without any additional terms or conditions.
-</sub>
diff --git a/quote/benches/bench.rs b/quote/benches/bench.rs
deleted file mode 100644
index c76a638..0000000
--- a/quote/benches/bench.rs
+++ /dev/null
@@ -1,193 +0,0 @@
-#![feature(test)]
-#![recursion_limit = "512"]
-
-extern crate test;
-
-use quote::quote;
-use test::Bencher;
-
-#[bench]
-fn bench_impl(b: &mut Bencher) {
- b.iter(|| {
- quote! {
- impl<'de> _serde::Deserialize<'de> for Response {
- fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where
- __D: _serde::Deserializer<'de>,
- {
- #[allow(non_camel_case_types)]
- enum __Field {
- __field0,
- __field1,
- __ignore,
- }
- struct __FieldVisitor;
- impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
- type Value = __Field;
- fn expecting(
- &self,
- __formatter: &mut _serde::export::Formatter,
- ) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(__formatter, "field identifier")
- }
- fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
- where
- __E: _serde::de::Error,
- {
- match __value {
- 0u64 => _serde::export::Ok(__Field::__field0),
- 1u64 => _serde::export::Ok(__Field::__field1),
- _ => _serde::export::Err(_serde::de::Error::invalid_value(
- _serde::de::Unexpected::Unsigned(__value),
- &"field index 0 <= i < 2",
- )),
- }
- }
- fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E>
- where
- __E: _serde::de::Error,
- {
- match __value {
- "id" => _serde::export::Ok(__Field::__field0),
- "s" => _serde::export::Ok(__Field::__field1),
- _ => _serde::export::Ok(__Field::__ignore),
- }
- }
- fn visit_bytes<__E>(
- self,
- __value: &[u8],
- ) -> _serde::export::Result<Self::Value, __E>
- where
- __E: _serde::de::Error,
- {
- match __value {
- b"id" => _serde::export::Ok(__Field::__field0),
- b"s" => _serde::export::Ok(__Field::__field1),
- _ => _serde::export::Ok(__Field::__ignore),
- }
- }
- }
- impl<'de> _serde::Deserialize<'de> for __Field {
- #[inline]
- fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where
- __D: _serde::Deserializer<'de>,
- {
- _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
- }
- }
- struct __Visitor<'de> {
- marker: _serde::export::PhantomData<Response>,
- lifetime: _serde::export::PhantomData<&'de ()>,
- }
- impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
- type Value = Response;
- fn expecting(
- &self,
- __formatter: &mut _serde::export::Formatter,
- ) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(__formatter, "struct Response")
- }
- #[inline]
- fn visit_seq<__A>(
- self,
- mut __seq: __A,
- ) -> _serde::export::Result<Self::Value, __A::Error>
- where
- __A: _serde::de::SeqAccess<'de>,
- {
- let __field0 =
- match try!(_serde::de::SeqAccess::next_element::<u64>(&mut __seq)) {
- _serde::export::Some(__value) => __value,
- _serde::export::None => {
- return _serde::export::Err(_serde::de::Error::invalid_length(
- 0usize,
- &"struct Response with 2 elements",
- ));
- }
- };
- let __field1 =
- match try!(_serde::de::SeqAccess::next_element::<String>(&mut __seq)) {
- _serde::export::Some(__value) => __value,
- _serde::export::None => {
- return _serde::export::Err(_serde::de::Error::invalid_length(
- 1usize,
- &"struct Response with 2 elements",
- ));
- }
- };
- _serde::export::Ok(Response {
- id: __field0,
- s: __field1,
- })
- }
- #[inline]
- fn visit_map<__A>(
- self,
- mut __map: __A,
- ) -> _serde::export::Result<Self::Value, __A::Error>
- where
- __A: _serde::de::MapAccess<'de>,
- {
- let mut __field0: _serde::export::Option<u64> = _serde::export::None;
- let mut __field1: _serde::export::Option<String> = _serde::export::None;
- while let _serde::export::Some(__key) =
- try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map))
- {
- match __key {
- __Field::__field0 => {
- if _serde::export::Option::is_some(&__field0) {
- return _serde::export::Err(
- <__A::Error as _serde::de::Error>::duplicate_field("id"),
- );
- }
- __field0 = _serde::export::Some(
- try!(_serde::de::MapAccess::next_value::<u64>(&mut __map)),
- );
- }
- __Field::__field1 => {
- if _serde::export::Option::is_some(&__field1) {
- return _serde::export::Err(
- <__A::Error as _serde::de::Error>::duplicate_field("s"),
- );
- }
- __field1 = _serde::export::Some(
- try!(_serde::de::MapAccess::next_value::<String>(&mut __map)),
- );
- }
- _ => {
- let _ = try!(_serde::de::MapAccess::next_value::<
- _serde::de::IgnoredAny,
- >(&mut __map));
- }
- }
- }
- let __field0 = match __field0 {
- _serde::export::Some(__field0) => __field0,
- _serde::export::None => try!(_serde::private::de::missing_field("id")),
- };
- let __field1 = match __field1 {
- _serde::export::Some(__field1) => __field1,
- _serde::export::None => try!(_serde::private::de::missing_field("s")),
- };
- _serde::export::Ok(Response {
- id: __field0,
- s: __field1,
- })
- }
- }
- const FIELDS: &'static [&'static str] = &["id", "s"];
- _serde::Deserializer::deserialize_struct(
- __deserializer,
- "Response",
- FIELDS,
- __Visitor {
- marker: _serde::export::PhantomData::<Response>,
- lifetime: _serde::export::PhantomData,
- },
- )
- }
- }
- }
- });
-}
diff --git a/quote/src/ext.rs b/quote/src/ext.rs
deleted file mode 100644
index 9e9b4a5..0000000
--- a/quote/src/ext.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-use super::ToTokens;
-
-use std::iter;
-
-use proc_macro2::{TokenStream, TokenTree};
-
-/// TokenStream extension trait with methods for appending tokens.
-///
-/// This trait is sealed and cannot be implemented outside of the `quote` crate.
-pub trait TokenStreamExt: private::Sealed {
- /// For use by `ToTokens` implementations.
- ///
- /// Appends the token specified to this list of tokens.
- fn append<U>(&mut self, token: U)
- where
- U: Into<TokenTree>;
-
- /// For use by `ToTokens` implementations.
- ///
- /// ```
- /// # use quote::{quote, TokenStreamExt, ToTokens};
- /// # use proc_macro2::TokenStream;
- /// #
- /// struct X;
- ///
- /// impl ToTokens for X {
- /// fn to_tokens(&self, tokens: &mut TokenStream) {
- /// tokens.append_all(&[true, false]);
- /// }
- /// }
- ///
- /// let tokens = quote!(#X);
- /// assert_eq!(tokens.to_string(), "true false");
- /// ```
- fn append_all<I>(&mut self, iter: I)
- where
- I: IntoIterator,
- I::Item: ToTokens;
-
- /// For use by `ToTokens` implementations.
- ///
- /// Appends all of the items in the iterator `I`, separated by the tokens
- /// `U`.
- fn append_separated<I, U>(&mut self, iter: I, op: U)
- where
- I: IntoIterator,
- I::Item: ToTokens,
- U: ToTokens;
-
- /// For use by `ToTokens` implementations.
- ///
- /// Appends all tokens in the iterator `I`, appending `U` after each
- /// element, including after the last element of the iterator.
- fn append_terminated<I, U>(&mut self, iter: I, term: U)
- where
- I: IntoIterator,
- I::Item: ToTokens,
- U: ToTokens;
-}
-
-impl TokenStreamExt for TokenStream {
- fn append<U>(&mut self, token: U)
- where
- U: Into<TokenTree>,
- {
- self.extend(iter::once(token.into()));
- }
-
- fn append_all<I>(&mut self, iter: I)
- where
- I: IntoIterator,
- I::Item: ToTokens,
- {
- for token in iter {
- token.to_tokens(self);
- }
- }
-
- fn append_separated<I, U>(&mut self, iter: I, op: U)
- where
- I: IntoIterator,
- I::Item: ToTokens,
- U: ToTokens,
- {
- for (i, token) in iter.into_iter().enumerate() {
- if i > 0 {
- op.to_tokens(self);
- }
- token.to_tokens(self);
- }
- }
-
- fn append_terminated<I, U>(&mut self, iter: I, term: U)
- where
- I: IntoIterator,
- I::Item: ToTokens,
- U: ToTokens,
- {
- for token in iter {
- token.to_tokens(self);
- term.to_tokens(self);
- }
- }
-}
-
-mod private {
- use proc_macro2::TokenStream;
-
- pub trait Sealed {}
-
- impl Sealed for TokenStream {}
-}
diff --git a/quote/src/format.rs b/quote/src/format.rs
deleted file mode 100644
index 13c8811..0000000
--- a/quote/src/format.rs
+++ /dev/null
@@ -1,164 +0,0 @@
-/// Formatting macro for constructing `Ident`s.
-///
-/// <br>
-///
-/// # Syntax
-///
-/// Syntax is copied from the [`format!`] macro, supporting both positional and
-/// named arguments.
-///
-/// Only a limited set of formatting traits are supported. The current mapping
-/// 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`)
-///
-/// See [`std::fmt`] for more information.
-///
-/// <br>
-///
-/// # IdentFragment
-///
-/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
-/// default. This trait is like `Display`, with a few differences:
-///
-/// * `IdentFragment` is only implemented for a limited set of types, such as
-/// unsigned integers and strings.
-/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
-///
-/// [`Ident`]: `proc_macro2::Ident`
-///
-/// <br>
-///
-/// # Hygiene
-///
-/// The [`Span`] of the first `Ident` argument is used as the span of the final
-/// identifier, falling back to [`Span::call_site`] when no identifiers are
-/// provided.
-///
-/// ```
-/// # use quote::format_ident;
-/// # let ident = format_ident!("Ident");
-/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
-/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
-/// assert_eq!(my_ident, "MyIdentIsCool");
-/// ```
-///
-/// Alternatively, the span can be overridden by passing the `span` named
-/// argument.
-///
-/// ```
-/// # use quote::format_ident;
-/// # const IGNORE_TOKENS: &'static str = stringify! {
-/// let my_span = /* ... */;
-/// # };
-/// # let my_span = proc_macro2::Span::call_site();
-/// format_ident!("MyIdent", span = my_span);
-/// ```
-///
-/// [`Span`]: `proc_macro2::Span`
-/// [`Span::call_site`]: `proc_macro2::Span::call_site`
-///
-/// <p><br></p>
-///
-/// # Panics
-///
-/// This method will panic if the resulting formatted string is not a valid
-/// identifier.
-///
-/// <br>
-///
-/// # Examples
-///
-/// Composing raw and non-raw identifiers:
-/// ```
-/// # use quote::format_ident;
-/// let my_ident = format_ident!("My{}", "Ident");
-/// assert_eq!(my_ident, "MyIdent");
-///
-/// let raw = format_ident!("r#Raw");
-/// assert_eq!(raw, "r#Raw");
-///
-/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
-/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
-/// ```
-///
-/// Integer formatting options:
-/// ```
-/// # use quote::format_ident;
-/// let num: u32 = 10;
-///
-/// let decimal = format_ident!("Id_{}", num);
-/// assert_eq!(decimal, "Id_10");
-///
-/// let octal = format_ident!("Id_{:o}", num);
-/// assert_eq!(octal, "Id_12");
-///
-/// let binary = format_ident!("Id_{:b}", num);
-/// assert_eq!(binary, "Id_1010");
-///
-/// let lower_hex = format_ident!("Id_{:x}", num);
-/// assert_eq!(lower_hex, "Id_a");
-///
-/// let upper_hex = format_ident!("Id_{:X}", num);
-/// assert_eq!(upper_hex, "Id_A");
-/// ```
-#[macro_export]
-macro_rules! format_ident {
- ($fmt:expr) => {
- $crate::format_ident_impl!([
- ::std::option::Option::None,
- $fmt
- ])
- };
-
- ($fmt:expr, $($rest:tt)*) => {
- $crate::format_ident_impl!([
- ::std::option::Option::None,
- $fmt
- ] $($rest)*)
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! format_ident_impl {
- // Final state
- ([$span:expr, $($fmt:tt)*]) => {
- $crate::__rt::mk_ident(&format!($($fmt)*), $span)
- };
-
- // Span argument
- ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
- $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
- };
- ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
- $crate::format_ident_impl!([
- ::std::option::Option::Some::<$crate::__rt::Span>($span),
- $($fmt)*
- ] $($rest)*)
- };
-
- // Named argument
- ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
- $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
- };
- ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
- match $crate::__rt::IdentFragmentAdapter(&$arg) {
- arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
- }
- };
-
- // Positional argument
- ([$span:expr, $($fmt:tt)*] $arg:expr) => {
- $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
- };
- ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
- match $crate::__rt::IdentFragmentAdapter(&$arg) {
- arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
- }
- };
-}
diff --git a/quote/src/ident_fragment.rs b/quote/src/ident_fragment.rs
deleted file mode 100644
index 09ead65..0000000
--- a/quote/src/ident_fragment.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-use proc_macro2::{Ident, Span};
-use std::fmt;
-
-/// Specialized formatting trait used by `format_ident!`.
-///
-/// [`Ident`] arguments formatted using this trait will have their `r#` prefix
-/// stripped, if present.
-///
-/// See [`format_ident!`] for more information.
-pub trait IdentFragment {
- /// Format this value as an identifier fragment.
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
-
- /// Span associated with this `IdentFragment`.
- ///
- /// If non-`None`, may be inherited by formatted identifiers.
- fn span(&self) -> Option<Span> {
- None
- }
-}
-
-impl<'a, T: IdentFragment + ?Sized> IdentFragment for &'a T {
- fn span(&self) -> Option<Span> {
- <T as IdentFragment>::span(*self)
- }
-
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- IdentFragment::fmt(*self, f)
- }
-}
-
-impl<'a, T: IdentFragment + ?Sized> IdentFragment for &'a mut T {
- fn span(&self) -> Option<Span> {
- <T as IdentFragment>::span(*self)
- }
-
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- IdentFragment::fmt(*self, f)
- }
-}
-
-impl IdentFragment for Ident {
- fn span(&self) -> Option<Span> {
- Some(self.span())
- }
-
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let id = self.to_string();
- if id.starts_with("r#") {
- fmt::Display::fmt(&id[2..], f)
- } else {
- fmt::Display::fmt(&id[..], f)
- }
- }
-}
-
-// Limited set of types which this is implemented for, as we want to avoid types
-// which will often include non-identifier characters in their `Display` impl.
-macro_rules! ident_fragment_display {
- ($($T:ty),*) => {
- $(
- impl IdentFragment for $T {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self, f)
- }
- }
- )*
- }
-}
-
-ident_fragment_display!(bool, str, String);
-ident_fragment_display!(u8, u16, u32, u64, u128, usize);
diff --git a/quote/src/lib.rs b/quote/src/lib.rs
deleted file mode 100644
index 3341a16..0000000
--- a/quote/src/lib.rs
+++ /dev/null
@@ -1,948 +0,0 @@
-//! This crate provides the [`quote!`] macro for turning Rust syntax tree data
-//! structures into tokens of source code.
-//!
-//! [`quote!`]: macro.quote.html
-//!
-//! Procedural macros in Rust receive a stream of tokens as input, execute
-//! arbitrary Rust code to determine how to manipulate those tokens, and produce
-//! a stream of tokens to hand back to the compiler to compile into the caller's
-//! crate. Quasi-quoting is a solution to one piece of that &mdash; producing
-//! tokens to return to the compiler.
-//!
-//! The idea of quasi-quoting is that we write *code* that we treat as *data*.
-//! Within the `quote!` macro, we can write what looks like code to our text
-//! editor or IDE. We get all the benefits of the editor's brace matching,
-//! syntax highlighting, indentation, and maybe autocompletion. But rather than
-//! compiling that as code into the current crate, we can treat it as data, pass
-//! it around, mutate it, and eventually hand it back to the compiler as tokens
-//! to compile into the macro caller's crate.
-//!
-//! This crate is motivated by the procedural macro use case, but is a
-//! general-purpose Rust quasi-quoting library and is not specific to procedural
-//! macros.
-//!
-//! ```toml
-//! [dependencies]
-//! quote = "1.0"
-//! ```
-//!
-//! <br>
-//!
-//! # Example
-//!
-//! The following quasi-quoted block of code is something you might find in [a]
-//! procedural macro having to do with data structure serialization. The `#var`
-//! syntax performs interpolation of runtime variables into the quoted tokens.
-//! Check out the documentation of the [`quote!`] macro for more detail about
-//! the syntax. See also the [`quote_spanned!`] macro which is important for
-//! implementing hygienic procedural macros.
-//!
-//! [a]: https://serde.rs/
-//! [`quote_spanned!`]: macro.quote_spanned.html
-//!
-//! ```
-//! # use quote::quote;
-//! #
-//! # let generics = "";
-//! # let where_clause = "";
-//! # let field_ty = "";
-//! # let item_ty = "";
-//! # let path = "";
-//! # let value = "";
-//! #
-//! let tokens = quote! {
-//! struct SerializeWith #generics #where_clause {
-//! value: &'a #field_ty,
-//! phantom: core::marker::PhantomData<#item_ty>,
-//! }
-//!
-//! impl #generics serde::Serialize for SerializeWith #generics #where_clause {
-//! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-//! where
-//! S: serde::Serializer,
-//! {
-//! #path(self.value, serializer)
-//! }
-//! }
-//!
-//! SerializeWith {
-//! value: #value,
-//! phantom: core::marker::PhantomData::<#item_ty>,
-//! }
-//! };
-//! ```
-
-// Quote types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/quote/1.0.2")]
-
-#[cfg(all(
- not(all(target_arch = "wasm32", target_os = "unknown")),
- feature = "proc-macro"
-))]
-extern crate proc_macro;
-
-mod ext;
-mod format;
-mod ident_fragment;
-mod to_tokens;
-
-// Not public API.
-#[doc(hidden)]
-#[path = "runtime.rs"]
-pub mod __rt;
-
-pub use crate::ext::TokenStreamExt;
-pub use crate::ident_fragment::IdentFragment;
-pub use crate::to_tokens::ToTokens;
-
-// Not public API.
-#[doc(hidden)]
-pub mod spanned;
-
-/// The whole point.
-///
-/// Performs variable interpolation against the input and produces it as
-/// [`proc_macro2::TokenStream`].
-///
-/// Note: for returning tokens to the compiler in a procedural macro, use
-/// `.into()` on the result to convert to [`proc_macro::TokenStream`].
-///
-/// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
-///
-/// <br>
-///
-/// # Interpolation
-///
-/// Variable interpolation is done with `#var` (similar to `$var` in
-/// `macro_rules!` macros). This grabs the `var` variable that is currently in
-/// scope and inserts it in that location in the output tokens. Any type
-/// implementing the [`ToTokens`] trait can be interpolated. This includes most
-/// Rust primitive types as well as most of the syntax tree types from the [Syn]
-/// crate.
-///
-/// [`ToTokens`]: trait.ToTokens.html
-/// [Syn]: https://github.com/dtolnay/syn
-///
-/// Repetition is done using `#(...)*` or `#(...),*` again similar to
-/// `macro_rules!`. This iterates through the elements of any variable
-/// interpolated within the repetition and inserts a copy of the repetition body
-/// for each one. The variables in an interpolation may be a `Vec`, slice,
-/// `BTreeSet`, or any `Iterator`.
-///
-/// - `#(#var)*` — no separators
-/// - `#(#var),*` — the character before the asterisk is used as a separator
-/// - `#( struct #var; )*` — the repetition can contain other tokens
-/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
-///
-/// <br>
-///
-/// # Hygiene
-///
-/// Any interpolated tokens preserve the `Span` information provided by their
-/// `ToTokens` implementation. Tokens that originate within the `quote!`
-/// invocation are spanned with [`Span::call_site()`].
-///
-/// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
-///
-/// A different span can be provided through the [`quote_spanned!`] macro.
-///
-/// [`quote_spanned!`]: macro.quote_spanned.html
-///
-/// <br>
-///
-/// # Return type
-///
-/// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
-/// Meanwhile Rust procedural macros are expected to return the type
-/// `proc_macro::TokenStream`.
-///
-/// The difference between the two types is that `proc_macro` types are entirely
-/// specific to procedural macros and cannot ever exist in code outside of a
-/// procedural macro, while `proc_macro2` types may exist anywhere including
-/// tests and non-macro code like main.rs and build.rs. This is why even the
-/// procedural macro ecosystem is largely built around `proc_macro2`, because
-/// that ensures the libraries are unit testable and accessible in non-macro
-/// contexts.
-///
-/// There is a [`From`]-conversion in both directions so returning the output of
-/// `quote!` from a procedural macro usually looks like `tokens.into()` or
-/// `proc_macro::TokenStream::from(tokens)`.
-///
-/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
-///
-/// <br>
-///
-/// # Examples
-///
-/// ### Procedural macro
-///
-/// The structure of a basic procedural macro is as follows. Refer to the [Syn]
-/// crate for further useful guidance on using `quote!` as part of a procedural
-/// macro.
-///
-/// [Syn]: https://github.com/dtolnay/syn
-///
-/// ```
-/// # #[cfg(any())]
-/// extern crate proc_macro;
-/// # extern crate proc_macro2;
-///
-/// # #[cfg(any())]
-/// use proc_macro::TokenStream;
-/// # use proc_macro2::TokenStream;
-/// use quote::quote;
-///
-/// # const IGNORE_TOKENS: &'static str = stringify! {
-/// #[proc_macro_derive(HeapSize)]
-/// # };
-/// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
-/// // Parse the input and figure out what implementation to generate...
-/// # const IGNORE_TOKENS: &'static str = stringify! {
-/// let name = /* ... */;
-/// let expr = /* ... */;
-/// # };
-/// #
-/// # let name = 0;
-/// # let expr = 0;
-///
-/// let expanded = quote! {
-/// // The generated impl.
-/// impl heapsize::HeapSize for #name {
-/// fn heap_size_of_children(&self) -> usize {
-/// #expr
-/// }
-/// }
-/// };
-///
-/// // Hand the output tokens back to the compiler.
-/// TokenStream::from(expanded)
-/// }
-/// ```
-///
-/// <p><br></p>
-///
-/// ### Combining quoted fragments
-///
-/// Usually you don't end up constructing an entire final `TokenStream` in one
-/// piece. Different parts may come from different helper functions. The tokens
-/// produced by `quote!` themselves implement `ToTokens` and so can be
-/// interpolated into later `quote!` invocations to build up a final result.
-///
-/// ```
-/// # use quote::quote;
-/// #
-/// let type_definition = quote! {...};
-/// let methods = quote! {...};
-///
-/// let tokens = quote! {
-/// #type_definition
-/// #methods
-/// };
-/// ```
-///
-/// <p><br></p>
-///
-/// ### Constructing identifiers
-///
-/// Suppose we have an identifier `ident` which came from somewhere in a macro
-/// input and we need to modify it in some way for the macro output. Let's
-/// consider prepending the identifier with an underscore.
-///
-/// Simply interpolating the identifier next to an underscore will not have the
-/// behavior of concatenating them. The underscore and the identifier will
-/// continue to be two separate tokens as if you had written `_ x`.
-///
-/// ```
-/// # use proc_macro2::{self as syn, Span};
-/// # use quote::quote;
-/// #
-/// # let ident = syn::Ident::new("i", Span::call_site());
-/// #
-/// // incorrect
-/// quote! {
-/// let mut _#ident = 0;
-/// }
-/// # ;
-/// ```
-///
-/// The solution is to build a new identifier token with the correct value. As
-/// this is such a common case, the [`format_ident!`] macro provides a
-/// convenient utility for doing so correctly.
-///
-/// ```
-/// # use proc_macro2::{Ident, Span};
-/// # use quote::{format_ident, quote};
-/// #
-/// # let ident = Ident::new("i", Span::call_site());
-/// #
-/// let varname = format_ident!("_{}", ident);
-/// quote! {
-/// let mut #varname = 0;
-/// }
-/// # ;
-/// ```
-///
-/// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
-/// directly build the identifier. This is roughly equivalent to the above, but
-/// will not handle `ident` being a raw identifier.
-///
-/// ```
-/// # use proc_macro2::{self as syn, Span};
-/// # use quote::quote;
-/// #
-/// # let ident = syn::Ident::new("i", Span::call_site());
-/// #
-/// let concatenated = format!("_{}", ident);
-/// let varname = syn::Ident::new(&concatenated, ident.span());
-/// quote! {
-/// let mut #varname = 0;
-/// }
-/// # ;
-/// ```
-///
-/// <p><br></p>
-///
-/// ### Making method calls
-///
-/// Let's say our macro requires some type specified in the macro input to have
-/// a constructor called `new`. We have the type in a variable called
-/// `field_type` of type `syn::Type` and want to invoke the constructor.
-///
-/// ```
-/// # use quote::quote;
-/// #
-/// # let field_type = quote!(...);
-/// #
-/// // incorrect
-/// quote! {
-/// let value = #field_type::new();
-/// }
-/// # ;
-/// ```
-///
-/// This works only sometimes. If `field_type` is `String`, the expanded code
-/// contains `String::new()` which is fine. But if `field_type` is something
-/// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
-/// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
-/// but for macros often the following is more convenient.
-///
-/// ```
-/// # use quote::quote;
-/// #
-/// # let field_type = quote!(...);
-/// #
-/// quote! {
-/// let value = <#field_type>::new();
-/// }
-/// # ;
-/// ```
-///
-/// This expands to `<Vec<i32>>::new()` which behaves correctly.
-///
-/// A similar pattern is appropriate for trait methods.
-///
-/// ```
-/// # use quote::quote;
-/// #
-/// # let field_type = quote!(...);
-/// #
-/// quote! {
-/// let value = <#field_type as core::default::Default>::default();
-/// }
-/// # ;
-/// ```
-///
-/// <p><br></p>
-///
-/// ### Interpolating text inside of doc comments
-///
-/// Neither doc comments nor string literals get interpolation behavior in
-/// quote:
-///
-/// ```compile_fail
-/// quote! {
-/// /// try to interpolate: #ident
-/// ///
-/// /// ...
-/// }
-/// ```
-///
-/// ```compile_fail
-/// quote! {
-/// #[doc = "try to interpolate: #ident"]
-/// }
-/// ```
-///
-/// 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.
-///
-/// ```rust
-/// # use proc_macro2::{Ident, Span};
-/// # use quote::quote;
-/// #
-/// # const IGNORE: &str = stringify! {
-/// let msg = format!(...);
-/// # };
-/// #
-/// # let ident = Ident::new("var", Span::call_site());
-/// # let msg = format!("try to interpolate: {}", ident);
-/// quote! {
-/// #[doc = #msg]
-/// ///
-/// /// ...
-/// }
-/// # ;
-/// ```
-///
-/// <p><br></p>
-///
-/// ### Indexing into a tuple struct
-///
-/// When interpolating indices of a tuple or tuple struct, we need them not to
-/// appears suffixed as integer literals by interpolating them as [`syn::Index`]
-/// instead.
-///
-/// [`syn::Index`]: https://docs.rs/syn/1.0/syn/struct.Index.html
-///
-/// ```compile_fail
-/// let i = 0usize..self.fields.len();
-///
-/// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
-/// // which is not valid syntax
-/// quote! {
-/// 0 #( + self.#i.heap_size() )*
-/// }
-/// ```
-///
-/// ```
-/// # use proc_macro2::{Ident, TokenStream};
-/// # use quote::quote;
-/// #
-/// # mod syn {
-/// # use proc_macro2::{Literal, TokenStream};
-/// # use quote::{ToTokens, TokenStreamExt};
-/// #
-/// # pub struct Index(usize);
-/// #
-/// # impl From<usize> for Index {
-/// # fn from(i: usize) -> Self {
-/// # Index(i)
-/// # }
-/// # }
-/// #
-/// # impl ToTokens for Index {
-/// # fn to_tokens(&self, tokens: &mut TokenStream) {
-/// # tokens.append(Literal::usize_unsuffixed(self.0));
-/// # }
-/// # }
-/// # }
-/// #
-/// # struct Struct {
-/// # fields: Vec<Ident>,
-/// # }
-/// #
-/// # impl Struct {
-/// # fn example(&self) -> TokenStream {
-/// let i = (0..self.fields.len()).map(syn::Index::from);
-///
-/// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
-/// quote! {
-/// 0 #( + self.#i.heap_size() )*
-/// }
-/// # }
-/// # }
-/// ```
-#[macro_export]
-macro_rules! quote {
- ($($tt:tt)*) => {
- $crate::quote_spanned!($crate::__rt::Span::call_site()=> $($tt)*)
- };
-}
-
-/// Same as `quote!`, but applies a given span to all tokens originating within
-/// the macro invocation.
-///
-/// <br>
-///
-/// # Syntax
-///
-/// A span expression of type [`Span`], followed by `=>`, followed by the tokens
-/// to quote. The span expression should be brief &mdash; use a variable for
-/// anything more than a few characters. There should be no space before the
-/// `=>` token.
-///
-/// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
-///
-/// ```
-/// # use proc_macro2::Span;
-/// # use quote::quote_spanned;
-/// #
-/// # const IGNORE_TOKENS: &'static str = stringify! {
-/// let span = /* ... */;
-/// # };
-/// # let span = Span::call_site();
-/// # let init = 0;
-///
-/// // On one line, use parentheses.
-/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
-///
-/// // On multiple lines, place the span at the top and use braces.
-/// let tokens = quote_spanned! {span=>
-/// Box::into_raw(Box::new(#init))
-/// };
-/// ```
-///
-/// The lack of space before the `=>` should look jarring to Rust programmers
-/// and this is intentional. The formatting is designed to be visibly
-/// off-balance and draw the eye a particular way, due to the span expression
-/// being evaluated in the context of the procedural macro and the remaining
-/// tokens being evaluated in the generated code.
-///
-/// <br>
-///
-/// # Hygiene
-///
-/// Any interpolated tokens preserve the `Span` information provided by their
-/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
-/// invocation are spanned with the given span argument.
-///
-/// <br>
-///
-/// # Example
-///
-/// The following procedural macro code uses `quote_spanned!` to assert that a
-/// particular Rust type implements the [`Sync`] trait so that references can be
-/// safely shared between threads.
-///
-/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
-///
-/// ```
-/// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
-/// # use proc_macro2::{Span, TokenStream};
-/// #
-/// # struct Type;
-/// #
-/// # impl Type {
-/// # fn span(&self) -> Span {
-/// # Span::call_site()
-/// # }
-/// # }
-/// #
-/// # impl ToTokens for Type {
-/// # fn to_tokens(&self, _tokens: &mut TokenStream) {}
-/// # }
-/// #
-/// # let ty = Type;
-/// # let call_site = Span::call_site();
-/// #
-/// let ty_span = ty.span();
-/// let assert_sync = quote_spanned! {ty_span=>
-/// struct _AssertSync where #ty: Sync;
-/// };
-/// ```
-///
-/// If the assertion fails, the user will see an error like the following. The
-/// input span of their type is hightlighted in the error.
-///
-/// ```text
-/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
-/// --> src/main.rs:10:21
-/// |
-/// 10 | static ref PTR: *const () = &();
-/// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely
-/// ```
-///
-/// 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.
-#[macro_export]
-macro_rules! quote_spanned {
- ($span:expr=> $($tt:tt)*) => {{
- let mut _s = $crate::__rt::TokenStream::new();
- let _span: $crate::__rt::Span = $span;
- $crate::quote_each_token!(_s _span $($tt)*);
- _s
- }};
-}
-
-// Extract the names of all #metavariables and pass them to the $call macro.
-//
-// in: pounded_var_names!(then!(...) a #b c #( #d )* #e)
-// out: then!(... b);
-// then!(... d);
-// then!(... e);
-#[macro_export]
-#[doc(hidden)]
-macro_rules! pounded_var_names {
- ($call:ident! $extra:tt $($tts:tt)*) => {
- $crate::pounded_var_names_with_context!($call! $extra
- (@ $($tts)*)
- ($($tts)* @)
- )
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! pounded_var_names_with_context {
- ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
- $(
- $crate::pounded_var_with_context!($call! $extra $b1 $curr);
- )*
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! pounded_var_with_context {
- ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
- };
-
- ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
- };
-
- ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
- $crate::pounded_var_names!($call! $extra $($inner)*);
- };
-
- ($call:ident!($($extra:tt)*) # $var:ident) => {
- $crate::$call!($($extra)* $var);
- };
-
- ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_bind_into_iter {
- ($has_iter:ident $var:ident) => {
- // `mut` may be unused if $var occurs multiple times in the list.
- #[allow(unused_mut)]
- let (mut $var, i) = $var.quote_into_iter();
- let $has_iter = $has_iter | i;
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_bind_next_or_break {
- ($var:ident) => {
- let $var = match $var.next() {
- Some(_x) => $crate::__rt::RepInterp(_x),
- None => break,
- };
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_each_token {
- ($tokens:ident $span:ident $($tts:tt)*) => {
- $crate::quote_tokens_with_context!($tokens $span
- (@ @ @ @ @ @ $($tts)*)
- (@ @ @ @ @ $($tts)* @)
- (@ @ @ @ $($tts)* @ @)
- (@ @ @ $(($tts))* @ @ @)
- (@ @ $($tts)* @ @ @ @)
- (@ $($tts)* @ @ @ @ @)
- ($($tts)* @ @ @ @ @ @)
- );
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_tokens_with_context {
- ($tokens:ident $span:ident
- ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
- ($($curr:tt)*)
- ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
- ) => {
- $(
- $crate::quote_token_with_context!($tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3);
- )*
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_token_with_context {
- ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
-
- ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
- use $crate::__rt::ext::*;
- let has_iter = $crate::__rt::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
- let _: $crate::__rt::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.
- while true {
- $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
- $crate::quote_each_token!($tokens $span $($inner)*);
- }
- }};
- ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
- ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
-
- ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
- use $crate::__rt::ext::*;
- let mut _i = 0usize;
- let has_iter = $crate::__rt::ThereIsNoIteratorInRepetition;
- $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
- let _: $crate::__rt::HasIterator = has_iter;
- while true {
- $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
- if _i > 0 {
- $crate::quote_token!($tokens $span $sep);
- }
- _i += 1;
- $crate::quote_each_token!($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!($tokens $span *);
- };
- ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
-
- ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
- $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!($tokens $span $curr);
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! quote_token {
- ($tokens:ident $span:ident ( $($inner:tt)* )) => {
- $tokens.extend({
- let mut g = $crate::__rt::Group::new(
- $crate::__rt::Delimiter::Parenthesis,
- $crate::quote_spanned!($span=> $($inner)*),
- );
- g.set_span($span);
- Some($crate::__rt::TokenTree::from(g))
- });
- };
-
- ($tokens:ident $span:ident [ $($inner:tt)* ]) => {
- $tokens.extend({
- let mut g = $crate::__rt::Group::new(
- $crate::__rt::Delimiter::Bracket,
- $crate::quote_spanned!($span=> $($inner)*),
- );
- g.set_span($span);
- Some($crate::__rt::TokenTree::from(g))
- });
- };
-
- ($tokens:ident $span:ident { $($inner:tt)* }) => {
- $tokens.extend({
- let mut g = $crate::__rt::Group::new(
- $crate::__rt::Delimiter::Brace,
- $crate::quote_spanned!($span=> $($inner)*),
- );
- g.set_span($span);
- Some($crate::__rt::TokenTree::from(g))
- });
- };
-
- ($tokens:ident $span:ident +) => {
- $crate::__rt::push_add(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident +=) => {
- $crate::__rt::push_add_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident &) => {
- $crate::__rt::push_and(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident &&) => {
- $crate::__rt::push_and_and(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident &=) => {
- $crate::__rt::push_and_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident @) => {
- $crate::__rt::push_at(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident !) => {
- $crate::__rt::push_bang(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ^) => {
- $crate::__rt::push_caret(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ^=) => {
- $crate::__rt::push_caret_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident :) => {
- $crate::__rt::push_colon(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ::) => {
- $crate::__rt::push_colon2(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ,) => {
- $crate::__rt::push_comma(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident /) => {
- $crate::__rt::push_div(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident /=) => {
- $crate::__rt::push_div_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident .) => {
- $crate::__rt::push_dot(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ..) => {
- $crate::__rt::push_dot2(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ...) => {
- $crate::__rt::push_dot3(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ..=) => {
- $crate::__rt::push_dot_dot_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident =) => {
- $crate::__rt::push_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ==) => {
- $crate::__rt::push_eq_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident >=) => {
- $crate::__rt::push_ge(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident >) => {
- $crate::__rt::push_gt(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <=) => {
- $crate::__rt::push_le(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <) => {
- $crate::__rt::push_lt(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident *=) => {
- $crate::__rt::push_mul_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident !=) => {
- $crate::__rt::push_ne(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident |) => {
- $crate::__rt::push_or(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident |=) => {
- $crate::__rt::push_or_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ||) => {
- $crate::__rt::push_or_or(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident #) => {
- $crate::__rt::push_pound(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ?) => {
- $crate::__rt::push_question(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ->) => {
- $crate::__rt::push_rarrow(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <-) => {
- $crate::__rt::push_larrow(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident %) => {
- $crate::__rt::push_rem(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident %=) => {
- $crate::__rt::push_rem_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident =>) => {
- $crate::__rt::push_fat_arrow(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident ;) => {
- $crate::__rt::push_semi(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <<) => {
- $crate::__rt::push_shl(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident <<=) => {
- $crate::__rt::push_shl_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident >>) => {
- $crate::__rt::push_shr(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident >>=) => {
- $crate::__rt::push_shr_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident *) => {
- $crate::__rt::push_star(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident -) => {
- $crate::__rt::push_sub(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident -=) => {
- $crate::__rt::push_sub_eq(&mut $tokens, $span);
- };
-
- ($tokens:ident $span:ident $other:tt) => {
- $crate::__rt::parse(&mut $tokens, $span, stringify!($other));
- };
-}
diff --git a/quote/src/runtime.rs b/quote/src/runtime.rs
deleted file mode 100644
index 4a1c14c..0000000
--- a/quote/src/runtime.rs
+++ /dev/null
@@ -1,373 +0,0 @@
-use crate::{IdentFragment, ToTokens, TokenStreamExt};
-use std::fmt;
-use std::ops::BitOr;
-
-pub use proc_macro2::*;
-
-pub struct HasIterator; // True
-pub struct ThereIsNoIteratorInRepetition; // False
-
-impl BitOr<ThereIsNoIteratorInRepetition> for ThereIsNoIteratorInRepetition {
- type Output = ThereIsNoIteratorInRepetition;
- fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition {
- ThereIsNoIteratorInRepetition
- }
-}
-
-impl BitOr<ThereIsNoIteratorInRepetition> for HasIterator {
- type Output = HasIterator;
- fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator {
- HasIterator
- }
-}
-
-impl BitOr<HasIterator> for ThereIsNoIteratorInRepetition {
- type Output = HasIterator;
- fn bitor(self, _rhs: HasIterator) -> HasIterator {
- HasIterator
- }
-}
-
-impl BitOr<HasIterator> for HasIterator {
- type Output = HasIterator;
- fn bitor(self, _rhs: HasIterator) -> HasIterator {
- HasIterator
- }
-}
-
-/// Extension traits used by the implementation of `quote!`. These are defined
-/// in separate traits, rather than as a single trait due to ambiguity issues.
-///
-/// These traits expose a `quote_into_iter` method which should allow calling
-/// whichever impl happens to be applicable. Calling that method repeatedly on
-/// the returned value should be idempotent.
-pub mod ext {
- use super::RepInterp;
- use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
- use crate::ToTokens;
- 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 {
- fn quote_into_iter(self) -> (Self, HasIter) {
- (self, HasIter)
- }
- }
-
- impl<T: Iterator> RepIteratorExt for T {}
-
- /// Extension trait providing the `quote_into_iter` method for
- /// non-iterable types. These types interpolate the same value in each
- /// iteration of the repetition.
- pub trait RepToTokensExt {
- /// Pretend to be an iterator for the purposes of `quote_into_iter`.
- /// This allows repeated calls to `quote_into_iter` to continue
- /// correctly returning DoesNotHaveIter.
- fn next(&self) -> Option<&Self> {
- Some(self)
- }
-
- fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) {
- (self, DoesNotHaveIter)
- }
- }
-
- impl<T: ToTokens + ?Sized> RepToTokensExt for T {}
-
- /// Extension trait providing the `quote_into_iter` method for types that
- /// can be referenced as an iterator.
- pub trait RepAsIteratorExt<'q> {
- type Iter: Iterator;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter);
- }
-
- impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T {
- type Iter = T::Iter;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- <T as RepAsIteratorExt>::quote_into_iter(*self)
- }
- }
-
- impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T {
- type Iter = T::Iter;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- <T as RepAsIteratorExt>::quote_into_iter(*self)
- }
- }
-
- impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] {
- type Iter = slice::Iter<'q, T>;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- (self.iter(), HasIter)
- }
- }
-
- impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec<T> {
- type Iter = slice::Iter<'q, T>;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- (self.iter(), HasIter)
- }
- }
-
- impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet<T> {
- type Iter = btree_set::Iter<'q, T>;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- (self.iter(), HasIter)
- }
- }
-
- 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;
-
- fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
- self.0.quote_into_iter()
- }
- }
-}
-
-// Helper type used within interpolations to allow for repeated binding names.
-// Implements the relevant traits, and exports a dummy `next()` method.
-#[derive(Copy, Clone)]
-pub struct RepInterp<T>(pub T);
-
-impl<T> RepInterp<T> {
- // This method is intended to look like `Iterator::next`, and is called when
- // a name is bound multiple times, as the previous binding will shadow the
- // original `Iterator` object. This allows us to avoid advancing the
- // iterator multiple times per iteration.
- pub fn next(self) -> Option<T> {
- Some(self.0)
- }
-}
-
-impl<T: Iterator> Iterator for RepInterp<T> {
- type Item = T::Item;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.0.next()
- }
-}
-
-impl<T: ToTokens> ToTokens for RepInterp<T> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.0.to_tokens(tokens);
- }
-}
-
-fn is_ident_start(c: u8) -> bool {
- (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_'
-}
-
-fn is_ident_continue(c: u8) -> bool {
- (b'a' <= c && c <= b'z') || (b'A' <= c && c <= b'Z') || c == b'_' || (b'0' <= c && c <= b'9')
-}
-
-fn is_ident(token: &str) -> bool {
- let mut iter = token.bytes();
- let first_ok = iter.next().map(is_ident_start).unwrap_or(false);
-
- first_ok && iter.all(is_ident_continue)
-}
-
-pub fn parse(tokens: &mut TokenStream, span: Span, s: &str) {
- if is_ident(s) {
- // Fast path, since idents are the most common token.
- tokens.append(Ident::new(s, span));
- } else {
- let s: TokenStream = s.parse().expect("invalid token stream");
- tokens.extend(s.into_iter().map(|mut t| {
- t.set_span(span);
- t
- }));
- }
-}
-
-macro_rules! push_punct {
- ($name:ident $char1:tt) => {
- pub fn $name(tokens: &mut TokenStream, span: Span) {
- let mut punct = Punct::new($char1, Spacing::Alone);
- punct.set_span(span);
- tokens.append(punct);
- }
- };
- ($name:ident $char1:tt $char2:tt) => {
- pub fn $name(tokens: &mut TokenStream, span: Span) {
- let mut punct = Punct::new($char1, Spacing::Joint);
- punct.set_span(span);
- tokens.append(punct);
- let mut punct = Punct::new($char2, Spacing::Alone);
- punct.set_span(span);
- tokens.append(punct);
- }
- };
- ($name:ident $char1:tt $char2:tt $char3:tt) => {
- pub fn $name(tokens: &mut TokenStream, span: Span) {
- let mut punct = Punct::new($char1, Spacing::Joint);
- punct.set_span(span);
- tokens.append(punct);
- let mut punct = Punct::new($char2, Spacing::Joint);
- punct.set_span(span);
- tokens.append(punct);
- let mut punct = Punct::new($char3, Spacing::Alone);
- punct.set_span(span);
- tokens.append(punct);
- }
- };
-}
-
-push_punct!(push_add '+');
-push_punct!(push_add_eq '+' '=');
-push_punct!(push_and '&');
-push_punct!(push_and_and '&' '&');
-push_punct!(push_and_eq '&' '=');
-push_punct!(push_at '@');
-push_punct!(push_bang '!');
-push_punct!(push_caret '^');
-push_punct!(push_caret_eq '^' '=');
-push_punct!(push_colon ':');
-push_punct!(push_colon2 ':' ':');
-push_punct!(push_comma ',');
-push_punct!(push_div '/');
-push_punct!(push_div_eq '/' '=');
-push_punct!(push_dot '.');
-push_punct!(push_dot2 '.' '.');
-push_punct!(push_dot3 '.' '.' '.');
-push_punct!(push_dot_dot_eq '.' '.' '=');
-push_punct!(push_eq '=');
-push_punct!(push_eq_eq '=' '=');
-push_punct!(push_ge '>' '=');
-push_punct!(push_gt '>');
-push_punct!(push_le '<' '=');
-push_punct!(push_lt '<');
-push_punct!(push_mul_eq '*' '=');
-push_punct!(push_ne '!' '=');
-push_punct!(push_or '|');
-push_punct!(push_or_eq '|' '=');
-push_punct!(push_or_or '|' '|');
-push_punct!(push_pound '#');
-push_punct!(push_question '?');
-push_punct!(push_rarrow '-' '>');
-push_punct!(push_larrow '<' '-');
-push_punct!(push_rem '%');
-push_punct!(push_rem_eq '%' '=');
-push_punct!(push_fat_arrow '=' '>');
-push_punct!(push_semi ';');
-push_punct!(push_shl '<' '<');
-push_punct!(push_shl_eq '<' '<' '=');
-push_punct!(push_shr '>' '>');
-push_punct!(push_shr_eq '>' '>' '=');
-push_punct!(push_star '*');
-push_punct!(push_sub '-');
-push_punct!(push_sub_eq '-' '=');
-
-// 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.
-//
-// The `is_ident` method defined above is insufficient for validation, as it
-// will reject non-ASCII identifiers.
-pub fn mk_ident(id: &str, span: Option<Span>) -> Ident {
- let span = span.unwrap_or_else(Span::call_site);
-
- 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.
- match id.parse::<TokenStream>() {
- Ok(ts) => {
- let mut iter = ts.into_iter();
- match (iter.next(), iter.next()) {
- (Some(TokenTree::Ident(mut id)), None) => {
- id.set_span(span);
- id
- }
- _ => unreachable!("valid raw ident fails to parse"),
- }
- }
- Err(_) => unreachable!("valid raw ident fails to parse"),
- }
-}
-
-// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!`
-// macro, and exposes span information from these fragments.
-//
-// This struct also has forwarding implementations of the formatting traits
-// `Octal`, `LowerHex`, `UpperHex`, and `Binary` to allow for their use within
-// `format_ident!`.
-#[derive(Copy, Clone)]
-pub struct IdentFragmentAdapter<T: IdentFragment>(pub T);
-
-impl<T: IdentFragment> IdentFragmentAdapter<T> {
- pub fn span(&self) -> Option<Span> {
- self.0.span()
- }
-}
-
-impl<T: IdentFragment> fmt::Display for IdentFragmentAdapter<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- IdentFragment::fmt(&self.0, f)
- }
-}
-
-impl<T: IdentFragment + fmt::Octal> fmt::Octal for IdentFragmentAdapter<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Octal::fmt(&self.0, f)
- }
-}
-
-impl<T: IdentFragment + fmt::LowerHex> fmt::LowerHex for IdentFragmentAdapter<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::LowerHex::fmt(&self.0, f)
- }
-}
-
-impl<T: IdentFragment + fmt::UpperHex> fmt::UpperHex for IdentFragmentAdapter<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::UpperHex::fmt(&self.0, f)
- }
-}
-
-impl<T: IdentFragment + fmt::Binary> fmt::Binary for IdentFragmentAdapter<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- fmt::Binary::fmt(&self.0, f)
- }
-}
diff --git a/quote/src/spanned.rs b/quote/src/spanned.rs
deleted file mode 100644
index 55168bd..0000000
--- a/quote/src/spanned.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use crate::ToTokens;
-use proc_macro2::{Span, TokenStream};
-
-pub trait Spanned {
- fn __span(&self) -> Span;
-}
-
-impl Spanned for Span {
- fn __span(&self) -> Span {
- *self
- }
-}
-
-impl<T: ?Sized + ToTokens> Spanned for T {
- fn __span(&self) -> Span {
- join_spans(self.into_token_stream())
- }
-}
-
-fn join_spans(tokens: TokenStream) -> Span {
- 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)") {
- None
- } else {
- Some(span)
- }
- });
-
- let first = match iter.next() {
- Some(span) => span,
- None => return Span::call_site(),
- };
-
- iter.fold(None, |_prev, next| Some(next))
- .and_then(|last| first.join(last))
- .unwrap_or(first)
-}
diff --git a/quote/src/to_tokens.rs b/quote/src/to_tokens.rs
deleted file mode 100644
index 7f98083..0000000
--- a/quote/src/to_tokens.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-use super::TokenStreamExt;
-
-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
-pub trait ToTokens {
- /// Write `self` to the given `TokenStream`.
- ///
- /// The token append methods provided by the [`TokenStreamExt`] extension
- /// trait may be useful for implementing `ToTokens`.
- ///
- /// [`TokenStreamExt`]: trait.TokenStreamExt.html
- ///
- /// # Example
- ///
- /// Example implementation for a struct representing Rust paths like
- /// `std::cmp::PartialEq`:
- ///
- /// ```
- /// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream};
- /// use quote::{TokenStreamExt, ToTokens};
- ///
- /// pub struct Path {
- /// pub global: bool,
- /// pub segments: Vec<PathSegment>,
- /// }
- ///
- /// impl ToTokens for Path {
- /// fn to_tokens(&self, tokens: &mut TokenStream) {
- /// for (i, segment) in self.segments.iter().enumerate() {
- /// if i > 0 || self.global {
- /// // Double colon `::`
- /// tokens.append(Punct::new(':', Spacing::Joint));
- /// tokens.append(Punct::new(':', Spacing::Alone));
- /// }
- /// segment.to_tokens(tokens);
- /// }
- /// }
- /// }
- /// #
- /// # pub struct PathSegment;
- /// #
- /// # impl ToTokens for PathSegment {
- /// # fn to_tokens(&self, tokens: &mut TokenStream) {
- /// # unimplemented!()
- /// # }
- /// # }
- /// ```
- fn to_tokens(&self, tokens: &mut TokenStream);
-
- /// Convert `self` directly into a `TokenStream` object.
- ///
- /// This method is implicitly implemented using `to_tokens`, and acts as a
- /// convenience method for consumers of the `ToTokens` trait.
- fn to_token_stream(&self) -> TokenStream {
- let mut tokens = TokenStream::new();
- self.to_tokens(&mut tokens);
- tokens
- }
-
- /// Convert `self` directly into a `TokenStream` object.
- ///
- /// This method is implicitly implemented using `to_tokens`, and acts as a
- /// convenience method for consumers of the `ToTokens` trait.
- fn into_token_stream(self) -> TokenStream
- where
- Self: Sized,
- {
- self.to_token_stream()
- }
-}
-
-impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens);
- }
-}
-
-impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens);
- }
-}
-
-impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens);
- }
-}
-
-impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens);
- }
-}
-
-impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens);
- }
-}
-
-impl<T: ToTokens> ToTokens for Option<T> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- if let Some(ref t) = *self {
- t.to_tokens(tokens);
- }
- }
-}
-
-impl ToTokens for str {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(Literal::string(self));
- }
-}
-
-impl ToTokens for String {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- self.as_str().to_tokens(tokens);
- }
-}
-
-macro_rules! primitive {
- ($($t:ident => $name:ident)*) => ($(
- impl ToTokens for $t {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(Literal::$name(*self));
- }
- }
- )*)
-}
-
-primitive! {
- i8 => i8_suffixed
- i16 => i16_suffixed
- i32 => i32_suffixed
- i64 => i64_suffixed
- i128 => i128_suffixed
- isize => isize_suffixed
-
- u8 => u8_suffixed
- u16 => u16_suffixed
- u32 => u32_suffixed
- u64 => u64_suffixed
- u128 => u128_suffixed
- usize => usize_suffixed
-
- f32 => f32_suffixed
- f64 => f64_suffixed
-}
-
-impl ToTokens for char {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(Literal::character(*self));
- }
-}
-
-impl ToTokens for bool {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- let word = if *self { "true" } else { "false" };
- tokens.append(Ident::new(word, Span::call_site()));
- }
-}
-
-impl ToTokens for Group {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(self.clone());
- }
-}
-
-impl ToTokens for Ident {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(self.clone());
- }
-}
-
-impl ToTokens for Punct {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(self.clone());
- }
-}
-
-impl ToTokens for Literal {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(self.clone());
- }
-}
-
-impl ToTokens for TokenTree {
- fn to_tokens(&self, dst: &mut TokenStream) {
- dst.append(self.clone());
- }
-}
-
-impl ToTokens for TokenStream {
- fn to_tokens(&self, dst: &mut TokenStream) {
- dst.extend(iter::once(self.clone()));
- }
-
- fn into_token_stream(self) -> TokenStream {
- self
- }
-}
diff --git a/quote/tests/compiletest.rs b/quote/tests/compiletest.rs
deleted file mode 100644
index f9aea23..0000000
--- a/quote/tests/compiletest.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[rustversion::attr(not(nightly), ignore)]
-#[test]
-fn ui() {
- let t = trybuild::TestCases::new();
- t.compile_fail("tests/ui/*.rs");
-}
diff --git a/quote/tests/test.rs b/quote/tests/test.rs
deleted file mode 100644
index 957d470..0000000
--- a/quote/tests/test.rs
+++ /dev/null
@@ -1,429 +0,0 @@
-#![cfg_attr(feature = "cargo-clippy", allow(blacklisted_name))]
-
-use std::borrow::Cow;
-use std::collections::BTreeSet;
-
-use proc_macro2::{Ident, Span, TokenStream};
-use quote::{format_ident, quote, TokenStreamExt};
-
-struct X;
-
-impl quote::ToTokens for X {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append(Ident::new("X", Span::call_site()));
- }
-}
-
-#[test]
-fn test_quote_impl() {
- let tokens = quote! {
- impl<'a, T: ToTokens> ToTokens for &'a T {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- (**self).to_tokens(tokens)
- }
- }
- };
-
- let expected = concat!(
- "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
- "fn to_tokens ( & self , tokens : & mut TokenStream ) { ",
- "( * * self ) . to_tokens ( tokens ) ",
- "} ",
- "}"
- );
-
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_substitution() {
- let x = X;
- let tokens = quote!(#x <#x> (#x) [#x] {#x});
-
- let expected = "X < X > ( X ) [ X ] { X }";
-
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_iter() {
- let primes = &[X, X, X, X];
-
- assert_eq!("X X X X", quote!(#(#primes)*).to_string());
-
- assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());
-
- assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
-}
-
-#[test]
-fn test_advanced() {
- let generics = quote!( <'a, T> );
-
- let where_clause = quote!( where T: Serialize );
-
- let field_ty = quote!(String);
-
- let item_ty = quote!(Cow<'a, str>);
-
- let path = quote!(SomeTrait::serialize_with);
-
- let value = quote!(self.x);
-
- let tokens = quote! {
- struct SerializeWith #generics #where_clause {
- value: &'a #field_ty,
- phantom: ::std::marker::PhantomData<#item_ty>,
- }
-
- impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
- fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
- where S: ::serde::Serializer
- {
- #path(self.value, s)
- }
- }
-
- SerializeWith {
- value: #value,
- phantom: ::std::marker::PhantomData::<#item_ty>,
- }
- };
-
- let expected = concat!(
- "struct SerializeWith < 'a , T > where T : Serialize { ",
- "value : & 'a String , ",
- "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
- "} ",
- "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
- "fn serialize < S > ( & self , s : & mut S ) -> Result < ( ) , S :: Error > ",
- "where S : :: serde :: Serializer ",
- "{ ",
- "SomeTrait :: serialize_with ( self . value , s ) ",
- "} ",
- "} ",
- "SerializeWith { ",
- "value : self . x , ",
- "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
- "}"
- );
-
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_integer() {
- let ii8 = -1i8;
- let ii16 = -1i16;
- let ii32 = -1i32;
- let ii64 = -1i64;
- let ii128 = -1i128;
- let iisize = -1isize;
- let uu8 = 1u8;
- let uu16 = 1u16;
- let uu32 = 1u32;
- let uu64 = 1u64;
- let uu128 = 1u128;
- let uusize = 1usize;
-
- let tokens = quote! {
- #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";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_floating() {
- let e32 = 2.345f32;
-
- let e64 = 2.345f64;
-
- let tokens = quote! {
- #e32
- #e64
- };
- let expected = concat!("2.345f32 2.345f64");
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_char() {
- let zero = '\0';
- let pound = '#';
- let quote = '"';
- let apost = '\'';
- let newline = '\n';
- let heart = '\u{2764}';
-
- let tokens = quote! {
- #zero #pound #quote #apost #newline #heart
- };
- let expected = "'\\u{0}' '#' '\"' '\\'' '\\n' '\\u{2764}'";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_str() {
- let s = "\0 a 'b \" c";
- let tokens = quote!(#s);
- let expected = "\"\\u{0} a 'b \\\" c\"";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_string() {
- let s = "\0 a 'b \" c".to_string();
- let tokens = quote!(#s);
- let expected = "\"\\u{0} a 'b \\\" c\"";
- 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());
- let tokens = quote!(struct #foo; enum #bar {});
- let expected = "struct Foo ; enum Bar7 { }";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_duplicate() {
- let ch = 'x';
-
- let tokens = quote!(#ch #ch);
-
- let expected = "'x' 'x'";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_fancy_repetition() {
- let foo = vec!["a", "b"];
- let bar = vec![true, false];
-
- let tokens = quote! {
- #(#foo: #bar),*
- };
-
- let expected = r#""a" : true , "b" : false"#;
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_nested_fancy_repetition() {
- let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];
-
- let tokens = quote! {
- #(
- #(#nested)*
- ),*
- };
-
- let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_duplicate_name_repetition() {
- let foo = &["a", "b"];
-
- let tokens = quote! {
- #(#foo: #foo),*
- #(#foo: #foo),*
- };
-
- let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_duplicate_name_repetition_no_copy() {
- let foo = vec!["a".to_owned(), "b".to_owned()];
-
- let tokens = quote! {
- #(#foo: #foo),*
- };
-
- let expected = r#""a" : "a" , "b" : "b""#;
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_btreeset_repetition() {
- let mut set = BTreeSet::new();
- set.insert("a".to_owned());
- set.insert("b".to_owned());
-
- let tokens = quote! {
- #(#set: #set),*
- };
-
- let expected = r#""a" : "a" , "b" : "b""#;
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_variable_name_conflict() {
- // The implementation of `#(...),*` uses the variable `_i` but it should be
- // fine, if a little confusing when debugging.
- let _i = vec!['a', 'b'];
- let tokens = quote! { #(#_i),* };
- let expected = "'a' , 'b'";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_nonrep_in_repetition() {
- let rep = vec!["a", "b"];
- let nonrep = "c";
-
- let tokens = quote! {
- #(#rep #rep : #nonrep #nonrep),*
- };
-
- let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_empty_quote() {
- let tokens = quote!();
- assert_eq!("", tokens.to_string());
-}
-
-#[test]
-fn test_box_str() {
- let b = "str".to_owned().into_boxed_str();
- let tokens = quote! { #b };
- assert_eq!("\"str\"", tokens.to_string());
-}
-
-#[test]
-fn test_cow() {
- let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));
-
- let ident = Ident::new("borrowed", Span::call_site());
- let borrowed = Cow::Borrowed(&ident);
-
- let tokens = quote! { #owned #borrowed };
- assert_eq!("owned borrowed", tokens.to_string());
-}
-
-#[test]
-fn test_closure() {
- fn field_i(i: usize) -> Ident {
- format_ident!("__field{}", i)
- }
-
- let fields = (0usize..3)
- .map(field_i as fn(_) -> _)
- .map(|var| quote! { #var });
-
- let tokens = quote! { #(#fields)* };
- assert_eq!("__field0 __field1 __field2", tokens.to_string());
-}
-
-#[test]
-fn test_append_tokens() {
- let mut a = quote!(a);
- let b = quote!(b);
- a.append_all(b);
- assert_eq!("a b", a.to_string());
-}
-
-#[test]
-fn test_format_ident() {
- let id0 = format_ident!("Aa");
- let id1 = format_ident!("Hello{x}", x = id0);
- let id2 = format_ident!("Hello{x}", x = 5usize);
- let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
- let id4 = format_ident!("Aa", span = Span::call_site());
-
- assert_eq!(id0, "Aa");
- assert_eq!(id1, "HelloAa");
- assert_eq!(id2, "Hello5");
- assert_eq!(id3, "HelloAa_10");
- assert_eq!(id4, "Aa");
-}
-
-#[test]
-fn test_format_ident_strip_raw() {
- let id = format_ident!("r#struct");
- let my_id = format_ident!("MyId{}", id);
- let raw_my_id = format_ident!("r#MyId{}", id);
-
- assert_eq!(id, "r#struct");
- assert_eq!(my_id, "MyIdstruct");
- assert_eq!(raw_my_id, "r#MyIdstruct");
-}
-
-#[test]
-fn test_outer_line_comment() {
- let tokens = quote! {
- /// doc
- };
- let expected = "# [ doc = r\" doc\" ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_inner_line_comment() {
- let tokens = quote! {
- //! doc
- };
- let expected = "# ! [ doc = r\" doc\" ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_outer_block_comment() {
- let tokens = quote! {
- /** doc */
- };
- let expected = "# [ doc = r\" doc \" ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_inner_block_comment() {
- let tokens = quote! {
- /*! doc */
- };
- let expected = "# ! [ doc = r\" doc \" ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_outer_attr() {
- let tokens = quote! {
- #[inline]
- };
- let expected = "# [ inline ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-#[test]
-fn test_inner_attr() {
- let tokens = quote! {
- #![no_std]
- };
- let expected = "# ! [ no_std ]";
- assert_eq!(expected, tokens.to_string());
-}
-
-// https://github.com/dtolnay/quote/issues/130
-#[test]
-fn test_star_after_repetition() {
- let c = vec!['0', '1'];
- let tokens = quote! {
- #(
- f(#c);
- )*
- *out = None;
- };
- let expected = "f ( '0' ) ; f ( '1' ) ; * out = None ;";
- assert_eq!(expected, tokens.to_string());
-}
diff --git a/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
deleted file mode 100644
index 0a39f41..0000000
--- a/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use quote::quote;
-
-fn main() {
- let nonrep = "";
-
- // Without some protection against repetitions with no iterator somewhere
- // inside, this would loop infinitely.
- quote!(#(#nonrep #nonrep)*);
-}
diff --git a/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
deleted file mode 100644
index 6ee6fdf..0000000
--- a/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/does-not-have-iter-interpolated-dup.rs:8:5
- |
-8 | quote!(#(#nonrep #nonrep)*);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `quote::__rt::HasIterator`, found struct `quote::__rt::ThereIsNoIteratorInRepetition`
- |
- = note: expected type `quote::__rt::HasIterator`
- found type `quote::__rt::ThereIsNoIteratorInRepetition`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/quote/tests/ui/does-not-have-iter-interpolated.rs b/quote/tests/ui/does-not-have-iter-interpolated.rs
deleted file mode 100644
index 2c740cc..0000000
--- a/quote/tests/ui/does-not-have-iter-interpolated.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-use quote::quote;
-
-fn main() {
- let nonrep = "";
-
- // Without some protection against repetitions with no iterator somewhere
- // inside, this would loop infinitely.
- quote!(#(#nonrep)*);
-}
diff --git a/quote/tests/ui/does-not-have-iter-interpolated.stderr b/quote/tests/ui/does-not-have-iter-interpolated.stderr
deleted file mode 100644
index 8d6c990..0000000
--- a/quote/tests/ui/does-not-have-iter-interpolated.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/does-not-have-iter-interpolated.rs:8:5
- |
-8 | quote!(#(#nonrep)*);
- | ^^^^^^^^^^^^^^^^^^^^ expected struct `quote::__rt::HasIterator`, found struct `quote::__rt::ThereIsNoIteratorInRepetition`
- |
- = note: expected type `quote::__rt::HasIterator`
- found type `quote::__rt::ThereIsNoIteratorInRepetition`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/quote/tests/ui/does-not-have-iter-separated.rs b/quote/tests/ui/does-not-have-iter-separated.rs
deleted file mode 100644
index c027243..0000000
--- a/quote/tests/ui/does-not-have-iter-separated.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use quote::quote;
-
-fn main() {
- quote!(#(a b),*);
-}
diff --git a/quote/tests/ui/does-not-have-iter-separated.stderr b/quote/tests/ui/does-not-have-iter-separated.stderr
deleted file mode 100644
index c1fd0ad..0000000
--- a/quote/tests/ui/does-not-have-iter-separated.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/does-not-have-iter-separated.rs:4:5
- |
-4 | quote!(#(a b),*);
- | ^^^^^^^^^^^^^^^^^ expected struct `quote::__rt::HasIterator`, found struct `quote::__rt::ThereIsNoIteratorInRepetition`
- |
- = note: expected type `quote::__rt::HasIterator`
- found type `quote::__rt::ThereIsNoIteratorInRepetition`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/quote/tests/ui/does-not-have-iter.rs b/quote/tests/ui/does-not-have-iter.rs
deleted file mode 100644
index 8908353..0000000
--- a/quote/tests/ui/does-not-have-iter.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use quote::quote;
-
-fn main() {
- quote!(#(a b)*);
-}
diff --git a/quote/tests/ui/does-not-have-iter.stderr b/quote/tests/ui/does-not-have-iter.stderr
deleted file mode 100644
index 3b87705..0000000
--- a/quote/tests/ui/does-not-have-iter.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/does-not-have-iter.rs:4:5
- |
-4 | quote!(#(a b)*);
- | ^^^^^^^^^^^^^^^^ expected struct `quote::__rt::HasIterator`, found struct `quote::__rt::ThereIsNoIteratorInRepetition`
- |
- = note: expected type `quote::__rt::HasIterator`
- found type `quote::__rt::ThereIsNoIteratorInRepetition`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/quote/tests/ui/not-quotable.rs b/quote/tests/ui/not-quotable.rs
deleted file mode 100644
index f991c18..0000000
--- a/quote/tests/ui/not-quotable.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use quote::quote;
-use std::net::Ipv4Addr;
-
-fn main() {
- let ip = Ipv4Addr::LOCALHOST;
- let _ = quote! { #ip };
-}
diff --git a/quote/tests/ui/not-quotable.stderr b/quote/tests/ui/not-quotable.stderr
deleted file mode 100644
index f51f85f..0000000
--- a/quote/tests/ui/not-quotable.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error[E0277]: the trait bound `std::net::Ipv4Addr: quote::to_tokens::ToTokens` is not satisfied
- --> $DIR/not-quotable.rs:6:13
- |
-6 | let _ = quote! { #ip };
- | ^^^^^^^^^^^^^^ the trait `quote::to_tokens::ToTokens` is not implemented for `std::net::Ipv4Addr`
- |
- = note: required by `quote::to_tokens::ToTokens::to_tokens`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/quote/tests/ui/not-repeatable.rs b/quote/tests/ui/not-repeatable.rs
deleted file mode 100644
index ff18060..0000000
--- a/quote/tests/ui/not-repeatable.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use quote::quote;
-use std::net::Ipv4Addr;
-
-fn main() {
- let ip = Ipv4Addr::LOCALHOST;
- let _ = quote! { #(#ip)* };
-}
diff --git a/quote/tests/ui/not-repeatable.stderr b/quote/tests/ui/not-repeatable.stderr
deleted file mode 100644
index ddcac05..0000000
--- a/quote/tests/ui/not-repeatable.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0599]: no method named `quote_into_iter` found for type `std::net::Ipv4Addr` in the current scope
- --> $DIR/not-repeatable.rs:6:13
- |
-6 | let _ = quote! { #(#ip)* };
- | ^^^^^^^^^^^^^^^^^^
- |
- = note: the method `quote_into_iter` exists but the following trait bounds were not satisfied:
- `&mut std::net::Ipv4Addr : quote::__rt::ext::RepIteratorExt`
- `&std::net::Ipv4Addr : quote::__rt::ext::RepIteratorExt`
- `std::net::Ipv4Addr : quote::__rt::ext::RepIteratorExt`
- `std::net::Ipv4Addr : quote::__rt::ext::RepToTokensExt`
- = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/quote/tests/ui/wrong-type-span.rs b/quote/tests/ui/wrong-type-span.rs
deleted file mode 100644
index 1ce391c..0000000
--- a/quote/tests/ui/wrong-type-span.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use quote::quote_spanned;
-
-fn main() {
- let span = "";
- let x = 0;
- quote_spanned!(span=> #x);
-}
diff --git a/quote/tests/ui/wrong-type-span.stderr b/quote/tests/ui/wrong-type-span.stderr
deleted file mode 100644
index a6ae8ef..0000000
--- a/quote/tests/ui/wrong-type-span.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error[E0308]: mismatched types
- --> $DIR/wrong-type-span.rs:6:20
- |
-6 | quote_spanned!(span=> #x);
- | ^^^^ expected struct `proc_macro2::Span`, found &str
- |
- = note: expected type `proc_macro2::Span`
- found type `&str`
-
-For more information about this error, try `rustc --explain E0308`.