更新libclamav库1.0.0版本
This commit is contained in:
1
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/.cargo-checksum.json
vendored
Normal file
1
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/.cargo-checksum.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"ae1169ef7f2dc32d4b461732284ad5d66019fd3d2a5897254c240759b61e675d","LICENSE-APACHE":"0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/lib.rs":"3c1b4ae774d0c05d74997e5f88fe43d95162df14f5eaf6ebbf03ca92b2ebdf7d","src/pin_project/args.rs":"903be7b22a2eda4ed59d890feb75bd4c98e243b4faaa809aff0621d15cd06431","src/pin_project/attribute.rs":"3e392493e875f0c935525579ba9bd888d8e00b57b3d6594b7fde040c31790784","src/pin_project/derive.rs":"0060e78285d89f5807126eb7f3d8a721dd4592a9e070ca0cda2f6cf2bf34e27b","src/pin_project/mod.rs":"83e6fc982a8c136811332512abc7d368e5d09b94f245de5d19490f835e85943a","src/pinned_drop.rs":"f3d386e00ce2fe25fc817ac57f07569f9e43a519e12d977db39f4c239be4dcf4","src/utils.rs":"24372d39be74fb9b6728bca08d74ed0a8ed7915de97ada6b20ebb6243ae6eed0"},"package":"069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"}
|
||||
51
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/Cargo.toml
vendored
Normal file
51
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/Cargo.toml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.37"
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.12"
|
||||
description = """
|
||||
Implementation detail of the `pin-project` crate.
|
||||
"""
|
||||
keywords = [
|
||||
"pin",
|
||||
"macros",
|
||||
"attribute",
|
||||
]
|
||||
categories = [
|
||||
"no-std",
|
||||
"rust-patterns",
|
||||
]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/taiki-e/pin-project"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1"
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "1.0.56"
|
||||
features = [
|
||||
"full",
|
||||
"visit-mut",
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
177
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/LICENSE-APACHE
vendored
Normal file
177
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/LICENSE-APACHE
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
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
|
||||
23
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/LICENSE-MIT
vendored
Normal file
23
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/LICENSE-MIT
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
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.
|
||||
584
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/lib.rs
vendored
Normal file
584
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/lib.rs
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
//! Implementation detail of the `pin-project` crate. - **do not use directly**
|
||||
|
||||
#![doc(test(
|
||||
no_crate_inject,
|
||||
attr(
|
||||
deny(warnings, rust_2018_idioms, single_use_lifetimes),
|
||||
allow(dead_code, unused_variables)
|
||||
)
|
||||
))]
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::needless_doctest_main,
|
||||
clippy::similar_names,
|
||||
clippy::single_match_else,
|
||||
clippy::too_many_lines,
|
||||
clippy::unnested_or_patterns
|
||||
)]
|
||||
|
||||
// older compilers require explicit `extern crate`.
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate proc_macro;
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
|
||||
mod pin_project;
|
||||
mod pinned_drop;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// An attribute that creates projection types covering all the fields of
|
||||
/// struct or enum.
|
||||
///
|
||||
/// This attribute creates projection types according to the following rules:
|
||||
///
|
||||
/// - For the fields that use `#[pin]` attribute, create the pinned reference to
|
||||
/// the field.
|
||||
/// - For the other fields, create a normal reference to the field.
|
||||
///
|
||||
/// And the following methods are implemented on the original type:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::pin::Pin;
|
||||
/// # type Projection<'a> = &'a ();
|
||||
/// # type ProjectionRef<'a> = &'a ();
|
||||
/// # trait Dox {
|
||||
/// fn project(self: Pin<&mut Self>) -> Projection<'_>;
|
||||
/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// By passing an argument with the same name as the method to the attribute,
|
||||
/// you can name the projection type returned from the method. This allows you
|
||||
/// to use pattern matching on the projected types.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pin_project::pin_project;
|
||||
/// # use std::pin::Pin;
|
||||
/// #[pin_project(project = EnumProj)]
|
||||
/// enum Enum<T> {
|
||||
/// Variant(#[pin] T),
|
||||
/// }
|
||||
///
|
||||
/// impl<T> Enum<T> {
|
||||
/// fn method(self: Pin<&mut Self>) {
|
||||
/// let this: EnumProj<'_, T> = self.project();
|
||||
/// match this {
|
||||
/// EnumProj::Variant(x) => {
|
||||
/// let _: Pin<&mut T> = x;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that the projection types returned by `project` and `project_ref` have
|
||||
/// an additional lifetime at the beginning of generics.
|
||||
///
|
||||
/// ```text
|
||||
/// let this: EnumProj<'_, T> = self.project();
|
||||
/// ^^
|
||||
/// ```
|
||||
///
|
||||
/// The visibility of the projected types and projection methods is based on the
|
||||
/// original type. However, if the visibility of the original type is `pub`, the
|
||||
/// visibility of the projected types and the projection methods is downgraded
|
||||
/// to `pub(crate)`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This attribute is completely safe. In the absence of other `unsafe` code
|
||||
/// *that you write*, it is impossible to cause [undefined
|
||||
/// behavior][undefined-behavior] with this attribute.
|
||||
///
|
||||
/// This is accomplished by enforcing the four requirements for pin projection
|
||||
/// stated in [the Rust documentation][pin-projection]:
|
||||
///
|
||||
/// 1. The struct must only be [`Unpin`] if all the structural fields are
|
||||
/// [`Unpin`].
|
||||
///
|
||||
/// To enforce this, this attribute will automatically generate an [`Unpin`]
|
||||
/// implementation for you, which will require that all structurally pinned
|
||||
/// fields be [`Unpin`].
|
||||
///
|
||||
/// If you attempt to provide an [`Unpin`] impl, the blanket impl will then
|
||||
/// apply to your type, causing a compile-time error due to the conflict with
|
||||
/// the second impl.
|
||||
///
|
||||
/// If you wish to provide a manual [`Unpin`] impl, you can do so via the
|
||||
/// [`UnsafeUnpin`][unsafe-unpin] argument.
|
||||
///
|
||||
/// 2. The destructor of the struct must not move structural fields out of its
|
||||
/// argument.
|
||||
///
|
||||
/// To enforce this, this attribute will generate code like this:
|
||||
///
|
||||
/// ```rust
|
||||
/// struct MyStruct {}
|
||||
/// trait MyStructMustNotImplDrop {}
|
||||
/// # #[allow(unknown_lints, drop_bounds)]
|
||||
/// impl<T: Drop> MyStructMustNotImplDrop for T {}
|
||||
/// impl MyStructMustNotImplDrop for MyStruct {}
|
||||
/// ```
|
||||
///
|
||||
/// If you attempt to provide an [`Drop`] impl, the blanket impl will then
|
||||
/// apply to your type, causing a compile-time error due to the conflict with
|
||||
/// the second impl.
|
||||
///
|
||||
/// If you wish to provide a custom [`Drop`] impl, you can annotate an impl
|
||||
/// with [`#[pinned_drop]`][pinned-drop]. This impl takes a pinned version of
|
||||
/// your struct - that is, [`Pin`]`<&mut MyStruct>` where `MyStruct` is the
|
||||
/// type of your struct.
|
||||
///
|
||||
/// You can call `.project()` on this type as usual, along with any other
|
||||
/// methods you have defined. Because your code is never provided with
|
||||
/// a `&mut MyStruct`, it is impossible to move out of pin-projectable
|
||||
/// fields in safe code in your destructor.
|
||||
///
|
||||
/// 3. You must make sure that you uphold the [`Drop`
|
||||
/// guarantee][drop-guarantee]: once your struct is pinned, the memory that
|
||||
/// contains the content is not overwritten or deallocated without calling
|
||||
/// the content's destructors.
|
||||
///
|
||||
/// Safe code doesn't need to worry about this - the only way to violate
|
||||
/// this requirement is to manually deallocate memory (which is `unsafe`),
|
||||
/// or to overwrite a field with something else.
|
||||
/// Because your custom destructor takes [`Pin`]`<&mut MyStruct>`, it's
|
||||
/// impossible to obtain a mutable reference to a pin-projected field in safe
|
||||
/// code.
|
||||
///
|
||||
/// 4. You must not offer any other operations that could lead to data being
|
||||
/// moved out of the structural fields when your type is pinned.
|
||||
///
|
||||
/// As with requirement 3, it is impossible for safe code to violate this.
|
||||
/// This crate ensures that safe code can never obtain a mutable reference to
|
||||
/// `#[pin]` fields, which prevents you from ever moving out of them in safe
|
||||
/// code.
|
||||
///
|
||||
/// Pin projections are also incompatible with [`#[repr(packed)]`][repr-packed]
|
||||
/// types. Attempting to use this attribute on a `#[repr(packed)]` type results
|
||||
/// in a compile-time error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `#[pin_project]` can be used on structs and enums.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project]
|
||||
/// struct Struct<T, U> {
|
||||
/// #[pin]
|
||||
/// pinned: T,
|
||||
/// unpinned: U,
|
||||
/// }
|
||||
///
|
||||
/// impl<T, U> Struct<T, U> {
|
||||
/// fn method(self: Pin<&mut Self>) {
|
||||
/// let this = self.project();
|
||||
/// let _: Pin<&mut T> = this.pinned;
|
||||
/// let _: &mut U = this.unpinned;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project]
|
||||
/// struct TupleStruct<T, U>(#[pin] T, U);
|
||||
///
|
||||
/// impl<T, U> TupleStruct<T, U> {
|
||||
/// fn method(self: Pin<&mut Self>) {
|
||||
/// let this = self.project();
|
||||
/// let _: Pin<&mut T> = this.0;
|
||||
/// let _: &mut U = this.1;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// To use `#[pin_project]` on enums, you need to name the projection type
|
||||
/// returned from the method.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project(project = EnumProj)]
|
||||
/// enum Enum<T, U> {
|
||||
/// Tuple(#[pin] T),
|
||||
/// Struct { field: U },
|
||||
/// Unit,
|
||||
/// }
|
||||
///
|
||||
/// impl<T, U> Enum<T, U> {
|
||||
/// fn method(self: Pin<&mut Self>) {
|
||||
/// match self.project() {
|
||||
/// EnumProj::Tuple(x) => {
|
||||
/// let _: Pin<&mut T> = x;
|
||||
/// }
|
||||
/// EnumProj::Struct { field } => {
|
||||
/// let _: &mut U = field;
|
||||
/// }
|
||||
/// EnumProj::Unit => {}
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When `#[pin_project]` is used on enums, only named projection types and
|
||||
/// methods are generated because there is no way to access variants of
|
||||
/// projected types without naming it.
|
||||
/// For example, in the above example, only the `project` method is generated,
|
||||
/// and the `project_ref` method is not generated.
|
||||
/// (When `#[pin_project]` is used on structs, both methods are always generated.)
|
||||
///
|
||||
/// ```rust,compile_fail,E0599
|
||||
/// # use pin_project::pin_project;
|
||||
/// # use std::pin::Pin;
|
||||
/// #
|
||||
/// # #[pin_project(project = EnumProj)]
|
||||
/// # enum Enum<T, U> {
|
||||
/// # Tuple(#[pin] T),
|
||||
/// # Struct { field: U },
|
||||
/// # Unit,
|
||||
/// # }
|
||||
/// #
|
||||
/// impl<T, U> Enum<T, U> {
|
||||
/// fn call_project_ref(self: Pin<&Self>) {
|
||||
/// let _this = self.project_ref();
|
||||
/// //~^ ERROR no method named `project_ref` found for struct `Pin<&Enum<T, U>>` in the current scope
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If you want to call `.project()` multiple times or later use the
|
||||
/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
|
||||
/// consuming the [`Pin`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project]
|
||||
/// struct Struct<T> {
|
||||
/// #[pin]
|
||||
/// field: T,
|
||||
/// }
|
||||
///
|
||||
/// impl<T> Struct<T> {
|
||||
/// fn call_project_twice(mut self: Pin<&mut Self>) {
|
||||
/// // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
|
||||
/// self.as_mut().project();
|
||||
/// self.as_mut().project();
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # `!Unpin`
|
||||
///
|
||||
/// If you want to ensure that [`Unpin`] is not implemented, use the `!Unpin`
|
||||
/// argument to `#[pin_project]`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project(!Unpin)]
|
||||
/// struct Struct<T> {
|
||||
/// field: T,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This is equivalent to using `#[pin]` attribute for the [`PhantomPinned`]
|
||||
/// field.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::marker::PhantomPinned;
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project]
|
||||
/// struct Struct<T> {
|
||||
/// field: T,
|
||||
/// #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`.
|
||||
/// _pin: PhantomPinned,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Note that using [`PhantomPinned`] without `#[pin]` attribute has no effect.
|
||||
///
|
||||
/// # `UnsafeUnpin`
|
||||
///
|
||||
/// If you want to implement [`Unpin`] manually, you must use the `UnsafeUnpin`
|
||||
/// argument to `#[pin_project]`.
|
||||
///
|
||||
/// ```rust
|
||||
/// use pin_project::{pin_project, UnsafeUnpin};
|
||||
///
|
||||
/// #[pin_project(UnsafeUnpin)]
|
||||
/// struct Struct<T, U> {
|
||||
/// #[pin]
|
||||
/// pinned: T,
|
||||
/// unpinned: U,
|
||||
/// }
|
||||
///
|
||||
/// unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {}
|
||||
/// ```
|
||||
///
|
||||
/// Note the usage of the unsafe [`UnsafeUnpin`] trait, instead of the usual
|
||||
/// [`Unpin`] trait. [`UnsafeUnpin`] behaves exactly like [`Unpin`], except that
|
||||
/// is unsafe to implement. This unsafety comes from the fact that pin
|
||||
/// projections are being used. If you implement [`UnsafeUnpin`], you must
|
||||
/// ensure that it is only implemented when all pin-projected fields implement
|
||||
/// [`Unpin`].
|
||||
///
|
||||
/// See [`UnsafeUnpin`] trait for more details.
|
||||
///
|
||||
/// # `#[pinned_drop]`
|
||||
///
|
||||
/// In order to correctly implement pin projections, a type's [`Drop`] impl must
|
||||
/// not move out of any structurally pinned fields. Unfortunately,
|
||||
/// [`Drop::drop`] takes `&mut Self`, not [`Pin`]`<&mut Self>`.
|
||||
///
|
||||
/// To ensure that this requirement is upheld, the `#[pin_project]` attribute
|
||||
/// will provide a [`Drop`] impl for you. This [`Drop`] impl will delegate to
|
||||
/// an impl block annotated with `#[pinned_drop]` if you use the `PinnedDrop`
|
||||
/// argument to `#[pin_project]`.
|
||||
///
|
||||
/// This impl block acts just like a normal [`Drop`] impl,
|
||||
/// except for the following two:
|
||||
///
|
||||
/// - `drop` method takes [`Pin`]`<&mut Self>`
|
||||
/// - Name of the trait is `PinnedDrop`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::pin::Pin;
|
||||
/// pub trait PinnedDrop {
|
||||
/// fn drop(self: Pin<&mut Self>);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you
|
||||
/// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`]
|
||||
/// function just like dropping a type that directly implements [`Drop`].
|
||||
///
|
||||
/// In particular, it will never be called more than once, just like
|
||||
/// [`Drop::drop`].
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::{fmt::Debug, pin::Pin};
|
||||
///
|
||||
/// use pin_project::{pin_project, pinned_drop};
|
||||
///
|
||||
/// #[pin_project(PinnedDrop)]
|
||||
/// struct PrintOnDrop<T: Debug, U: Debug> {
|
||||
/// #[pin]
|
||||
/// pinned_field: T,
|
||||
/// unpin_field: U,
|
||||
/// }
|
||||
///
|
||||
/// #[pinned_drop]
|
||||
/// impl<T: Debug, U: Debug> PinnedDrop for PrintOnDrop<T, U> {
|
||||
/// fn drop(self: Pin<&mut Self>) {
|
||||
/// println!("Dropping pinned field: {:?}", self.pinned_field);
|
||||
/// println!("Dropping unpin field: {:?}", self.unpin_field);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let _x = PrintOnDrop { pinned_field: true, unpin_field: 40 };
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// See also [`#[pinned_drop]`][macro@pinned_drop] attribute.
|
||||
///
|
||||
/// # `project_replace` method
|
||||
///
|
||||
/// In addition to the `project` and `project_ref` methods which are always
|
||||
/// provided when you use the `#[pin_project]` attribute, there is a third
|
||||
/// method, `project_replace` which can be useful in some situations. It is
|
||||
/// equivalent to [`Pin::set`], except that the unpinned fields are moved and
|
||||
/// returned, instead of being dropped in-place.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::pin::Pin;
|
||||
/// # type ProjectionOwned = ();
|
||||
/// # trait Dox {
|
||||
/// fn project_replace(self: Pin<&mut Self>, other: Self) -> ProjectionOwned;
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// The `ProjectionOwned` type is identical to the `Self` type, except that
|
||||
/// all pinned fields have been replaced by equivalent [`PhantomData`] types.
|
||||
///
|
||||
/// This method is opt-in, because it is only supported for [`Sized`] types, and
|
||||
/// because it is incompatible with the [`#[pinned_drop]`][pinned-drop]
|
||||
/// attribute described above. It can be enabled by using
|
||||
/// `#[pin_project(project_replace)]`.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::{marker::PhantomData, pin::Pin};
|
||||
///
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project(project_replace)]
|
||||
/// struct Struct<T, U> {
|
||||
/// #[pin]
|
||||
/// pinned_field: T,
|
||||
/// unpinned_field: U,
|
||||
/// }
|
||||
///
|
||||
/// impl<T, U> Struct<T, U> {
|
||||
/// fn method(self: Pin<&mut Self>, other: Self) {
|
||||
/// let this = self.project_replace(other);
|
||||
/// let _: U = this.unpinned_field;
|
||||
/// let _: PhantomData<T> = this.pinned_field;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// By passing the value to the `project_replace` argument, you can name the
|
||||
/// returned type of the `project_replace` method. This is necessary whenever
|
||||
/// destructuring the return type of the `project_replace` method, and work in exactly
|
||||
/// the same way as the `project` and `project_ref` arguments.
|
||||
///
|
||||
/// ```rust
|
||||
/// use pin_project::pin_project;
|
||||
///
|
||||
/// #[pin_project(project_replace = EnumProjOwn)]
|
||||
/// enum Enum<T, U> {
|
||||
/// A {
|
||||
/// #[pin]
|
||||
/// pinned_field: T,
|
||||
/// unpinned_field: U,
|
||||
/// },
|
||||
/// B,
|
||||
/// }
|
||||
///
|
||||
/// let mut x = Box::pin(Enum::A { pinned_field: 42, unpinned_field: "hello" });
|
||||
///
|
||||
/// match x.as_mut().project_replace(Enum::B) {
|
||||
/// EnumProjOwn::A { unpinned_field, .. } => assert_eq!(unpinned_field, "hello"),
|
||||
/// EnumProjOwn::B => unreachable!(),
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`PhantomData`]: core::marker::PhantomData
|
||||
/// [`PhantomPinned`]: core::marker::PhantomPinned
|
||||
/// [`Pin::as_mut`]: core::pin::Pin::as_mut
|
||||
/// [`Pin::set`]: core::pin::Pin::set
|
||||
/// [`Pin`]: core::pin::Pin
|
||||
/// [`UnsafeUnpin`]: https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html
|
||||
/// [drop-guarantee]: core::pin#drop-guarantee
|
||||
/// [pin-projection]: core::pin#projections-and-structural-pinning
|
||||
/// [pinned-drop]: macro@pin_project#pinned_drop
|
||||
/// [repr-packed]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked
|
||||
/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
|
||||
/// [unsafe-unpin]: macro@pin_project#unsafeunpin
|
||||
#[proc_macro_attribute]
|
||||
pub fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
pin_project::attribute(&args.into(), input.into()).into()
|
||||
}
|
||||
|
||||
/// An attribute used for custom implementations of [`Drop`].
|
||||
///
|
||||
/// This attribute is used in conjunction with the `PinnedDrop` argument to
|
||||
/// the [`#[pin_project]`][macro@pin_project] attribute.
|
||||
///
|
||||
/// The impl block annotated with this attribute acts just like a normal
|
||||
/// [`Drop`] impl, except for the following two:
|
||||
///
|
||||
/// - `drop` method takes [`Pin`]`<&mut Self>`
|
||||
/// - Name of the trait is `PinnedDrop`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::pin::Pin;
|
||||
/// pub trait PinnedDrop {
|
||||
/// fn drop(self: Pin<&mut Self>);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you
|
||||
/// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`]
|
||||
/// function just like dropping a type that directly implements [`Drop`].
|
||||
///
|
||||
/// In particular, it will never be called more than once, just like
|
||||
/// [`Drop::drop`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::pin::Pin;
|
||||
///
|
||||
/// use pin_project::{pin_project, pinned_drop};
|
||||
///
|
||||
/// #[pin_project(PinnedDrop)]
|
||||
/// struct PrintOnDrop {
|
||||
/// #[pin]
|
||||
/// field: u8,
|
||||
/// }
|
||||
///
|
||||
/// #[pinned_drop]
|
||||
/// impl PinnedDrop for PrintOnDrop {
|
||||
/// fn drop(self: Pin<&mut Self>) {
|
||||
/// println!("Dropping: {}", self.field);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let _x = PrintOnDrop { field: 50 };
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// See also ["pinned-drop" section of `#[pin_project]` attribute][pinned-drop].
|
||||
///
|
||||
/// # Why `#[pinned_drop]` attribute is needed?
|
||||
///
|
||||
/// Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
|
||||
/// This is because destructors can be called multiple times in safe code and
|
||||
/// [double dropping is unsound][rust-lang/rust#62360].
|
||||
///
|
||||
/// Ideally, it would be desirable to be able to forbid manual calls in
|
||||
/// the same way as [`Drop::drop`], but the library cannot do it. So, by using
|
||||
/// macros and replacing them with private traits like the following,
|
||||
/// this crate prevent users from calling `PinnedDrop::drop` in safe code.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::pin::Pin;
|
||||
/// pub trait PinnedDrop {
|
||||
/// unsafe fn drop(self: Pin<&mut Self>);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// This allows implementing [`Drop`] safely using `#[pinned_drop]`.
|
||||
/// Also by using the [`drop`] function just like dropping a type that directly
|
||||
/// implements [`Drop`], can drop safely a type that implements `PinnedDrop`.
|
||||
///
|
||||
/// [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360
|
||||
/// [`Pin`]: core::pin::Pin
|
||||
/// [pinned-drop]: macro@pin_project#pinned_drop
|
||||
#[proc_macro_attribute]
|
||||
pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let input = syn::parse_macro_input!(input);
|
||||
pinned_drop::attribute(&args.into(), input).into()
|
||||
}
|
||||
|
||||
// Not public API.
|
||||
#[doc(hidden)]
|
||||
#[proc_macro_derive(__PinProjectInternalDerive, attributes(pin))]
|
||||
pub fn __pin_project_internal_derive(input: TokenStream) -> TokenStream {
|
||||
pin_project::derive(input.into()).into()
|
||||
}
|
||||
254
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/args.rs
vendored
Normal file
254
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/args.rs
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
spanned::Spanned,
|
||||
Attribute, Error, Ident, Result, Token,
|
||||
};
|
||||
|
||||
use super::PIN;
|
||||
use crate::utils::{ParseBufferExt, SliceExt};
|
||||
|
||||
pub(super) fn parse_args(attrs: &[Attribute]) -> Result<Args> {
|
||||
// `(__private(<args>))` -> `<args>`
|
||||
struct Input(Option<TokenStream>);
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||
Ok(Self((|| {
|
||||
let content = input.parenthesized().ok()?;
|
||||
let private = content.parse::<Ident>().ok()?;
|
||||
if private == "__private" {
|
||||
content.parenthesized().ok()?.parse::<TokenStream>().ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})()))
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(attr) = attrs.find("pin_project") {
|
||||
bail!(attr, "duplicate #[pin_project] attribute");
|
||||
}
|
||||
|
||||
let mut attrs = attrs.iter().filter(|attr| attr.path.is_ident(PIN));
|
||||
|
||||
let prev = if let Some(attr) = attrs.next() {
|
||||
(attr, syn::parse2::<Input>(attr.tokens.clone()).unwrap().0)
|
||||
} else {
|
||||
// This only fails if another macro removes `#[pin]`.
|
||||
bail!(TokenStream::new(), "#[pin_project] attribute has been removed");
|
||||
};
|
||||
|
||||
if let Some(attr) = attrs.next() {
|
||||
let (prev_attr, prev_res) = &prev;
|
||||
// As the `#[pin]` attribute generated by `#[pin_project]`
|
||||
// has the same span as `#[pin_project]`, it is possible
|
||||
// that a useless error message will be generated.
|
||||
// So, use the span of `prev_attr` if it is not a valid attribute.
|
||||
let res = syn::parse2::<Input>(attr.tokens.clone()).unwrap().0;
|
||||
let span = match (prev_res, res) {
|
||||
(Some(_), _) => attr,
|
||||
(None, _) => prev_attr,
|
||||
};
|
||||
bail!(span, "duplicate #[pin] attribute");
|
||||
}
|
||||
// This `unwrap` only fails if another macro removes `#[pin]` and inserts own `#[pin]`.
|
||||
syn::parse2(prev.1.unwrap())
|
||||
}
|
||||
|
||||
pub(super) struct Args {
|
||||
/// `PinnedDrop` argument.
|
||||
pub(super) pinned_drop: Option<Span>,
|
||||
/// `UnsafeUnpin` or `!Unpin` argument.
|
||||
pub(super) unpin_impl: UnpinImpl,
|
||||
/// `project = <ident>` argument.
|
||||
pub(super) project: Option<Ident>,
|
||||
/// `project_ref = <ident>` argument.
|
||||
pub(super) project_ref: Option<Ident>,
|
||||
/// `project_replace [= <ident>]` argument.
|
||||
pub(super) project_replace: ProjReplace,
|
||||
}
|
||||
|
||||
impl Parse for Args {
|
||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||
mod kw {
|
||||
syn::custom_keyword!(Unpin);
|
||||
}
|
||||
|
||||
/// Parses `= <value>` in `<name> = <value>` and returns value and span of name-value pair.
|
||||
fn parse_value(
|
||||
input: ParseStream<'_>,
|
||||
name: &Ident,
|
||||
has_prev: bool,
|
||||
) -> Result<(Ident, TokenStream)> {
|
||||
if input.is_empty() {
|
||||
bail!(name, "expected `{0} = <identifier>`, found `{0}`", name);
|
||||
}
|
||||
let eq_token: Token![=] = input.parse()?;
|
||||
if input.is_empty() {
|
||||
let span = quote!(#name #eq_token);
|
||||
bail!(span, "expected `{0} = <identifier>`, found `{0} =`", name);
|
||||
}
|
||||
let value: Ident = input.parse()?;
|
||||
let span = quote!(#name #value);
|
||||
if has_prev {
|
||||
bail!(span, "duplicate `{}` argument", name);
|
||||
}
|
||||
Ok((value, span))
|
||||
}
|
||||
|
||||
let mut pinned_drop = None;
|
||||
let mut unsafe_unpin = None;
|
||||
let mut not_unpin = None;
|
||||
let mut project = None;
|
||||
let mut project_ref = None;
|
||||
let mut project_replace_value = None;
|
||||
let mut project_replace_span = None;
|
||||
|
||||
while !input.is_empty() {
|
||||
if input.peek(Token![!]) {
|
||||
let bang: Token![!] = input.parse()?;
|
||||
if input.is_empty() {
|
||||
bail!(bang, "expected `!Unpin`, found `!`");
|
||||
}
|
||||
let unpin: kw::Unpin = input.parse()?;
|
||||
let span = quote!(#bang #unpin);
|
||||
if not_unpin.replace(span.span()).is_some() {
|
||||
bail!(span, "duplicate `!Unpin` argument");
|
||||
}
|
||||
} else {
|
||||
let token = input.parse::<Ident>()?;
|
||||
match &*token.to_string() {
|
||||
"PinnedDrop" => {
|
||||
if pinned_drop.replace(token.span()).is_some() {
|
||||
bail!(token, "duplicate `PinnedDrop` argument");
|
||||
}
|
||||
}
|
||||
"UnsafeUnpin" => {
|
||||
if unsafe_unpin.replace(token.span()).is_some() {
|
||||
bail!(token, "duplicate `UnsafeUnpin` argument");
|
||||
}
|
||||
}
|
||||
"project" => {
|
||||
project = Some(parse_value(input, &token, project.is_some())?.0);
|
||||
}
|
||||
"project_ref" => {
|
||||
project_ref = Some(parse_value(input, &token, project_ref.is_some())?.0);
|
||||
}
|
||||
"project_replace" => {
|
||||
if input.peek(Token![=]) {
|
||||
let (value, span) =
|
||||
parse_value(input, &token, project_replace_span.is_some())?;
|
||||
project_replace_value = Some(value);
|
||||
project_replace_span = Some(span.span());
|
||||
} else if project_replace_span.is_some() {
|
||||
bail!(token, "duplicate `project_replace` argument");
|
||||
} else {
|
||||
project_replace_span = Some(token.span());
|
||||
}
|
||||
}
|
||||
"Replace" => {
|
||||
bail!(
|
||||
token,
|
||||
"`Replace` argument was removed, use `project_replace` argument instead"
|
||||
);
|
||||
}
|
||||
_ => bail!(token, "unexpected argument: {}", token),
|
||||
}
|
||||
}
|
||||
|
||||
if input.is_empty() {
|
||||
break;
|
||||
}
|
||||
let _: Token![,] = input.parse()?;
|
||||
}
|
||||
|
||||
if project.is_some() || project_ref.is_some() {
|
||||
if project == project_ref {
|
||||
bail!(
|
||||
project_ref,
|
||||
"name `{}` is already specified by `project` argument",
|
||||
project_ref.as_ref().unwrap()
|
||||
);
|
||||
}
|
||||
if let Some(ident) = &project_replace_value {
|
||||
if project == project_replace_value {
|
||||
bail!(ident, "name `{}` is already specified by `project` argument", ident);
|
||||
} else if project_ref == project_replace_value {
|
||||
bail!(ident, "name `{}` is already specified by `project_ref` argument", ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(span) = pinned_drop {
|
||||
if project_replace_span.is_some() {
|
||||
return Err(Error::new(
|
||||
span,
|
||||
"arguments `PinnedDrop` and `project_replace` are mutually exclusive",
|
||||
));
|
||||
}
|
||||
}
|
||||
let project_replace = match (project_replace_span, project_replace_value) {
|
||||
(None, _) => ProjReplace::None,
|
||||
(Some(span), Some(ident)) => ProjReplace::Named { ident, span },
|
||||
(Some(span), None) => ProjReplace::Unnamed { span },
|
||||
};
|
||||
let unpin_impl = match (unsafe_unpin, not_unpin) {
|
||||
(None, None) => UnpinImpl::Default,
|
||||
(Some(span), None) => UnpinImpl::Unsafe(span),
|
||||
(None, Some(span)) => UnpinImpl::Negative(span),
|
||||
(Some(span), Some(_)) => {
|
||||
return Err(Error::new(
|
||||
span,
|
||||
"arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive",
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self { pinned_drop, unpin_impl, project, project_ref, project_replace })
|
||||
}
|
||||
}
|
||||
|
||||
/// `UnsafeUnpin` or `!Unpin` argument.
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) enum UnpinImpl {
|
||||
Default,
|
||||
/// `UnsafeUnpin`.
|
||||
Unsafe(Span),
|
||||
/// `!Unpin`.
|
||||
Negative(Span),
|
||||
}
|
||||
|
||||
/// `project_replace [= <ident>]` argument.
|
||||
pub(super) enum ProjReplace {
|
||||
None,
|
||||
/// `project_replace`.
|
||||
Unnamed {
|
||||
span: Span,
|
||||
},
|
||||
/// `project_replace = <ident>`.
|
||||
#[allow(dead_code)] // false positive that fixed in Rust 1.38
|
||||
Named {
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
},
|
||||
}
|
||||
|
||||
impl ProjReplace {
|
||||
/// Return the span of this argument.
|
||||
pub(super) fn span(&self) -> Option<Span> {
|
||||
match self {
|
||||
Self::None => None,
|
||||
Self::Named { span, .. } | Self::Unnamed { span, .. } => Some(*span),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn ident(&self) -> Option<&Ident> {
|
||||
if let Self::Named { ident, .. } = self {
|
||||
Some(ident)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
65
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/attribute.rs
vendored
Normal file
65
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/attribute.rs
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
Attribute, Result, Token, Visibility,
|
||||
};
|
||||
|
||||
use super::PIN;
|
||||
use crate::utils::SliceExt;
|
||||
|
||||
// To generate the correct `Unpin` implementation and the projection methods,
|
||||
// we need to collect the types of the pinned fields.
|
||||
// However, since proc-macro-attribute is applied before `cfg` and `cfg_attr`
|
||||
// on fields, we cannot be collecting field types properly at this timing.
|
||||
// So instead of generating the `Unpin` implementation and the projection
|
||||
// methods here, delegate their processing to proc-macro-derive.
|
||||
//
|
||||
// At this stage, only attributes are parsed and the following attributes are
|
||||
// added to the attributes of the item.
|
||||
// - `#[derive(InternalDerive)]` - An internal helper macro that does the above
|
||||
// processing.
|
||||
// - `#[pin(__private(#args))]` - Pass the argument of `#[pin_project]` to
|
||||
// proc-macro-derive (`InternalDerive`).
|
||||
|
||||
pub(super) fn parse_attribute(args: &TokenStream, input: TokenStream) -> Result<TokenStream> {
|
||||
let Input { attrs, body } = syn::parse2(input)?;
|
||||
|
||||
Ok(quote! {
|
||||
#(#attrs)*
|
||||
#[derive(::pin_project::__private::__PinProjectInternalDerive)]
|
||||
// Use `__private` to prevent users from trying to control `InternalDerive`
|
||||
// manually. `__private` does not guarantee compatibility between patch
|
||||
// versions, so it should be sufficient for this purpose in most cases.
|
||||
#[pin(__private(#args))]
|
||||
#body
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // false positive that fixed in Rust 1.39
|
||||
struct Input {
|
||||
attrs: Vec<Attribute>,
|
||||
body: TokenStream,
|
||||
}
|
||||
|
||||
impl Parse for Input {
|
||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
|
||||
let ahead = input.fork();
|
||||
let _vis: Visibility = ahead.parse()?;
|
||||
if !ahead.peek(Token![struct]) && !ahead.peek(Token![enum]) {
|
||||
// If we check this only on proc-macro-derive, it may generate unhelpful error
|
||||
// messages. So it is preferable to be able to detect it here.
|
||||
bail!(
|
||||
input.parse::<TokenStream>()?,
|
||||
"#[pin_project] attribute may only be used on structs or enums"
|
||||
);
|
||||
} else if let Some(attr) = attrs.find(PIN) {
|
||||
bail!(attr, "#[pin] attribute may only be used on fields of structs or variants");
|
||||
} else if let Some(attr) = attrs.find("pin_project") {
|
||||
bail!(attr, "duplicate #[pin_project] attribute");
|
||||
}
|
||||
Ok(Self { attrs, body: input.parse()? })
|
||||
}
|
||||
}
|
||||
1127
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/derive.rs
vendored
Normal file
1127
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/derive.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/mod.rs
vendored
Normal file
17
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pin_project/mod.rs
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
mod args;
|
||||
mod attribute;
|
||||
mod derive;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::Error;
|
||||
|
||||
/// The annotation for pinned type.
|
||||
const PIN: &str = "pin";
|
||||
|
||||
pub(crate) fn attribute(args: &TokenStream, input: TokenStream) -> TokenStream {
|
||||
attribute::parse_attribute(args, input).unwrap_or_else(Error::into_compile_error)
|
||||
}
|
||||
|
||||
pub(crate) fn derive(input: TokenStream) -> TokenStream {
|
||||
derive::parse_derive(input).unwrap_or_else(Error::into_compile_error)
|
||||
}
|
||||
226
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pinned_drop.rs
vendored
Normal file
226
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/pinned_drop.rs
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{
|
||||
parse_quote, spanned::Spanned, visit_mut::VisitMut, Error, FnArg, GenericArgument, ImplItem,
|
||||
ItemImpl, Pat, PatIdent, Path, PathArguments, Result, ReturnType, Signature, Token, Type,
|
||||
TypePath, TypeReference,
|
||||
};
|
||||
|
||||
use crate::utils::{parse_as_empty, prepend_underscore_to_self, ReplaceReceiver, SliceExt};
|
||||
|
||||
pub(crate) fn attribute(args: &TokenStream, mut input: ItemImpl) -> TokenStream {
|
||||
let res = (|| -> Result<()> {
|
||||
parse_as_empty(args)?;
|
||||
validate_impl(&input)?;
|
||||
expand_impl(&mut input);
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
if let Err(e) = res {
|
||||
let mut tokens = e.to_compile_error();
|
||||
if let Type::Path(self_ty) = &*input.self_ty {
|
||||
let (impl_generics, _, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
// Generate a dummy impl of `PinnedDrop`.
|
||||
// In many cases, `#[pinned_drop] impl` is declared after `#[pin_project]`.
|
||||
// Therefore, if `pinned_drop` compile fails, you will also get an error
|
||||
// about `PinnedDrop` not being implemented.
|
||||
// This can be prevented to some extent by generating a dummy
|
||||
// `PinnedDrop` implementation.
|
||||
// We already know that we will get a compile error, so this won't
|
||||
// accidentally compile successfully.
|
||||
//
|
||||
// However, if `input.self_ty` is not Type::Path, there is a high possibility that
|
||||
// the type does not exist (since #[pin_project] can only be used on struct/enum
|
||||
// definitions), so do not generate a dummy impl.
|
||||
tokens.extend(quote! {
|
||||
impl #impl_generics ::pin_project::__private::PinnedDrop for #self_ty
|
||||
#where_clause
|
||||
{
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
});
|
||||
}
|
||||
tokens
|
||||
} else {
|
||||
input.into_token_stream()
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates the signature of given `PinnedDrop` impl.
|
||||
fn validate_impl(item: &ItemImpl) -> Result<()> {
|
||||
const INVALID_ITEM: &str =
|
||||
"#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait";
|
||||
|
||||
if let Some(attr) = item.attrs.find("pinned_drop") {
|
||||
bail!(attr, "duplicate #[pinned_drop] attribute");
|
||||
}
|
||||
|
||||
if let Some((_, path, _)) = &item.trait_ {
|
||||
if !path.is_ident("PinnedDrop") {
|
||||
bail!(path, INVALID_ITEM);
|
||||
}
|
||||
} else {
|
||||
bail!(item.self_ty, INVALID_ITEM);
|
||||
}
|
||||
|
||||
if item.unsafety.is_some() {
|
||||
bail!(item.unsafety, "implementing the trait `PinnedDrop` is not unsafe");
|
||||
}
|
||||
if item.items.is_empty() {
|
||||
bail!(item, "not all trait items implemented, missing: `drop`");
|
||||
}
|
||||
|
||||
match &*item.self_ty {
|
||||
Type::Path(_) => {}
|
||||
ty => {
|
||||
bail!(ty, "implementing the trait `PinnedDrop` on this type is unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
item.items.iter().enumerate().try_for_each(|(i, item)| match item {
|
||||
ImplItem::Const(item) => {
|
||||
bail!(item, "const `{}` is not a member of trait `PinnedDrop`", item.ident)
|
||||
}
|
||||
ImplItem::Type(item) => {
|
||||
bail!(item, "type `{}` is not a member of trait `PinnedDrop`", item.ident)
|
||||
}
|
||||
ImplItem::Method(method) => {
|
||||
validate_sig(&method.sig)?;
|
||||
if i == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
bail!(method, "duplicate definitions with name `drop`")
|
||||
}
|
||||
}
|
||||
_ => unreachable!("unexpected ImplItem"),
|
||||
})
|
||||
}
|
||||
|
||||
/// Validates the signature of given `PinnedDrop::drop` method.
|
||||
///
|
||||
/// The correct signature is: `(mut) self: (<path>::)Pin<&mut Self>`
|
||||
fn validate_sig(sig: &Signature) -> Result<()> {
|
||||
fn get_ty_path(ty: &Type) -> Option<&Path> {
|
||||
if let Type::Path(TypePath { qself: None, path }) = ty {
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
const INVALID_ARGUMENT: &str = "method `drop` must take an argument `self: Pin<&mut Self>`";
|
||||
|
||||
if sig.ident != "drop" {
|
||||
bail!(sig.ident, "method `{}` is not a member of trait `PinnedDrop", sig.ident,);
|
||||
}
|
||||
|
||||
if let ReturnType::Type(_, ty) = &sig.output {
|
||||
match &**ty {
|
||||
Type::Tuple(ty) if ty.elems.is_empty() => {}
|
||||
_ => bail!(ty, "method `drop` must return the unit type"),
|
||||
}
|
||||
}
|
||||
|
||||
match sig.inputs.len() {
|
||||
1 => {}
|
||||
0 => return Err(Error::new(sig.paren_token.span, INVALID_ARGUMENT)),
|
||||
_ => bail!(sig.inputs, INVALID_ARGUMENT),
|
||||
}
|
||||
|
||||
if let Some(FnArg::Typed(arg)) = sig.receiver() {
|
||||
// (mut) self: <path>
|
||||
if let Some(path) = get_ty_path(&arg.ty) {
|
||||
let ty = path.segments.last().unwrap();
|
||||
if let PathArguments::AngleBracketed(args) = &ty.arguments {
|
||||
// (mut) self: (<path>::)<ty><&mut <elem>..>
|
||||
if let Some(GenericArgument::Type(Type::Reference(TypeReference {
|
||||
mutability: Some(_),
|
||||
elem,
|
||||
..
|
||||
}))) = args.args.first()
|
||||
{
|
||||
// (mut) self: (<path>::)Pin<&mut Self>
|
||||
if args.args.len() == 1
|
||||
&& ty.ident == "Pin"
|
||||
&& get_ty_path(elem).map_or(false, |path| path.is_ident("Self"))
|
||||
{
|
||||
if sig.unsafety.is_some() {
|
||||
bail!(sig.unsafety, "implementing the method `drop` is not unsafe");
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bail!(sig.inputs[0], INVALID_ARGUMENT)
|
||||
}
|
||||
|
||||
// from:
|
||||
//
|
||||
// fn drop(self: Pin<&mut Self>) {
|
||||
// // ...
|
||||
// }
|
||||
//
|
||||
// into:
|
||||
//
|
||||
// unsafe fn drop(self: Pin<&mut Self>) {
|
||||
// fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
|
||||
// fn __drop_inner() {}
|
||||
// // ...
|
||||
// }
|
||||
// __drop_inner(self);
|
||||
// }
|
||||
//
|
||||
fn expand_impl(item: &mut ItemImpl) {
|
||||
fn get_arg_pat(arg: &mut FnArg) -> Option<&mut PatIdent> {
|
||||
if let FnArg::Typed(arg) = arg {
|
||||
if let Pat::Ident(ident) = &mut *arg.pat {
|
||||
return Some(ident);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
// `PinnedDrop` is a private trait and should not appear in docs.
|
||||
item.attrs.push(parse_quote!(#[doc(hidden)]));
|
||||
|
||||
let path = &mut item.trait_.as_mut().unwrap().1;
|
||||
*path = parse_quote_spanned! { path.span() =>
|
||||
::pin_project::__private::PinnedDrop
|
||||
};
|
||||
|
||||
let method =
|
||||
if let ImplItem::Method(method) = &mut item.items[0] { method } else { unreachable!() };
|
||||
|
||||
// `fn drop(mut self: Pin<&mut Self>)` -> `fn __drop_inner<T>(mut __self: Pin<&mut Receiver>)`
|
||||
let drop_inner = {
|
||||
let mut drop_inner = method.clone();
|
||||
let ident = format_ident!("__drop_inner");
|
||||
// Add a dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
|
||||
drop_inner.block.stmts.insert(0, parse_quote!(fn #ident() {}));
|
||||
drop_inner.sig.ident = ident;
|
||||
drop_inner.sig.generics = item.generics.clone();
|
||||
let self_pat = get_arg_pat(&mut drop_inner.sig.inputs[0]).unwrap();
|
||||
prepend_underscore_to_self(&mut self_pat.ident);
|
||||
let self_ty = if let Type::Path(ty) = &*item.self_ty { ty } else { unreachable!() };
|
||||
let mut visitor = ReplaceReceiver(self_ty);
|
||||
visitor.visit_signature_mut(&mut drop_inner.sig);
|
||||
visitor.visit_block_mut(&mut drop_inner.block);
|
||||
drop_inner
|
||||
};
|
||||
|
||||
// `fn drop(mut self: Pin<&mut Self>)` -> `unsafe fn drop(self: Pin<&mut Self>)`
|
||||
method.sig.unsafety = Some(<Token![unsafe]>::default());
|
||||
let self_pat = get_arg_pat(&mut method.sig.inputs[0]).unwrap();
|
||||
self_pat.mutability = None;
|
||||
let self_token = &self_pat.ident;
|
||||
|
||||
method.block.stmts = parse_quote! {
|
||||
#[allow(clippy::needless_pass_by_value)] // This lint does not warn the receiver.
|
||||
#drop_inner
|
||||
__drop_inner(#self_token);
|
||||
};
|
||||
}
|
||||
402
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/utils.rs
vendored
Normal file
402
clamav/libclamav_rust/.cargo/vendor/pin-project-internal/src/utils.rs
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
use std::{iter::FromIterator, mem};
|
||||
|
||||
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::{
|
||||
parse::{Parse, ParseBuffer, ParseStream},
|
||||
parse_quote,
|
||||
punctuated::Punctuated,
|
||||
token,
|
||||
visit_mut::{self, VisitMut},
|
||||
Attribute, ExprPath, ExprStruct, Generics, Ident, Item, Lifetime, LifetimeDef, Macro, PatPath,
|
||||
PatStruct, PatTupleStruct, Path, PathArguments, PredicateType, QSelf, Result, Token, Type,
|
||||
TypeParamBound, TypePath, Variant, Visibility, WherePredicate,
|
||||
};
|
||||
|
||||
pub(crate) type Variants = Punctuated<Variant, Token![,]>;
|
||||
|
||||
macro_rules! format_err {
|
||||
($span:expr, $msg:expr $(,)?) => {
|
||||
syn::Error::new_spanned(&$span as &dyn quote::ToTokens, &$msg as &dyn std::fmt::Display)
|
||||
};
|
||||
($span:expr, $($tt:tt)*) => {
|
||||
format_err!($span, format!($($tt)*))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! bail {
|
||||
($($tt:tt)*) => {
|
||||
return Err(format_err!($($tt)*))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! parse_quote_spanned {
|
||||
($span:expr => $($tt:tt)*) => {
|
||||
syn::parse2(quote::quote_spanned!($span => $($tt)*)).unwrap_or_else(|e| panic!("{}", e))
|
||||
};
|
||||
}
|
||||
|
||||
/// Determines the lifetime names. Ensure it doesn't overlap with any existing
|
||||
/// lifetime names.
|
||||
pub(crate) fn determine_lifetime_name(lifetime_name: &mut String, generics: &mut Generics) {
|
||||
struct CollectLifetimes(Vec<String>);
|
||||
|
||||
impl VisitMut for CollectLifetimes {
|
||||
fn visit_lifetime_def_mut(&mut self, def: &mut LifetimeDef) {
|
||||
self.0.push(def.lifetime.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert!(lifetime_name.starts_with('\''));
|
||||
|
||||
let mut lifetimes = CollectLifetimes(Vec::new());
|
||||
lifetimes.visit_generics_mut(generics);
|
||||
|
||||
while lifetimes.0.iter().any(|name| name.starts_with(&**lifetime_name)) {
|
||||
lifetime_name.push('_');
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `insert_lifetime`, but also generates a bound of the form
|
||||
/// `OriginalType<A, B>: 'lifetime`. Used when generating the definition
|
||||
/// of a projection type
|
||||
pub(crate) fn insert_lifetime_and_bound(
|
||||
generics: &mut Generics,
|
||||
lifetime: Lifetime,
|
||||
orig_generics: &Generics,
|
||||
orig_ident: &Ident,
|
||||
) -> WherePredicate {
|
||||
insert_lifetime(generics, lifetime.clone());
|
||||
|
||||
let orig_type: Type = parse_quote!(#orig_ident #orig_generics);
|
||||
let mut punct = Punctuated::new();
|
||||
punct.push(TypeParamBound::Lifetime(lifetime));
|
||||
|
||||
WherePredicate::Type(PredicateType {
|
||||
lifetimes: None,
|
||||
bounded_ty: orig_type,
|
||||
colon_token: <Token![:]>::default(),
|
||||
bounds: punct,
|
||||
})
|
||||
}
|
||||
|
||||
/// Inserts a `lifetime` at position `0` of `generics.params`.
|
||||
pub(crate) fn insert_lifetime(generics: &mut Generics, lifetime: Lifetime) {
|
||||
generics.lt_token.get_or_insert_with(<Token![<]>::default);
|
||||
generics.gt_token.get_or_insert_with(<Token![>]>::default);
|
||||
generics.params.insert(0, LifetimeDef::new(lifetime).into());
|
||||
}
|
||||
|
||||
/// Determines the visibility of the projected types and projection methods.
|
||||
///
|
||||
/// If given visibility is `pub`, returned visibility is `pub(crate)`.
|
||||
/// Otherwise, returned visibility is the same as given visibility.
|
||||
pub(crate) fn determine_visibility(vis: &Visibility) -> Visibility {
|
||||
if let Visibility::Public(token) = vis {
|
||||
parse_quote_spanned!(token.pub_token.span => pub(crate))
|
||||
} else {
|
||||
vis.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `tokens` is an empty `TokenStream`.
|
||||
///
|
||||
/// This is almost equivalent to `syn::parse2::<Nothing>()`, but produces
|
||||
/// a better error message and does not require ownership of `tokens`.
|
||||
pub(crate) fn parse_as_empty(tokens: &TokenStream) -> Result<()> {
|
||||
if tokens.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
bail!(tokens, "unexpected token: `{}`", tokens)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn respan<T>(node: &T, span: Span) -> T
|
||||
where
|
||||
T: ToTokens + Parse,
|
||||
{
|
||||
let tokens = node.to_token_stream();
|
||||
let respanned = respan_tokens(tokens, span);
|
||||
syn::parse2(respanned).unwrap()
|
||||
}
|
||||
|
||||
fn respan_tokens(tokens: TokenStream, span: Span) -> TokenStream {
|
||||
tokens
|
||||
.into_iter()
|
||||
.map(|mut token| {
|
||||
token.set_span(span);
|
||||
token
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// =================================================================================================
|
||||
// extension traits
|
||||
|
||||
pub(crate) trait SliceExt {
|
||||
fn position_exact(&self, ident: &str) -> Result<Option<usize>>;
|
||||
fn find(&self, ident: &str) -> Option<&Attribute>;
|
||||
}
|
||||
|
||||
impl SliceExt for [Attribute] {
|
||||
/// # Errors
|
||||
///
|
||||
/// - There are multiple specified attributes.
|
||||
/// - The `Attribute::tokens` field of the specified attribute is not empty.
|
||||
fn position_exact(&self, ident: &str) -> Result<Option<usize>> {
|
||||
self.iter()
|
||||
.try_fold((0, None), |(i, mut prev), attr| {
|
||||
if attr.path.is_ident(ident) {
|
||||
if prev.replace(i).is_some() {
|
||||
bail!(attr, "duplicate #[{}] attribute", ident);
|
||||
}
|
||||
parse_as_empty(&attr.tokens)?;
|
||||
}
|
||||
Ok((i + 1, prev))
|
||||
})
|
||||
.map(|(_, pos)| pos)
|
||||
}
|
||||
|
||||
fn find(&self, ident: &str) -> Option<&Attribute> {
|
||||
self.iter().position(|attr| attr.path.is_ident(ident)).map(|i| &self[i])
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ParseBufferExt<'a> {
|
||||
fn parenthesized(self) -> Result<ParseBuffer<'a>>;
|
||||
}
|
||||
|
||||
impl<'a> ParseBufferExt<'a> for ParseStream<'a> {
|
||||
fn parenthesized(self) -> Result<ParseBuffer<'a>> {
|
||||
let content;
|
||||
let _: token::Paren = syn::parenthesized!(content in self);
|
||||
Ok(content)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ParseBufferExt<'a> for ParseBuffer<'a> {
|
||||
fn parenthesized(self) -> Result<ParseBuffer<'a>> {
|
||||
let content;
|
||||
let _: token::Paren = syn::parenthesized!(content in self);
|
||||
Ok(content)
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================
|
||||
// visitors
|
||||
|
||||
// Replace `self`/`Self` with `__self`/`self_ty`.
|
||||
// Based on:
|
||||
// - https://github.com/dtolnay/async-trait/blob/0.1.35/src/receiver.rs
|
||||
// - https://github.com/dtolnay/async-trait/commit/6029cbf375c562ca98fa5748e9d950a8ff93b0e7
|
||||
|
||||
pub(crate) struct ReplaceReceiver<'a>(pub(crate) &'a TypePath);
|
||||
|
||||
impl ReplaceReceiver<'_> {
|
||||
fn self_ty(&self, span: Span) -> TypePath {
|
||||
respan(self.0, span)
|
||||
}
|
||||
|
||||
fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
if path.leading_colon.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = &path.segments[0];
|
||||
if first.ident != "Self" || !first.arguments.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if path.segments.len() == 1 {
|
||||
self.self_to_expr_path(path);
|
||||
return;
|
||||
}
|
||||
|
||||
let span = first.ident.span();
|
||||
*qself = Some(QSelf {
|
||||
lt_token: Token,
|
||||
ty: Box::new(self.self_ty(span).into()),
|
||||
position: 0,
|
||||
as_token: None,
|
||||
gt_token: Token,
|
||||
});
|
||||
|
||||
path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
|
||||
|
||||
let segments = mem::replace(&mut path.segments, Punctuated::new());
|
||||
path.segments = segments.into_pairs().skip(1).collect();
|
||||
}
|
||||
|
||||
fn self_to_expr_path(&self, path: &mut Path) {
|
||||
if path.leading_colon.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = &path.segments[0];
|
||||
if first.ident != "Self" || !first.arguments.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let self_ty = self.self_ty(first.ident.span());
|
||||
let variant = mem::replace(path, self_ty.path);
|
||||
for segment in &mut path.segments {
|
||||
if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
|
||||
if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
|
||||
bracketed.colon2_token = Some(<Token![::]>::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
if variant.segments.len() > 1 {
|
||||
path.segments.push_punct(<Token![::]>::default());
|
||||
path.segments.extend(variant.segments.into_pairs().skip(1));
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_token_stream(&self, tokens: &mut TokenStream) -> bool {
|
||||
let mut out = Vec::new();
|
||||
let mut modified = false;
|
||||
let mut iter = tokens.clone().into_iter().peekable();
|
||||
while let Some(tt) = iter.next() {
|
||||
match tt {
|
||||
TokenTree::Ident(mut ident) => {
|
||||
modified |= prepend_underscore_to_self(&mut ident);
|
||||
if ident == "Self" {
|
||||
modified = true;
|
||||
let self_ty = self.self_ty(ident.span());
|
||||
match iter.peek() {
|
||||
Some(TokenTree::Punct(p))
|
||||
if p.as_char() == ':' && p.spacing() == Spacing::Joint =>
|
||||
{
|
||||
let next = iter.next().unwrap();
|
||||
match iter.peek() {
|
||||
Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
|
||||
let span = ident.span();
|
||||
out.extend(quote_spanned!(span=> <#self_ty>));
|
||||
}
|
||||
_ => out.extend(quote!(#self_ty)),
|
||||
}
|
||||
out.push(next);
|
||||
}
|
||||
_ => out.extend(quote!(#self_ty)),
|
||||
}
|
||||
} else {
|
||||
out.push(TokenTree::Ident(ident));
|
||||
}
|
||||
}
|
||||
TokenTree::Group(group) => {
|
||||
let mut content = group.stream();
|
||||
modified |= self.visit_token_stream(&mut content);
|
||||
let mut new = Group::new(group.delimiter(), content);
|
||||
new.set_span(group.span());
|
||||
out.push(TokenTree::Group(new));
|
||||
}
|
||||
other => out.push(other),
|
||||
}
|
||||
}
|
||||
if modified {
|
||||
*tokens = TokenStream::from_iter(out);
|
||||
}
|
||||
modified
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for ReplaceReceiver<'_> {
|
||||
// `Self` -> `Receiver`
|
||||
fn visit_type_mut(&mut self, ty: &mut Type) {
|
||||
if let Type::Path(node) = ty {
|
||||
if node.qself.is_none() && node.path.is_ident("Self") {
|
||||
*ty = self.self_ty(node.path.segments[0].ident.span()).into();
|
||||
} else {
|
||||
self.visit_type_path_mut(node);
|
||||
}
|
||||
} else {
|
||||
visit_mut::visit_type_mut(self, ty);
|
||||
}
|
||||
}
|
||||
|
||||
// `Self::Assoc` -> `<Receiver>::Assoc`
|
||||
fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
|
||||
if ty.qself.is_none() {
|
||||
self.self_to_qself(&mut ty.qself, &mut ty.path);
|
||||
}
|
||||
visit_mut::visit_type_path_mut(self, ty);
|
||||
}
|
||||
|
||||
// `Self::method` -> `<Receiver>::method`
|
||||
fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
|
||||
if expr.qself.is_none() {
|
||||
self.self_to_qself(&mut expr.qself, &mut expr.path);
|
||||
}
|
||||
visit_mut::visit_expr_path_mut(self, expr);
|
||||
}
|
||||
|
||||
fn visit_expr_struct_mut(&mut self, expr: &mut ExprStruct) {
|
||||
self.self_to_expr_path(&mut expr.path);
|
||||
visit_mut::visit_expr_struct_mut(self, expr);
|
||||
}
|
||||
|
||||
fn visit_pat_path_mut(&mut self, pat: &mut PatPath) {
|
||||
if pat.qself.is_none() {
|
||||
self.self_to_qself(&mut pat.qself, &mut pat.path);
|
||||
}
|
||||
visit_mut::visit_pat_path_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_pat_struct_mut(&mut self, pat: &mut PatStruct) {
|
||||
self.self_to_expr_path(&mut pat.path);
|
||||
visit_mut::visit_pat_struct_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_pat_tuple_struct_mut(&mut self, pat: &mut PatTupleStruct) {
|
||||
self.self_to_expr_path(&mut pat.path);
|
||||
visit_mut::visit_pat_tuple_struct_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_path_mut(&mut self, path: &mut Path) {
|
||||
if path.segments.len() == 1 {
|
||||
// Replace `self`, but not `self::function`.
|
||||
prepend_underscore_to_self(&mut path.segments[0].ident);
|
||||
}
|
||||
for segment in &mut path.segments {
|
||||
self.visit_path_arguments_mut(&mut segment.arguments);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, item: &mut Item) {
|
||||
match item {
|
||||
// Visit `macro_rules!` because locally defined macros can refer to `self`.
|
||||
Item::Macro(item) if item.mac.path.is_ident("macro_rules") => {
|
||||
self.visit_macro_mut(&mut item.mac);
|
||||
}
|
||||
// Otherwise, do not recurse into nested items.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_macro_mut(&mut self, mac: &mut Macro) {
|
||||
// We can't tell in general whether `self` inside a macro invocation
|
||||
// refers to the self in the argument list or a different self
|
||||
// introduced within the macro. Heuristic: if the macro input contains
|
||||
// `fn`, then `self` is more likely to refer to something other than the
|
||||
// outer function's self argument.
|
||||
if !contains_fn(mac.tokens.clone()) {
|
||||
self.visit_token_stream(&mut mac.tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_fn(tokens: TokenStream) -> bool {
|
||||
tokens.into_iter().any(|tt| match tt {
|
||||
TokenTree::Ident(ident) => ident == "fn",
|
||||
TokenTree::Group(group) => contains_fn(group.stream()),
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn prepend_underscore_to_self(ident: &mut Ident) -> bool {
|
||||
let modified = ident == "self";
|
||||
if modified {
|
||||
*ident = Ident::new("__self", ident.span());
|
||||
}
|
||||
modified
|
||||
}
|
||||
Reference in New Issue
Block a user