mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1716518 - Upgrade pin-project and pin-project-internal to v0.4.28. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D117830
This commit is contained in:
parent
509f00541c
commit
d63b139fc1
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -3810,18 +3810,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f6a7f5eee6292c559c793430c55c00aea9d3b3d1905e855806ca4d7253426a2"
|
||||
checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"
|
||||
checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1 +1 @@
|
||||
{"files":{"Cargo.toml":"3fe6c53bc8cb8dfee1091ff799a743024b78bbf7ded986396ccb8a139bc7f02b","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/lib.rs":"fe9fdaa1dcf2e9ade6ae1c34e20195223c8f63d19c0ba2d0189e07207d4f1a30","src/pin_project/attribute.rs":"5b441bab16d19215d660790b46eab18b402d36edb951ba7f8284772bf2a470bd","src/pin_project/derive.rs":"f244d4bed929350fdfcc96513fce17a4ab2146e1f7974ae1255d72a9b72ffd33","src/pin_project/mod.rs":"4c5f5215d1737a6e4797d7f5eb1f7f6008505b06cfc304a66758bd96e6252c0c","src/pinned_drop.rs":"4519a66e9804143578faf60ed8239811d92cc6b2af817736439a9bc772d48780","src/project.rs":"e6ce9acaaad85d9945c24ec4507e6373aa61dfab50717453666733fa8161c099","src/utils.rs":"340a79dd4b02b5ea97c747ef5c56d5a8cedfaeff4a259fe5140c83803b2ed115"},"package":"8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"}
|
||||
{"files":{"Cargo.toml":"6691c704de55962c48e8e34a109ae4948427fdb453836f7bdd62ac9c9fb50992","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","build.rs":"ff90cd6a515a5eab716f63f3af90db47c411ac3a1629800731fb73de832495aa","src/lib.rs":"57267f77a182d4baf651b3495eb89cb326bebb17c2f2f69a5e351bf1529d775b","src/pin_project/attribute.rs":"6601b126a642b25a4c0a5fbb2bbeb2bdc59ecb28eb678ef40595fc28001e5433","src/pin_project/derive.rs":"f97503dcdd13c15f27bfc24a557701fc9790218041ada1491cfc96b8dce67762","src/pin_project/mod.rs":"149bda261825c80b1043ce1a26f944f69d939d86e5fc37fd1f71969469202b2f","src/pinned_drop.rs":"1feb86175c035c2cbe5e5a0a43d18d2502d764d930644c5456d0ae249b4bbc2c","src/project.rs":"c1fe5164374317ada25ce0a26945c2fd2484d611de60b8ce05adc15013d768b2","src/utils.rs":"120e4c49164a1cbaf5e9f6632f29d88ab9821acb34355758c6b1566233a2fccc"},"package":"3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e"}
|
15
third_party/rust/pin-project-internal/Cargo.toml
vendored
15
third_party/rust/pin-project-internal/Cargo.toml
vendored
@ -13,24 +13,27 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
authors = ["Taiki Endo <te316e89@gmail.com>"]
|
||||
description = "An internal crate to support pin_project - do not use directly\n"
|
||||
homepage = "https://github.com/taiki-e/pin-project"
|
||||
description = "Implementation detail of the `pin-project` crate.\n"
|
||||
documentation = "https://docs.rs/pin-project-internal"
|
||||
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.0"
|
||||
version = "1"
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1.0"
|
||||
version = "1"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "1.0"
|
||||
version = "1.0.44"
|
||||
features = ["full", "visit-mut"]
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1"
|
||||
|
34
third_party/rust/pin-project-internal/build.rs
vendored
Normal file
34
third_party/rust/pin-project-internal/build.rs
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
use std::{env, process::Command, str};
|
||||
|
||||
// The rustc-cfg strings below are *not* public API. Please let us know by
|
||||
// opening a GitHub issue if your build environment requires some way to enable
|
||||
// these cfgs other than by executing our build script.
|
||||
fn main() {
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(minor) => minor,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Underscore const names requires Rust 1.37:
|
||||
// https://github.com/rust-lang/rust/pull/61347
|
||||
if minor >= 37 {
|
||||
println!("cargo:rustc-cfg=underscore_consts");
|
||||
}
|
||||
|
||||
// #[deprecated] on proc-macro requires Rust 1.40:
|
||||
// https://github.com/rust-lang/rust/pull/65666
|
||||
if minor >= 40 {
|
||||
println!("cargo:rustc-cfg=deprecated_proc_macro");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
pieces.next()?.parse().ok()
|
||||
}
|
847
third_party/rust/pin-project-internal/src/lib.rs
vendored
847
third_party/rust/pin-project-internal/src/lib.rs
vendored
File diff suppressed because it is too large
Load Diff
@ -1,42 +1,37 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
*,
|
||||
};
|
||||
|
||||
use crate::utils::{SliceExt, CURRENT_PRIVATE_MODULE};
|
||||
|
||||
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.
|
||||
// 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`).
|
||||
// * `#[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 { mut attrs, body } = syn::parse2(input)?;
|
||||
|
||||
let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
|
||||
attrs.push(syn::parse_quote! {
|
||||
#[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.
|
||||
attrs.push(syn::parse_quote! {
|
||||
#[pin(#private(#args))]
|
||||
});
|
||||
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
|
||||
})
|
||||
}
|
||||
@ -52,10 +47,10 @@ impl Parse for Input {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
|
||||
let ahead = input.fork();
|
||||
let _vis: Visibility = ahead.parse()?;
|
||||
let _: 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.
|
||||
// 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.
|
||||
Err(error!(
|
||||
input.parse::<TokenStream>()?,
|
||||
"#[pin_project] attribute may only be used on structs or enums"
|
||||
@ -63,7 +58,7 @@ impl Parse for Input {
|
||||
} else if let Some(attr) = attrs.find(PIN) {
|
||||
Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants"))
|
||||
} else if let Some(attr) = attrs.find("pin_project") {
|
||||
Err(error!(attr, "only one #[pin_project] attribute is allowed"))
|
||||
Err(error!(attr, "duplicate #[pin_project] attribute"))
|
||||
} else {
|
||||
Ok(Self { attrs, body: input.parse()? })
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
mod attribute;
|
||||
mod derive;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
/// The annotation for pinned type.
|
||||
const PIN: &str = "pin";
|
||||
|
||||
|
@ -1,31 +1,34 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{spanned::Spanned, visit_mut::VisitMut, *};
|
||||
|
||||
use crate::utils::{
|
||||
parse_as_empty, prepend_underscore_to_self, ReplaceReceiver, CURRENT_PRIVATE_MODULE,
|
||||
};
|
||||
use crate::utils::{parse_as_empty, prepend_underscore_to_self, ReplaceReceiver, SliceExt};
|
||||
|
||||
pub(crate) fn attribute(args: &TokenStream, mut input: ItemImpl) -> TokenStream {
|
||||
if let Err(e) = parse_as_empty(args).and_then(|()| parse(&mut input)) {
|
||||
let self_ty = &input.self_ty;
|
||||
let (impl_generics, _, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
let mut tokens = e.to_compile_error();
|
||||
let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
|
||||
// Generate a dummy `PinnedDrop` implementation.
|
||||
// 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.
|
||||
tokens.extend(quote! {
|
||||
impl #impl_generics ::pin_project::#private::PinnedDrop for #self_ty #where_clause {
|
||||
unsafe fn drop(self: ::core::pin::Pin<&mut Self>) {}
|
||||
}
|
||||
});
|
||||
if let Type::Path(self_ty) = &*input.self_ty {
|
||||
let (impl_generics, _, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
// 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, 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()
|
||||
@ -48,44 +51,41 @@ fn parse_method(method: &ImplItemMethod) -> Result<()> {
|
||||
|
||||
if let ReturnType::Type(_, ty) = &method.sig.output {
|
||||
match &**ty {
|
||||
Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => {}
|
||||
Type::Tuple(ty) if ty.elems.is_empty() => {}
|
||||
_ => return Err(error!(ty, "method `drop` must return the unit type")),
|
||||
}
|
||||
}
|
||||
|
||||
if method.sig.inputs.len() != 1 {
|
||||
if method.sig.inputs.is_empty() {
|
||||
return Err(syn::Error::new(method.sig.paren_token.span, INVALID_ARGUMENT));
|
||||
} else {
|
||||
return Err(error!(&method.sig.inputs, INVALID_ARGUMENT));
|
||||
}
|
||||
match method.sig.inputs.len() {
|
||||
1 => {}
|
||||
0 => return Err(Error::new(method.sig.paren_token.span, INVALID_ARGUMENT)),
|
||||
_ => return Err(error!(method.sig.inputs, INVALID_ARGUMENT)),
|
||||
}
|
||||
|
||||
if let FnArg::Typed(PatType { pat, ty, .. }) = &method.sig.inputs[0] {
|
||||
// !by_ref (mutability) ident !subpat: path
|
||||
if let (Pat::Ident(PatIdent { by_ref: None, ident, subpat: None, .. }), Some(path)) =
|
||||
(&**pat, get_ty_path(ty))
|
||||
{
|
||||
let ty = &path.segments.last().unwrap();
|
||||
if let Some(FnArg::Typed(pat)) = method.sig.receiver() {
|
||||
// (mut) self: <path>
|
||||
if let Some(path) = get_ty_path(&pat.ty) {
|
||||
let ty = path.segments.last().unwrap();
|
||||
if let PathArguments::AngleBracketed(args) = &ty.arguments {
|
||||
// (mut) self: (path::)Pin<args>
|
||||
if ident == "self" && args.args.len() == 1 && ty.ident == "Pin" {
|
||||
// &mut <elem>
|
||||
if let GenericArgument::Type(Type::Reference(TypeReference {
|
||||
mutability: Some(_),
|
||||
elem,
|
||||
..
|
||||
})) = &args.args[0]
|
||||
// (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 get_ty_path(elem).map_or(false, |path| path.is_ident("Self")) {
|
||||
if method.sig.unsafety.is_some() {
|
||||
return Err(error!(
|
||||
method.sig.unsafety,
|
||||
"implementing the method `drop` is not unsafe"
|
||||
));
|
||||
}
|
||||
return Ok(());
|
||||
if method.sig.unsafety.is_some() {
|
||||
return Err(error!(
|
||||
method.sig.unsafety,
|
||||
"implementing the method `drop` is not unsafe"
|
||||
));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,24 +96,23 @@ fn parse_method(method: &ImplItemMethod) -> Result<()> {
|
||||
}
|
||||
|
||||
fn parse(item: &mut 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") {
|
||||
return Err(error!(attr, "duplicate #[pinned_drop] attribute"));
|
||||
}
|
||||
|
||||
if let Some((_, path, _)) = &mut item.trait_ {
|
||||
if path.is_ident("PinnedDrop") {
|
||||
let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
|
||||
*path = syn::parse2(quote_spanned! { path.span() =>
|
||||
::pin_project::#private::PinnedDrop
|
||||
})
|
||||
.unwrap();
|
||||
*path = parse_quote_spanned! { path.span() =>
|
||||
::pin_project::__private::PinnedDrop
|
||||
};
|
||||
} else {
|
||||
return Err(error!(
|
||||
path,
|
||||
"#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait"
|
||||
));
|
||||
return Err(error!(path, INVALID_ITEM));
|
||||
}
|
||||
} else {
|
||||
return Err(error!(
|
||||
item.self_ty,
|
||||
"#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait"
|
||||
));
|
||||
return Err(error!(item.self_ty, INVALID_ITEM));
|
||||
}
|
||||
|
||||
if item.unsafety.is_some() {
|
||||
@ -123,33 +122,37 @@ fn parse(item: &mut ItemImpl) -> Result<()> {
|
||||
return Err(error!(item, "not all trait items implemented, missing: `drop`"));
|
||||
}
|
||||
|
||||
for (i, item) in item.items.iter().enumerate() {
|
||||
match item {
|
||||
ImplItem::Const(item) => {
|
||||
return Err(error!(
|
||||
item,
|
||||
"const `{}` is not a member of trait `PinnedDrop`", item.ident
|
||||
));
|
||||
}
|
||||
ImplItem::Type(item) => {
|
||||
return Err(error!(
|
||||
item,
|
||||
"type `{}` is not a member of trait `PinnedDrop`", item.ident
|
||||
));
|
||||
}
|
||||
ImplItem::Method(method) => {
|
||||
parse_method(method)?;
|
||||
if i != 0 {
|
||||
return Err(error!(method, "duplicate definitions with name `drop`"));
|
||||
}
|
||||
}
|
||||
_ => parse_as_empty(&item.to_token_stream())?,
|
||||
match &*item.self_ty {
|
||||
Type::Path(_) => {}
|
||||
ty => {
|
||||
return Err(error!(
|
||||
ty,
|
||||
"implementing the trait `PinnedDrop` on this type is unsupported"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
expand_item(item);
|
||||
|
||||
Ok(())
|
||||
item.items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.try_for_each(|(i, item)| match item {
|
||||
ImplItem::Const(item) => {
|
||||
Err(error!(item, "const `{}` is not a member of trait `PinnedDrop`", item.ident))
|
||||
}
|
||||
ImplItem::Type(item) => {
|
||||
Err(error!(item, "type `{}` is not a member of trait `PinnedDrop`", item.ident))
|
||||
}
|
||||
ImplItem::Method(method) => {
|
||||
parse_method(method)?;
|
||||
if i == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error!(method, "duplicate definitions with name `drop`"))
|
||||
}
|
||||
}
|
||||
_ => unreachable!("unexpected ImplItem"),
|
||||
})
|
||||
.map(|()| expand_item(item))
|
||||
}
|
||||
|
||||
// from:
|
||||
@ -162,6 +165,7 @@ fn parse(item: &mut ItemImpl) -> Result<()> {
|
||||
//
|
||||
// unsafe fn drop(self: Pin<&mut Self>) {
|
||||
// fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
|
||||
// fn __drop_inner() {}
|
||||
// // something
|
||||
// }
|
||||
// __drop_inner(self);
|
||||
@ -173,27 +177,35 @@ fn expand_item(item: &mut ItemImpl) {
|
||||
let mut drop_inner = method.clone();
|
||||
|
||||
// `fn drop(mut self: Pin<&mut Self>)` -> `fn __drop_inner<T>(mut __self: Pin<&mut Receiver>)`
|
||||
drop_inner.sig.ident = Ident::new("__drop_inner", drop_inner.sig.ident.span());
|
||||
let ident = Ident::new("__drop_inner", drop_inner.sig.ident.span());
|
||||
// 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();
|
||||
if let FnArg::Typed(arg) = &mut drop_inner.sig.inputs[0] {
|
||||
if let Pat::Ident(ident) = &mut *arg.pat {
|
||||
prepend_underscore_to_self(&mut ident.ident);
|
||||
}
|
||||
}
|
||||
let mut visitor = ReplaceReceiver::new(&item.self_ty);
|
||||
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);
|
||||
|
||||
// `fn drop(mut self: Pin<&mut Self>)` -> `unsafe fn drop(self: Pin<&mut Self>)`
|
||||
method.sig.unsafety = Some(token::Unsafe::default());
|
||||
method.sig.unsafety = Some(<Token![unsafe]>::default());
|
||||
let mut self_token = None;
|
||||
if let FnArg::Typed(arg) = &mut method.sig.inputs[0] {
|
||||
if let Pat::Ident(ident) = &mut *arg.pat {
|
||||
ident.mutability = None;
|
||||
self_token = Some(&ident.ident);
|
||||
}
|
||||
}
|
||||
assert!(self_token.is_some());
|
||||
|
||||
method.block = syn::parse_quote! {{
|
||||
method.block.stmts = parse_quote! {
|
||||
#[allow(clippy::needless_pass_by_value)] // This lint does not warn the receiver.
|
||||
#drop_inner
|
||||
__drop_inner(self);
|
||||
}};
|
||||
__drop_inner(#self_token);
|
||||
};
|
||||
}
|
||||
|
322
third_party/rust/pin-project-internal/src/project.rs
vendored
322
third_party/rust/pin-project-internal/src/project.rs
vendored
@ -5,23 +5,23 @@ use syn::{
|
||||
*,
|
||||
};
|
||||
|
||||
use crate::utils::*;
|
||||
use crate::utils::{
|
||||
determine_lifetime_name, insert_lifetime, parse_as_empty, ProjKind, SliceExt, VecExt,
|
||||
};
|
||||
|
||||
pub(crate) fn attribute(args: &TokenStream, input: Stmt, mutability: Mutability) -> TokenStream {
|
||||
parse_as_empty(args)
|
||||
.and_then(|()| parse(input, mutability))
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
pub(crate) fn attribute(args: &TokenStream, input: Stmt, kind: ProjKind) -> TokenStream {
|
||||
parse_as_empty(args).and_then(|()| parse(input, kind)).unwrap_or_else(|e| e.to_compile_error())
|
||||
}
|
||||
|
||||
fn replace_stmt(stmt: &mut Stmt, mutability: Mutability) -> Result<()> {
|
||||
match stmt {
|
||||
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
|
||||
Context::new(mutability).replace_expr_match(expr);
|
||||
fn replace_expr(expr: &mut Expr, kind: ProjKind) {
|
||||
match expr {
|
||||
Expr::Match(expr) => {
|
||||
Context::new(kind).replace_expr_match(expr);
|
||||
}
|
||||
Stmt::Expr(Expr::If(expr_if)) => {
|
||||
Expr::If(expr_if) => {
|
||||
let mut expr_if = expr_if;
|
||||
while let Expr::Let(ref mut expr) = &mut *expr_if.cond {
|
||||
Context::new(mutability).replace_expr_let(expr);
|
||||
Context::new(kind).replace_expr_let(expr);
|
||||
if let Some((_, ref mut expr)) = expr_if.else_branch {
|
||||
if let Expr::If(new_expr_if) = &mut **expr {
|
||||
expr_if = new_expr_if;
|
||||
@ -31,18 +31,17 @@ fn replace_stmt(stmt: &mut Stmt, mutability: Mutability) -> Result<()> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Stmt::Local(local) => Context::new(mutability).replace_local(local)?,
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
|
||||
replace_stmt(&mut stmt, mutability)?;
|
||||
fn parse(mut stmt: Stmt, kind: ProjKind) -> Result<TokenStream> {
|
||||
match &mut stmt {
|
||||
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
|
||||
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
|
||||
Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
|
||||
Stmt::Expr(expr) | Stmt::Semi(expr, _) => replace_expr(expr, kind),
|
||||
Stmt::Local(local) => Context::new(kind).replace_local(local)?,
|
||||
Stmt::Item(Item::Fn(item)) => replace_item_fn(item, kind)?,
|
||||
Stmt::Item(Item::Impl(item)) => replace_item_impl(item, kind)?,
|
||||
Stmt::Item(Item::Use(item)) => replace_item_use(item, kind)?,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -52,28 +51,30 @@ fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
|
||||
struct Context {
|
||||
register: Option<(Ident, usize)>,
|
||||
replaced: bool,
|
||||
mutability: Mutability,
|
||||
kind: ProjKind,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
fn new(mutability: Mutability) -> Self {
|
||||
Self { register: None, replaced: false, mutability }
|
||||
fn new(kind: ProjKind) -> Self {
|
||||
Self { register: None, replaced: false, kind }
|
||||
}
|
||||
|
||||
fn update(&mut self, ident: &Ident, len: usize) {
|
||||
if self.register.is_none() {
|
||||
self.register = Some((ident.clone(), len));
|
||||
}
|
||||
self.register.get_or_insert_with(|| (ident.clone(), len));
|
||||
}
|
||||
|
||||
fn compare_paths(&self, ident: &Ident, len: usize) -> bool {
|
||||
match &self.register {
|
||||
Some((i, l)) => *l == len && ident == i,
|
||||
Some((i, l)) => *l == len && i == ident,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_local(&mut self, local: &mut Local) -> Result<()> {
|
||||
if let Some(attr) = local.attrs.find(self.kind.method_name()) {
|
||||
return Err(error!(attr, "duplicate #[{}] attribute", self.kind.method_name()));
|
||||
}
|
||||
|
||||
if let Some(Expr::Match(expr)) = local.init.as_mut().map(|(_, expr)| &mut **expr) {
|
||||
self.replace_expr_match(expr);
|
||||
}
|
||||
@ -99,7 +100,7 @@ impl Context {
|
||||
}
|
||||
|
||||
fn replace_expr_match(&mut self, expr: &mut ExprMatch) {
|
||||
expr.arms.iter_mut().for_each(|Arm { pat, .. }| self.replace_pat(pat, true))
|
||||
expr.arms.iter_mut().for_each(|arm| self.replace_pat(&mut arm.pat, true))
|
||||
}
|
||||
|
||||
fn replace_pat(&mut self, pat: &mut Pat, allow_pat_path: bool) {
|
||||
@ -135,7 +136,7 @@ impl Context {
|
||||
if self.register.is_none() || self.compare_paths(&path.segments[0].ident, len) {
|
||||
self.update(&path.segments[0].ident, len);
|
||||
self.replaced = true;
|
||||
replace_ident(&mut path.segments[0].ident, self.mutability);
|
||||
replace_ident(&mut path.segments[0].ident, self.kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,132 +156,195 @@ fn is_replaceable(pat: &Pat, allow_pat_path: bool) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_item_impl(item: &mut ItemImpl, mutability: Mutability) {
|
||||
fn replace_ident(ident: &mut Ident, kind: ProjKind) {
|
||||
*ident = kind.proj_ident(ident);
|
||||
}
|
||||
|
||||
fn replace_item_impl(item: &mut ItemImpl, kind: ProjKind) -> Result<()> {
|
||||
if let Some(attr) = item.attrs.find(kind.method_name()) {
|
||||
return Err(error!(attr, "duplicate #[{}] attribute", kind.method_name()));
|
||||
}
|
||||
|
||||
let PathSegment { ident, arguments } = match &mut *item.self_ty {
|
||||
Type::Path(TypePath { qself: None, path }) => path.segments.last_mut().unwrap(),
|
||||
_ => return,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
replace_ident(ident, mutability);
|
||||
replace_ident(ident, kind);
|
||||
|
||||
let mut lifetime_name = String::from(DEFAULT_LIFETIME_NAME);
|
||||
determine_lifetime_name(&mut lifetime_name, &item.generics.params);
|
||||
let mut lifetime_name = String::from("'pin");
|
||||
determine_lifetime_name(&mut lifetime_name, &mut item.generics);
|
||||
item.items
|
||||
.iter_mut()
|
||||
.filter_map(|i| if let ImplItem::Method(i) = i { Some(i) } else { None })
|
||||
.for_each(|item| determine_lifetime_name(&mut lifetime_name, &item.sig.generics.params));
|
||||
.for_each(|item| determine_lifetime_name(&mut lifetime_name, &mut item.sig.generics));
|
||||
let lifetime = Lifetime::new(&lifetime_name, Span::call_site());
|
||||
|
||||
insert_lifetime(&mut item.generics, lifetime.clone());
|
||||
|
||||
match arguments {
|
||||
PathArguments::None => {
|
||||
*arguments = PathArguments::AngleBracketed(syn::parse_quote!(<#lifetime>));
|
||||
*arguments = PathArguments::AngleBracketed(parse_quote!(<#lifetime>));
|
||||
}
|
||||
PathArguments::AngleBracketed(args) => {
|
||||
args.args.insert(0, syn::parse_quote!(#lifetime));
|
||||
args.args.insert(0, parse_quote!(#lifetime));
|
||||
}
|
||||
PathArguments::Parenthesized(_) => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn replace_item_fn(item: &mut ItemFn, mutability: Mutability) -> Result<()> {
|
||||
let mut visitor = FnVisitor { res: Ok(()), mutability };
|
||||
fn replace_item_fn(item: &mut ItemFn, kind: ProjKind) -> Result<()> {
|
||||
struct FnVisitor(Result<()>);
|
||||
|
||||
impl FnVisitor {
|
||||
fn visit_stmt(&mut self, node: &mut Stmt) -> Result<()> {
|
||||
match node {
|
||||
Stmt::Expr(expr) | Stmt::Semi(expr, _) => self.visit_expr(expr),
|
||||
Stmt::Local(local) => {
|
||||
visit_mut::visit_local_mut(self, local);
|
||||
|
||||
let mut prev = None;
|
||||
for &kind in &ProjKind::ALL {
|
||||
if let Some(attr) = local.attrs.find_remove(kind.method_name())? {
|
||||
if let Some(prev) = prev.replace(kind) {
|
||||
return Err(error!(
|
||||
attr,
|
||||
"attributes `{}` and `{}` are mutually exclusive",
|
||||
prev.method_name(),
|
||||
kind.method_name(),
|
||||
));
|
||||
}
|
||||
Context::new(kind).replace_local(local)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Do not recurse into nested items.
|
||||
Stmt::Item(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, node: &mut Expr) -> Result<()> {
|
||||
visit_mut::visit_expr_mut(self, node);
|
||||
match node {
|
||||
Expr::Match(expr) => {
|
||||
let mut prev = None;
|
||||
for &kind in &ProjKind::ALL {
|
||||
if let Some(attr) = expr.attrs.find_remove(kind.method_name())? {
|
||||
if let Some(prev) = prev.replace(kind) {
|
||||
return Err(error!(
|
||||
attr,
|
||||
"attributes `{}` and `{}` are mutually exclusive",
|
||||
prev.method_name(),
|
||||
kind.method_name(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(kind) = prev {
|
||||
replace_expr(node, kind);
|
||||
}
|
||||
}
|
||||
Expr::If(expr_if) => {
|
||||
if let Expr::Let(_) = &*expr_if.cond {
|
||||
let mut prev = None;
|
||||
for &kind in &ProjKind::ALL {
|
||||
if let Some(attr) = expr_if.attrs.find_remove(kind.method_name())? {
|
||||
if let Some(prev) = prev.replace(kind) {
|
||||
return Err(error!(
|
||||
attr,
|
||||
"attributes `{}` and `{}` are mutually exclusive",
|
||||
prev.method_name(),
|
||||
kind.method_name(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(kind) = prev {
|
||||
replace_expr(node, kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for FnVisitor {
|
||||
fn visit_stmt_mut(&mut self, node: &mut Stmt) {
|
||||
if self.0.is_err() {
|
||||
return;
|
||||
}
|
||||
if let Err(e) = self.visit_stmt(node) {
|
||||
self.0 = Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr_mut(&mut self, node: &mut Expr) {
|
||||
if self.0.is_err() {
|
||||
return;
|
||||
}
|
||||
if let Err(e) = self.visit_expr(node) {
|
||||
self.0 = Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, _: &mut Item) {
|
||||
// Do not recurse into nested items.
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(attr) = item.attrs.find(kind.method_name()) {
|
||||
return Err(error!(attr, "duplicate #[{}] attribute", kind.method_name()));
|
||||
}
|
||||
|
||||
let mut visitor = FnVisitor(Ok(()));
|
||||
visitor.visit_block_mut(&mut item.block);
|
||||
visitor.res
|
||||
visitor.0
|
||||
}
|
||||
|
||||
fn replace_item_use(item: &mut ItemUse, mutability: Mutability) -> Result<()> {
|
||||
let mut visitor = UseTreeVisitor { res: Ok(()), mutability };
|
||||
fn replace_item_use(item: &mut ItemUse, kind: ProjKind) -> Result<()> {
|
||||
struct UseTreeVisitor {
|
||||
res: Result<()>,
|
||||
kind: ProjKind,
|
||||
}
|
||||
|
||||
impl VisitMut for UseTreeVisitor {
|
||||
fn visit_use_tree_mut(&mut self, node: &mut UseTree) {
|
||||
if self.res.is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
match node {
|
||||
// Desugar `use tree::<name>` into `tree::__<name>Projection`.
|
||||
UseTree::Name(name) => replace_ident(&mut name.ident, self.kind),
|
||||
UseTree::Glob(glob) => {
|
||||
self.res = Err(error!(
|
||||
glob,
|
||||
"#[{}] attribute may not be used on glob imports",
|
||||
self.kind.method_name()
|
||||
));
|
||||
}
|
||||
UseTree::Rename(rename) => {
|
||||
self.res = Err(error!(
|
||||
rename,
|
||||
"#[{}] attribute may not be used on renamed imports",
|
||||
self.kind.method_name()
|
||||
));
|
||||
}
|
||||
UseTree::Path(_) | UseTree::Group(_) => visit_mut::visit_use_tree_mut(self, node),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(attr) = item.attrs.find(kind.method_name()) {
|
||||
return Err(error!(attr, "duplicate #[{}] attribute", kind.method_name()));
|
||||
}
|
||||
|
||||
let mut visitor = UseTreeVisitor { res: Ok(()), kind };
|
||||
visitor.visit_item_use_mut(item);
|
||||
visitor.res
|
||||
}
|
||||
|
||||
fn replace_ident(ident: &mut Ident, mutability: Mutability) {
|
||||
*ident = proj_ident(ident, mutability);
|
||||
}
|
||||
|
||||
// =================================================================================================
|
||||
// visitors
|
||||
|
||||
struct FnVisitor {
|
||||
res: Result<()>,
|
||||
mutability: Mutability,
|
||||
}
|
||||
|
||||
impl FnVisitor {
|
||||
/// Returns the attribute name.
|
||||
fn name(&self) -> &str {
|
||||
if self.mutability == Mutable { "project" } else { "project_ref" }
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, node: &mut Stmt) -> Result<()> {
|
||||
let attr = match node {
|
||||
Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
|
||||
expr.attrs.find_remove(self.name())?
|
||||
}
|
||||
Stmt::Local(local) => local.attrs.find_remove(self.name())?,
|
||||
Stmt::Expr(Expr::If(expr_if)) => {
|
||||
if let Expr::Let(_) = &*expr_if.cond {
|
||||
expr_if.attrs.find_remove(self.name())?
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => return Ok(()),
|
||||
};
|
||||
if let Some(attr) = attr {
|
||||
parse_as_empty(&attr.tokens)?;
|
||||
replace_stmt(node, self.mutability)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for FnVisitor {
|
||||
fn visit_stmt_mut(&mut self, node: &mut Stmt) {
|
||||
if self.res.is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
visit_mut::visit_stmt_mut(self, node);
|
||||
|
||||
if let Err(e) = self.visit_stmt(node) {
|
||||
self.res = Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, _: &mut Item) {
|
||||
// Do not recurse into nested items.
|
||||
}
|
||||
}
|
||||
|
||||
struct UseTreeVisitor {
|
||||
res: Result<()>,
|
||||
mutability: Mutability,
|
||||
}
|
||||
|
||||
impl VisitMut for UseTreeVisitor {
|
||||
fn visit_use_tree_mut(&mut self, node: &mut UseTree) {
|
||||
if self.res.is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
match node {
|
||||
// Desugar `use tree::<name>` into `tree::__<name>Projection`.
|
||||
UseTree::Name(name) => replace_ident(&mut name.ident, self.mutability),
|
||||
UseTree::Glob(glob) => {
|
||||
self.res =
|
||||
Err(error!(glob, "#[project] attribute may not be used on glob imports"));
|
||||
}
|
||||
UseTree::Rename(rename) => {
|
||||
// TODO: Consider allowing the projected type to be renamed by `#[project] use Foo as Bar`.
|
||||
self.res =
|
||||
Err(error!(rename, "#[project] attribute may not be used on renamed imports"));
|
||||
}
|
||||
node @ UseTree::Path(_) | node @ UseTree::Group(_) => {
|
||||
visit_mut::visit_use_tree_mut(self, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
322
third_party/rust/pin-project-internal/src/utils.rs
vendored
322
third_party/rust/pin-project-internal/src/utils.rs
vendored
@ -1,21 +1,15 @@
|
||||
use std::mem;
|
||||
use std::{iter::FromIterator, mem};
|
||||
|
||||
use proc_macro2::{Group, TokenStream, TokenTree};
|
||||
use quote::{format_ident, quote_spanned};
|
||||
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
|
||||
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||
use syn::{
|
||||
parse::{ParseBuffer, ParseStream},
|
||||
parse::{Parse, ParseBuffer, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
token::{self, Comma},
|
||||
visit_mut::{self, VisitMut},
|
||||
*,
|
||||
};
|
||||
|
||||
pub(crate) const DEFAULT_LIFETIME_NAME: &str = "'pin";
|
||||
pub(crate) const CURRENT_PRIVATE_MODULE: &str = "__private";
|
||||
|
||||
pub(crate) type Variants = Punctuated<Variant, token::Comma>;
|
||||
|
||||
pub(crate) use Mutability::{Immutable, Mutable};
|
||||
pub(crate) type Variants = Punctuated<Variant, Token![,]>;
|
||||
|
||||
macro_rules! error {
|
||||
($span:expr, $msg:expr) => {
|
||||
@ -26,37 +20,59 @@ macro_rules! error {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum Mutability {
|
||||
Mutable,
|
||||
Immutable,
|
||||
macro_rules! parse_quote_spanned {
|
||||
($span:expr => $($tt:tt)*) => {
|
||||
syn::parse2(quote::quote_spanned!($span => $($tt)*)).unwrap_or_else(|e| panic!("{}", e))
|
||||
};
|
||||
}
|
||||
|
||||
/// Creates the ident of projected type from the ident of the original type.
|
||||
pub(crate) fn proj_ident(ident: &Ident, mutability: Mutability) -> Ident {
|
||||
if mutability == Mutable {
|
||||
format_ident!("__{}Projection", ident)
|
||||
} else {
|
||||
format_ident!("__{}ProjectionRef", ident)
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub(crate) enum ProjKind {
|
||||
Mutable,
|
||||
Immutable,
|
||||
Owned,
|
||||
}
|
||||
|
||||
impl ProjKind {
|
||||
pub(crate) const ALL: [Self; 3] = [ProjKind::Mutable, ProjKind::Immutable, ProjKind::Owned];
|
||||
|
||||
/// Returns the name of the projection method.
|
||||
pub(crate) fn method_name(self) -> &'static str {
|
||||
match self {
|
||||
ProjKind::Mutable => "project",
|
||||
ProjKind::Immutable => "project_ref",
|
||||
ProjKind::Owned => "project_replace",
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the ident of the projected type from the ident of the original
|
||||
/// type.
|
||||
pub(crate) fn proj_ident(self, ident: &Ident) -> Ident {
|
||||
match self {
|
||||
ProjKind::Mutable => format_ident!("__{}Projection", ident),
|
||||
ProjKind::Immutable => format_ident!("__{}ProjectionRef", ident),
|
||||
ProjKind::Owned => format_ident!("__{}ProjectionOwned", ident),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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: &Punctuated<GenericParam, Comma>,
|
||||
) {
|
||||
let existing_lifetimes: Vec<String> = generics
|
||||
.iter()
|
||||
.filter_map(|param| {
|
||||
if let GenericParam::Lifetime(LifetimeDef { lifetime, .. }) = param {
|
||||
Some(lifetime.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
while existing_lifetimes.iter().any(|name| name.starts_with(&**lifetime_name)) {
|
||||
/// 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('_');
|
||||
}
|
||||
}
|
||||
@ -68,68 +84,70 @@ pub(crate) fn insert_lifetime_and_bound(
|
||||
generics: &mut Generics,
|
||||
lifetime: Lifetime,
|
||||
orig_generics: &Generics,
|
||||
orig_ident: Ident,
|
||||
orig_ident: &Ident,
|
||||
) -> WherePredicate {
|
||||
insert_lifetime(generics, lifetime.clone());
|
||||
|
||||
let orig_type: syn::Type = syn::parse_quote!(#orig_ident #orig_generics);
|
||||
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: syn::token::Colon::default(),
|
||||
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) {
|
||||
if generics.lt_token.is_none() {
|
||||
generics.lt_token = Some(token::Lt::default())
|
||||
}
|
||||
if generics.gt_token.is_none() {
|
||||
generics.gt_token = Some(token::Gt::default())
|
||||
}
|
||||
|
||||
generics.params.insert(
|
||||
0,
|
||||
GenericParam::Lifetime(LifetimeDef {
|
||||
attrs: Vec::new(),
|
||||
lifetime,
|
||||
colon_token: None,
|
||||
bounds: Punctuated::new(),
|
||||
}),
|
||||
);
|
||||
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 type and projection method.
|
||||
pub(crate) fn determine_visibility(vis: &Visibility) -> Visibility {
|
||||
if let Visibility::Public(token) = vis {
|
||||
syn::parse2(quote_spanned! { token.pub_token.span =>
|
||||
pub(crate)
|
||||
})
|
||||
.unwrap()
|
||||
parse_quote_spanned!(token.pub_token.span => pub(crate))
|
||||
} else {
|
||||
vis.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Check 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`.
|
||||
/// 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 { Err(error!(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>;
|
||||
fn find_exact(&self, ident: &str) -> Result<Option<&Attribute>>;
|
||||
}
|
||||
|
||||
pub(crate) trait VecExt {
|
||||
@ -141,11 +159,10 @@ impl SliceExt for [Attribute] {
|
||||
self.iter()
|
||||
.try_fold((0, None), |(i, mut prev), attr| {
|
||||
if attr.path.is_ident(ident) {
|
||||
if prev.is_some() {
|
||||
if prev.replace(i).is_some() {
|
||||
return Err(error!(attr, "duplicate #[{}] attribute", ident));
|
||||
}
|
||||
parse_as_empty(&attr.tokens)?;
|
||||
prev = Some(i);
|
||||
}
|
||||
Ok((i + 1, prev))
|
||||
})
|
||||
@ -155,10 +172,6 @@ impl SliceExt for [Attribute] {
|
||||
fn find(&self, ident: &str) -> Option<&Attribute> {
|
||||
self.iter().position(|attr| attr.path.is_ident(ident)).and_then(|i| self.get(i))
|
||||
}
|
||||
|
||||
fn find_exact(&self, ident: &str) -> Result<Option<&Attribute>> {
|
||||
self.position_exact(ident).map(|pos| pos.and_then(|i| self.get(i)))
|
||||
}
|
||||
}
|
||||
|
||||
impl VecExt for Vec<Attribute> {
|
||||
@ -191,18 +204,16 @@ impl<'a> ParseBufferExt<'a> for ParseBuffer<'a> {
|
||||
// visitors
|
||||
|
||||
// Replace `self`/`Self` with `__self`/`self_ty`.
|
||||
// Based on https://github.com/dtolnay/async-trait/blob/0.1.22/src/receiver.rs
|
||||
// Based on https://github.com/dtolnay/async-trait/blob/0.1.35/src/receiver.rs
|
||||
|
||||
pub(crate) struct ReplaceReceiver<'a> {
|
||||
self_ty: &'a Type,
|
||||
}
|
||||
pub(crate) struct ReplaceReceiver<'a>(pub(crate) &'a TypePath);
|
||||
|
||||
impl<'a> ReplaceReceiver<'a> {
|
||||
pub(crate) fn new(self_ty: &'a Type) -> Self {
|
||||
Self { self_ty }
|
||||
impl ReplaceReceiver<'_> {
|
||||
fn self_ty(&self, span: Span) -> TypePath {
|
||||
respan(self.0, span)
|
||||
}
|
||||
|
||||
fn self_to_qself(&mut self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
if path.leading_colon.is_some() {
|
||||
return;
|
||||
}
|
||||
@ -217,39 +228,91 @@ impl<'a> ReplaceReceiver<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
let span = first.ident.span();
|
||||
*qself = Some(QSelf {
|
||||
lt_token: token::Lt::default(),
|
||||
ty: Box::new(self.self_ty.clone()),
|
||||
lt_token: Token![<](span),
|
||||
ty: Box::new(self.self_ty(span).into()),
|
||||
position: 0,
|
||||
as_token: None,
|
||||
gt_token: token::Gt::default(),
|
||||
gt_token: Token![>](span),
|
||||
});
|
||||
|
||||
match path.segments.pairs().next().unwrap().punct() {
|
||||
Some(&&colon) => path.leading_colon = Some(colon),
|
||||
None => return,
|
||||
}
|
||||
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 let Type::Path(self_ty) = &self.self_ty {
|
||||
*path = self_ty.path.clone();
|
||||
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::Colon2::default());
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let span = path.segments[0].ident.span();
|
||||
let msg = "Self type of this impl is unsupported in expression position";
|
||||
let error = Error::new(span, msg).to_compile_error();
|
||||
*path = parse_quote!(::core::marker::PhantomData::<#error>);
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,7 +321,7 @@ impl VisitMut for ReplaceReceiver<'_> {
|
||||
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.clone();
|
||||
*ty = self.self_ty(node.path.segments[0].ident.span()).into();
|
||||
} else {
|
||||
self.visit_type_path_mut(node);
|
||||
}
|
||||
@ -285,26 +348,48 @@ impl VisitMut for ReplaceReceiver<'_> {
|
||||
}
|
||||
|
||||
fn visit_expr_struct_mut(&mut self, expr: &mut ExprStruct) {
|
||||
if expr.path.is_ident("Self") {
|
||||
self.self_to_expr_path(&mut expr.path);
|
||||
}
|
||||
self.self_to_expr_path(&mut expr.path);
|
||||
visit_mut::visit_expr_struct_mut(self, expr);
|
||||
}
|
||||
|
||||
fn visit_macro_mut(&mut self, node: &mut Macro) {
|
||||
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_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(node.tokens.clone()) {
|
||||
node.tokens = fold_token_stream(node.tokens.clone());
|
||||
if !contains_fn(mac.tokens.clone()) {
|
||||
self.visit_token_stream(&mut mac.tokens);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, _: &mut Item) {
|
||||
// Do not recurse into nested items.
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_fn(tokens: TokenStream) -> bool {
|
||||
@ -315,25 +400,10 @@ fn contains_fn(tokens: TokenStream) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_token_stream(tokens: TokenStream) -> TokenStream {
|
||||
tokens
|
||||
.into_iter()
|
||||
.map(|tt| match tt {
|
||||
TokenTree::Ident(mut ident) => {
|
||||
prepend_underscore_to_self(&mut ident);
|
||||
TokenTree::Ident(ident)
|
||||
}
|
||||
TokenTree::Group(group) => {
|
||||
let content = fold_token_stream(group.stream());
|
||||
TokenTree::Group(Group::new(group.delimiter(), content))
|
||||
}
|
||||
other => other,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn prepend_underscore_to_self(ident: &mut Ident) {
|
||||
if ident == "self" {
|
||||
pub(crate) fn prepend_underscore_to_self(ident: &mut Ident) -> bool {
|
||||
let modified = ident == "self";
|
||||
if modified {
|
||||
*ident = Ident::new("__self", ident.span());
|
||||
}
|
||||
modified
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
467
third_party/rust/pin-project/CHANGELOG.md
vendored
467
third_party/rust/pin-project/CHANGELOG.md
vendored
@ -6,133 +6,324 @@ This project adheres to [Semantic Versioning](https://semver.org).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.4.28] - 2021-03-28
|
||||
|
||||
- [Fix `unused_must_use` warning on unused borrows, which will be added to rustc in the future.](https://github.com/taiki-e/pin-project/pull/322) See [#322](https://github.com/taiki-e/pin-project/pull/322) for more details.
|
||||
|
||||
(Note: 1.0 does not have this problem.)
|
||||
|
||||
## [0.4.27] - 2020-10-11
|
||||
|
||||
- Update minimal version of `syn` to 1.0.44
|
||||
|
||||
## [0.4.26] - 2020-10-04
|
||||
|
||||
- [Fix drop order of pinned fields in `project_replace`.](https://github.com/taiki-e/pin-project/pull/287)
|
||||
|
||||
## [0.4.25] - 2020-10-01
|
||||
|
||||
- [Suppress `drop_bounds` lint, which will be added to rustc in the future.](https://github.com/taiki-e/pin-project/pull/273) See [#272](https://github.com/taiki-e/pin-project/issues/272) for more details.
|
||||
|
||||
(Note: 1.0.0-alpha.1 already contains this change.)
|
||||
|
||||
## [0.4.24] - 2020-09-26
|
||||
|
||||
- [Fix compatibility of generated code with `forbid(future_incompatible)`.](https://github.com/taiki-e/pin-project/pull/282)
|
||||
|
||||
Note: This does not guarantee compatibility with `forbid(future_incompatible)` in the future.
|
||||
If rustc adds a new lint, we may not be able to keep this.
|
||||
|
||||
## [0.4.23] - 2020-07-27
|
||||
|
||||
- [Fix compile error with `?Sized` type parameters.](https://github.com/taiki-e/pin-project/pull/263)
|
||||
|
||||
## [0.4.22] - 2020-06-14
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
## [0.4.21] - 2020-06-13
|
||||
|
||||
- [Deprecated `#[project]`, `#[project_ref]`, and `#[project_replace]` attributes due to some unfixable limitations.](https://github.com/taiki-e/pin-project/pull/244)
|
||||
|
||||
Consider naming the projected type by passing an argument with the same name as the method to the `#[pin_project]` attribute instead.
|
||||
|
||||
```rust
|
||||
#[pin_project(project = EnumProj)]
|
||||
enum Enum<T> {
|
||||
Variant(#[pin] T),
|
||||
}
|
||||
|
||||
fn func<T>(x: Pin<&mut Enum<T>>) {
|
||||
match x.project() {
|
||||
EnumProj::Variant(y) => {
|
||||
let _: Pin<&mut T> = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See [#225](https://github.com/taiki-e/pin-project/pull/225) for more details.
|
||||
|
||||
- [Support `Self` in fields and generics in type definitions.](https://github.com/taiki-e/pin-project/pull/245)
|
||||
|
||||
- [Fix errors involving *"`self` value is a keyword only available in methods with `self` parameter"* in apparently correct code.](https://github.com/taiki-e/pin-project/pull/250)
|
||||
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.20] - 2020-06-07
|
||||
|
||||
- [You can now use `project_replace` argument without Replace argument.](https://github.com/taiki-e/pin-project/pull/243)
|
||||
This used to require you to specify both.
|
||||
|
||||
```diff
|
||||
- #[pin_project(Replace, project_replace = EnumProjOwn)]
|
||||
+ #[pin_project(project_replace = EnumProjOwn)]
|
||||
enum Enum<T> {
|
||||
Variant(#[pin] T)
|
||||
}
|
||||
```
|
||||
|
||||
- [Make `project_replace` argument an alias for `Replace` argument so that it can be used without a value.](https://github.com/taiki-e/pin-project/pull/243)
|
||||
|
||||
```rust
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<T> {
|
||||
Variant(#[pin] T)
|
||||
}
|
||||
```
|
||||
|
||||
*The `Replace` argument will be deprecated in the future.*
|
||||
|
||||
- [Suppress `unreachable_pub` lint in generated code.](https://github.com/taiki-e/pin-project/pull/240)
|
||||
|
||||
## [0.4.19] - 2020-06-04
|
||||
|
||||
- [Suppress `unused_results` lint in generated code.](https://github.com/taiki-e/pin-project/pull/239)
|
||||
|
||||
## [0.4.18] - 2020-06-04
|
||||
|
||||
- [Support `Self` in more syntax positions inside `#[pinned_drop]` impl.](https://github.com/taiki-e/pin-project/pull/230)
|
||||
|
||||
- [Suppress `clippy::type_repetition_in_bounds` and `clippy::used_underscore_binding` lints in generated code.](https://github.com/taiki-e/pin-project/pull/233)
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.17] - 2020-05-18
|
||||
|
||||
- [Support naming the projection types.](https://github.com/taiki-e/pin-project/pull/202)
|
||||
|
||||
By passing an argument with the same name as the method to the attribute, you can name the projection type returned from the method:
|
||||
|
||||
```rust
|
||||
#[pin_project(project = EnumProj)]
|
||||
enum Enum<T> {
|
||||
Variant(#[pin] T),
|
||||
}
|
||||
|
||||
fn func<T>(x: Pin<&mut Enum<T>>) {
|
||||
match x.project() {
|
||||
EnumProj::Variant(y) => {
|
||||
let _: Pin<&mut T> = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## [0.4.16] - 2020-05-11
|
||||
|
||||
- [Fix an issue that users can call internal function generated by `#[pinned_drop]`.](https://github.com/taiki-e/pin-project/pull/223)
|
||||
|
||||
## [0.4.15] - 2020-05-10
|
||||
|
||||
- [`#[project]` attribute can now handle all `project*` attributes in that scope with one wrapper attribute.](https://github.com/taiki-e/pin-project/pull/220)
|
||||
|
||||
## [0.4.14] - 2020-05-09
|
||||
|
||||
- [Add `!Unpin` option to `#[pin_project]` attribute for guarantee the type is `!Unpin`.](https://github.com/taiki-e/pin-project/pull/219)
|
||||
|
||||
```rust
|
||||
#[pin_project(!Unpin)]
|
||||
struct Struct<T, U> {
|
||||
field: T,
|
||||
}
|
||||
```
|
||||
|
||||
This is equivalent to use `#[pin]` attribute for `PhantomPinned` field.
|
||||
|
||||
```rust
|
||||
#[pin_project]
|
||||
struct Struct<T, U> {
|
||||
field: T,
|
||||
#[pin] // Note that using `PhantomPinned` without `#[pin]` attribute has no effect.
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
```
|
||||
|
||||
*[Note: This raises the minimum supported Rust version of this crate from Rust 1.33 to Rust 1.34.](https://github.com/taiki-e/pin-project/pull/219#pullrequestreview-408644187)*
|
||||
|
||||
- [Fix an issue where duplicate `#[project]` attributes were ignored.](https://github.com/taiki-e/pin-project/pull/218)
|
||||
|
||||
- [Suppress `single_use_lifetimes` lint in generated code.](https://github.com/taiki-e/pin-project/pull/217)
|
||||
|
||||
- [Support overlapping lifetime names in HRTB.](https://github.com/taiki-e/pin-project/pull/217)
|
||||
|
||||
- [Hide generated items from --document-private-items.](https://github.com/taiki-e/pin-project/pull/211) See [#211](https://github.com/taiki-e/pin-project/pull/211) for details.
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
## [0.4.13] - 2020-05-07
|
||||
|
||||
- [Fix a regression in 0.4.11.](https://github.com/taiki-e/pin-project/pull/207)
|
||||
|
||||
Changes from [0.4.10](https://github.com/taiki-e/pin-project/releases/tag/v0.4.10) and [0.4.12](https://github.com/taiki-e/pin-project/releases/tag/v0.4.12):
|
||||
|
||||
- [Fix an issue that `#[project]` on non-statement expression does not work without unstable features.](https://github.com/taiki-e/pin-project/pull/197)
|
||||
|
||||
- [Support overwriting the name of core crate.](https://github.com/taiki-e/pin-project/pull/199)
|
||||
|
||||
- [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.](https://github.com/taiki-e/pin-project/pull/200)
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.12] - 2020-05-07
|
||||
|
||||
- A release to avoid [a regression in 0.4.11](https://github.com/taiki-e/pin-project/issues/206). No code changes from [0.4.10](https://github.com/taiki-e/pin-project/releases/tag/v0.4.10).
|
||||
|
||||
## [0.4.11] - 2020-05-07
|
||||
|
||||
**Note: This release has been yanked.** See [#206](https://github.com/taiki-e/pin-project/issues/206) for details.
|
||||
|
||||
- [Fix an issue that `#[project]` on non-statement expression does not work without unstable features.](https://github.com/taiki-e/pin-project/pull/197)
|
||||
|
||||
- [Support overwriting the name of core crate.](https://github.com/taiki-e/pin-project/pull/199)
|
||||
|
||||
- [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.](https://github.com/taiki-e/pin-project/pull/200)
|
||||
|
||||
- Documentation improvements.
|
||||
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.10] - 2020-05-04
|
||||
|
||||
- [Add `project_replace` method and `#[project_replace]` attribute.](https://github.com/taiki-e/pin-project/pull/194)
|
||||
`project_replace` method is optional and can be enabled by passing the `Replace` argument to `#[pin_project]` attribute.
|
||||
See [the documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#project_replace) for more details.
|
||||
|
||||
- [Support `Self` and `self` in more syntax positions inside `#[pinned_drop]` impl.](https://github.com/taiki-e/pin-project/pull/190)
|
||||
|
||||
- [Hide all generated items except for projected types from calling code.](https://github.com/taiki-e/pin-project/pull/192) See [#192](https://github.com/taiki-e/pin-project/pull/192) for details.
|
||||
|
||||
## [0.4.9] - 2020-04-14
|
||||
|
||||
* [Fixed lifetime inference error when associated types are used in fields.][188]
|
||||
- [Fix lifetime inference error when associated types are used in fields.](https://github.com/taiki-e/pin-project/pull/188)
|
||||
|
||||
* [Fixed compile error with tuple structs with `where` clauses.][186]
|
||||
- [Fix compile error with tuple structs with `where` clauses.](https://github.com/taiki-e/pin-project/pull/186)
|
||||
|
||||
* [`#[project]` attribute can now be used for `if let` expressions.][181]
|
||||
|
||||
[188]: https://github.com/taiki-e/pin-project/pull/188
|
||||
[186]: https://github.com/taiki-e/pin-project/pull/186
|
||||
[181]: https://github.com/taiki-e/pin-project/pull/181
|
||||
- [`#[project]` attribute can now be used for `if let` expressions.](https://github.com/taiki-e/pin-project/pull/181)
|
||||
|
||||
## [0.4.8] - 2020-01-27
|
||||
|
||||
* [Ensured that users cannot implement `PinnedDrop` without proper attribute argument.][180]
|
||||
- [Ensure that users cannot implement `PinnedDrop` without proper attribute argument.](https://github.com/taiki-e/pin-project/pull/180)
|
||||
|
||||
[180]: https://github.com/taiki-e/pin-project/pull/180
|
||||
- [Fix use of `Self` in expression position inside `#[pinned_drop]` impl.](https://github.com/taiki-e/pin-project/pull/177)
|
||||
|
||||
## [0.4.7] - 2020-01-20
|
||||
|
||||
* [Fixed support for lifetime bounds.][176]
|
||||
|
||||
[176]: https://github.com/taiki-e/pin-project/pull/176
|
||||
- [Fix support for lifetime bounds.](https://github.com/taiki-e/pin-project/pull/176)
|
||||
|
||||
## [0.4.6] - 2019-11-20
|
||||
|
||||
* [Fixed compile error when there is `Self` in the where clause.][169]
|
||||
|
||||
[169]: https://github.com/taiki-e/pin-project/pull/169
|
||||
- [Fix compile error when there is `Self` in the where clause.](https://github.com/taiki-e/pin-project/pull/169)
|
||||
|
||||
## [0.4.5] - 2019-10-21
|
||||
|
||||
* [Fixed compile error with `dyn` types.][158]
|
||||
|
||||
[158]: https://github.com/taiki-e/pin-project/pull/158
|
||||
- [Fix compile error with `dyn` types.](https://github.com/taiki-e/pin-project/pull/158)
|
||||
|
||||
## [0.4.4] - 2019-10-17
|
||||
|
||||
* [Fixed an issue where `PinnedDrop` implementations can call unsafe code without an unsafe block.][149]
|
||||
- [Fix an issue where `PinnedDrop` implementations can call unsafe code without an unsafe block.](https://github.com/taiki-e/pin-project/pull/149)
|
||||
|
||||
[149]: https://github.com/taiki-e/pin-project/pull/149
|
||||
## [0.4.3] - 2019-10-15
|
||||
|
||||
## [0.4.3] - 2019-10-15 - YANKED
|
||||
**Note: This release has been yanked.** See [#148](https://github.com/taiki-e/pin-project/pull/148) for details.
|
||||
|
||||
* [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.][135]
|
||||
- [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.](https://github.com/taiki-e/pin-project/pull/135)
|
||||
|
||||
* [`#[pin_project]` can now interoperate with `#[cfg()]` on tuple structs and tuple variants.][135]
|
||||
- [`#[pin_project]` can now interoperate with `#[cfg()]` on tuple structs and tuple variants.](https://github.com/taiki-e/pin-project/pull/135)
|
||||
|
||||
* [Fixed support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`][120]
|
||||
- [Fix support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`](https://github.com/taiki-e/pin-project/pull/120)
|
||||
|
||||
[120]: https://github.com/taiki-e/pin-project/pull/120
|
||||
[135]: https://github.com/taiki-e/pin-project/pull/135
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.2] - 2019-09-29 - YANKED
|
||||
## [0.4.2] - 2019-09-29
|
||||
|
||||
* [Fixed support for DSTs(Dynamically Sized Types).][113]
|
||||
**Note: This release has been yanked.** See [#148](https://github.com/taiki-e/pin-project/pull/148) for details.
|
||||
|
||||
[113]: https://github.com/taiki-e/pin-project/pull/113
|
||||
- [Fix support for DSTs(Dynamically Sized Types).](https://github.com/taiki-e/pin-project/pull/113)
|
||||
|
||||
## [0.4.1] - 2019-09-26 - YANKED
|
||||
## [0.4.1] - 2019-09-26
|
||||
|
||||
* [Fixed an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.][111]
|
||||
**Note: This release has been yanked.** See [#148](https://github.com/taiki-e/pin-project/pull/148) for details.
|
||||
|
||||
[111]: https://github.com/taiki-e/pin-project/pull/111
|
||||
- [Fix an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.](https://github.com/taiki-e/pin-project/pull/111)
|
||||
|
||||
## [0.4.0] - 2019-09-25 - YANKED
|
||||
## [0.4.0] - 2019-09-25
|
||||
|
||||
* [**Pin projection has become a safe operation.**][18] In the absence of other unsafe code that you write, it is impossible to cause undefined behavior.
|
||||
**Note: This release has been yanked.** See [#148](https://github.com/taiki-e/pin-project/pull/148) for details.
|
||||
|
||||
* `#[unsafe_project]` attribute has been replaced with `#[pin_project]` attribute. ([#18][18], [#33][33])
|
||||
- [**Pin projection has become a safe operation.**](https://github.com/taiki-e/pin-project/pull/18) In the absence of other unsafe code that you write, it is impossible to cause undefined behavior.
|
||||
|
||||
* [The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.][18]
|
||||
- `#[unsafe_project]` attribute has been replaced with `#[pin_project]` attribute. ([#18](https://github.com/taiki-e/pin-project/pull/18), [#33](https://github.com/taiki-e/pin-project/pull/33))
|
||||
|
||||
* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl. ([#18][18], [#33][33], [#86][86])
|
||||
- [The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.](https://github.com/taiki-e/pin-project/pull/18)
|
||||
|
||||
* [`Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.][18]
|
||||
- Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl. ([#18](https://github.com/taiki-e/pin-project/pull/18), [#33](https://github.com/taiki-e/pin-project/pull/33), [#86](https://github.com/taiki-e/pin-project/pull/86))
|
||||
|
||||
* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
|
||||
- [`Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.](https://github.com/taiki-e/pin-project/pull/18)
|
||||
|
||||
* [`#[pin_project]` can now be used for public type with private field types.][53]
|
||||
- [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.](https://github.com/taiki-e/pin-project/pull/96)
|
||||
|
||||
* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
|
||||
- [`#[pin_project]` can now be used for public type with private field types.](https://github.com/taiki-e/pin-project/pull/53)
|
||||
|
||||
* [Added `project_ref` method to `#[pin_project]` types.][93]
|
||||
- [`#[pin_project]` can now interoperate with `#[cfg()]`.](https://github.com/taiki-e/pin-project/pull/77)
|
||||
|
||||
* [Added `#[project_ref]` attribute.][93]
|
||||
- [Add `project_ref` method to `#[pin_project]` types.](https://github.com/taiki-e/pin-project/pull/93)
|
||||
|
||||
* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
|
||||
- [Add `#[project_ref]` attribute.](https://github.com/taiki-e/pin-project/pull/93)
|
||||
|
||||
* [`#[project]` attribute can now be used for `impl` blocks.][46]
|
||||
- [Remove "project_attr" feature and always enable `#[project]` attribute.](https://github.com/taiki-e/pin-project/pull/94)
|
||||
|
||||
* [`#[project]` attribute can now be used for `use` statements.][85]
|
||||
- [`#[project]` attribute can now be used for `impl` blocks.](https://github.com/taiki-e/pin-project/pull/46)
|
||||
|
||||
* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
|
||||
- [`#[project]` attribute can now be used for `use` statements.](https://github.com/taiki-e/pin-project/pull/85)
|
||||
|
||||
- [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.](https://github.com/taiki-e/pin-project/pull/51)
|
||||
|
||||
Changes since the 0.4.0-beta.1 release:
|
||||
|
||||
* [Fixed an issue that caused an error when using `#[pin_project(UnsafeUnpin)]` and not providing a manual `UnsafeUnpin` implementation on a type with no generics or lifetime.][107]
|
||||
|
||||
[18]: https://github.com/taiki-e/pin-project/pull/18
|
||||
[33]: https://github.com/taiki-e/pin-project/pull/107
|
||||
[107]: https://github.com/taiki-e/pin-project/pull/107
|
||||
- [Fix an issue that caused an error when using `#[pin_project(UnsafeUnpin)]` and not providing a manual `UnsafeUnpin` implementation on a type with no generics or lifetime.](https://github.com/taiki-e/pin-project/pull/107)
|
||||
|
||||
## [0.4.0-beta.1] - 2019-09-21
|
||||
|
||||
* [Changed the argument type of project method back to `self: Pin<&mut Self>`.][90]
|
||||
- [Change the argument type of project method back to `self: Pin<&mut Self>`.](https://github.com/taiki-e/pin-project/pull/90)
|
||||
|
||||
* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
|
||||
- [Remove "project_attr" feature and always enable `#[project]` attribute.](https://github.com/taiki-e/pin-project/pull/94)
|
||||
|
||||
* [Removed "renamed" feature.][100]
|
||||
- [Remove "renamed" feature.](https://github.com/taiki-e/pin-project/pull/100)
|
||||
|
||||
* [`#[project]` attribute can now be used for `use` statements.][85]
|
||||
- [`#[project]` attribute can now be used for `use` statements.](https://github.com/taiki-e/pin-project/pull/85)
|
||||
|
||||
* [Added `project_ref` method and `#[project_ref]` attribute.][93]
|
||||
- [Add `project_ref` method and `#[project_ref]` attribute.](https://github.com/taiki-e/pin-project/pull/93)
|
||||
|
||||
* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
|
||||
|
||||
[85]: https://github.com/taiki-e/pin-project/pull/85
|
||||
[90]: https://github.com/taiki-e/pin-project/pull/90
|
||||
[93]: https://github.com/taiki-e/pin-project/pull/93
|
||||
[94]: https://github.com/taiki-e/pin-project/pull/94
|
||||
[96]: https://github.com/taiki-e/pin-project/pull/96
|
||||
[100]: https://github.com/taiki-e/pin-project/pull/100
|
||||
- [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.](https://github.com/taiki-e/pin-project/pull/96)
|
||||
|
||||
## [0.4.0-alpha.11] - 2019-09-11
|
||||
|
||||
* [Changed #[pinned_drop] to trait implementation.][86]
|
||||
- [Change #[pinned_drop] to trait implementation.](https://github.com/taiki-e/pin-project/pull/86)
|
||||
|
||||
```rust
|
||||
#[pinned_drop]
|
||||
@ -143,184 +334,186 @@ Changes since the 0.4.0-beta.1 release:
|
||||
}
|
||||
```
|
||||
|
||||
* Added some examples and generated code.
|
||||
- Add some examples and generated code.
|
||||
|
||||
* Improve error messages.
|
||||
|
||||
[86]: https://github.com/taiki-e/pin-project/pull/86
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.4.0-alpha.10] - 2019-09-07
|
||||
|
||||
* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
|
||||
- [`#[pin_project]` can now interoperate with `#[cfg()]`.](https://github.com/taiki-e/pin-project/pull/77)
|
||||
|
||||
* Improved documentation.
|
||||
|
||||
[77]: https://github.com/taiki-e/pin-project/pull/77
|
||||
- Documentation improvements.
|
||||
|
||||
## [0.4.0-alpha.9] - 2019-09-05
|
||||
|
||||
* [Added 'project_into' method to #[pin_project] types][69]. This can be useful when returning a pin projection from a method.
|
||||
- [Add `project_into` method to `#[pin_project]` types](https://github.com/taiki-e/pin-project/pull/69). This can be useful when returning a pin projection from a method.
|
||||
|
||||
```rust
|
||||
fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
|
||||
self.project_into().pinned
|
||||
}
|
||||
```
|
||||
|
||||
* [Prevented UnpinStruct from appearing in the document by default.][71] See [taiki-e/pin-project#71][71] for more details.
|
||||
|
||||
[69]: https://github.com/taiki-e/pin-project/pull/69
|
||||
[71]: https://github.com/taiki-e/pin-project/pull/69
|
||||
- [Prevent `UnpinStruct` from appearing in the document by default.](https://github.com/taiki-e/pin-project/pull/71) See [#71](https://github.com/taiki-e/pin-project/pull/71) for more details.
|
||||
|
||||
## [0.4.0-alpha.8] - 2019-09-03
|
||||
|
||||
* [Improved document of generated code.][62]. Also added an option to control the document of generated code. See [taiki-e/pin-project#62][62] for more details.
|
||||
- [Improve document of generated code.](https://github.com/taiki-e/pin-project/pull/62). Also added an option to control the document of generated code. See [#62](https://github.com/taiki-e/pin-project/pull/62) for more details.
|
||||
|
||||
* [Improved error messages][61]
|
||||
|
||||
[61]: https://github.com/taiki-e/pin-project/pull/61
|
||||
[62]: https://github.com/taiki-e/pin-project/pull/62
|
||||
- [Diagnostic improvements.](https://github.com/taiki-e/pin-project/pull/61)
|
||||
|
||||
## [0.4.0-alpha.7] - 2019-09-02
|
||||
|
||||
* [Applied `#[allow(dead_code)]` to generated types.][57]
|
||||
|
||||
[57]: https://github.com/taiki-e/pin-project/pull/57
|
||||
- [Suppress `dead_code` lint in generated types.](https://github.com/taiki-e/pin-project/pull/57)
|
||||
|
||||
## [0.4.0-alpha.6] - 2019-09-01
|
||||
|
||||
* [Allowed using `#[pin_project]` type with private field types][53]
|
||||
|
||||
[53]: https://github.com/taiki-e/pin-project/pull/53
|
||||
- [Allow using `#[pin_project]` type with private field types](https://github.com/taiki-e/pin-project/pull/53)
|
||||
|
||||
## [0.4.0-alpha.5] - 2019-08-24
|
||||
|
||||
* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
|
||||
|
||||
[51]: https://github.com/taiki-e/pin-project/pull/51
|
||||
- [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.](https://github.com/taiki-e/pin-project/pull/51)
|
||||
|
||||
## [0.4.0-alpha.4] - 2019-08-23
|
||||
|
||||
* Avoided clippy::drop_bounds lint in generated code.
|
||||
- Suppress `clippy::drop_bounds` lint in generated code.
|
||||
|
||||
## [0.4.0-alpha.3] - 2019-08-23
|
||||
|
||||
* [Changed `project` method generated by `#[pin_project]` attribute to take an `&mut Pin<&mut Self>` argument.][47]
|
||||
- [Change `project` method generated by `#[pin_project]` attribute to take an `&mut Pin<&mut Self>` argument.](https://github.com/taiki-e/pin-project/pull/47)
|
||||
|
||||
* [`#[project]` attribute can now be used for impl blocks.][46]
|
||||
- [`#[project]` attribute can now be used for impl blocks.](https://github.com/taiki-e/pin-project/pull/46)
|
||||
|
||||
* [`#[pin_project]` attribute can now detect that the type used does not have its own drop implementation without actually implementing drop.][48] This removed some restrictions.
|
||||
|
||||
[46]: https://github.com/taiki-e/pin-project/pull/46
|
||||
[47]: https://github.com/taiki-e/pin-project/pull/47
|
||||
[48]: https://github.com/taiki-e/pin-project/pull/48
|
||||
- [`#[pin_project]` attribute can now detect that the type used does not have its own drop implementation without actually implementing drop.](https://github.com/taiki-e/pin-project/pull/48) This removed some restrictions.
|
||||
|
||||
## [0.4.0-alpha.2] - 2019-08-13
|
||||
|
||||
* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
|
||||
- Update `proc-macro2`, `syn`, and `quote` to 1.0.
|
||||
|
||||
## [0.4.0-alpha.1] - 2019-08-11
|
||||
|
||||
* **Pin projection has become a safe operation.**
|
||||
- **Pin projection has become a safe operation.**
|
||||
|
||||
* `#[unsafe_project]` has been replaced with `#[pin_project]`.
|
||||
- `#[unsafe_project]` has been replaced with `#[pin_project]`.
|
||||
|
||||
* The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.
|
||||
- The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.
|
||||
|
||||
* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl.
|
||||
- Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl.
|
||||
|
||||
* `Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.
|
||||
- `Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.
|
||||
|
||||
* Made `#[project]` attribute disabled by default.
|
||||
- Made `#[project]` attribute disabled by default.
|
||||
|
||||
See also [tracking issue for 0.4 release][21].
|
||||
|
||||
[21]: https://github.com/taiki-e/pin-project/issues/21
|
||||
See also [tracking issue for 0.4 release](https://github.com/taiki-e/pin-project/issues/21).
|
||||
|
||||
## [0.3.5] - 2019-08-14
|
||||
|
||||
* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
|
||||
- Update `proc-macro2`, `syn`, and `quote` to 1.0.
|
||||
|
||||
## [0.3.4] - 2019-07-21
|
||||
|
||||
* Improved error messages.
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.3.3] - 2019-07-15 - YANKED
|
||||
## [0.3.3] - 2019-07-15
|
||||
|
||||
* Improved error messages.
|
||||
**Note: This release has been yanked.** See [#16](https://github.com/taiki-e/pin-project/issues/16) for details.
|
||||
|
||||
- Diagnostic improvements.
|
||||
|
||||
## [0.3.2] - 2019-03-30
|
||||
|
||||
* Avoided suffixes on tuple index.
|
||||
- Avoid suffixes on tuple index.
|
||||
|
||||
## [0.3.1] - 2019-03-02
|
||||
|
||||
* Improved documentation.
|
||||
- Documentation improvements.
|
||||
|
||||
* Updated minimum `syn` version to 0.15.22.
|
||||
- Update minimum `syn` version to 0.15.22.
|
||||
|
||||
## [0.3.0] - 2019-02-20
|
||||
|
||||
* Removed `unsafe_fields` attribute.
|
||||
- Remove `unsafe_fields` attribute.
|
||||
|
||||
* Removed `unsafe_variants` attribute.
|
||||
- Remove `unsafe_variants` attribute.
|
||||
|
||||
## [0.2.2] - 2019-02-20
|
||||
|
||||
* Fixed a bug that generates incorrect code for the some structures with trait bounds on type generics.
|
||||
- Fix a bug that generates incorrect code for the some structures with trait bounds on type generics.
|
||||
|
||||
## [0.2.1] - 2019-02-20
|
||||
|
||||
* Fixed a bug that generates incorrect code for the structures with where clause and associated type fields.
|
||||
- Fix a bug that generates incorrect code for the structures with where clause and associated type fields.
|
||||
|
||||
## [0.2.0] - 2019-02-11
|
||||
|
||||
* Made `unsafe_fields` optional.
|
||||
- Make `unsafe_fields` optional.
|
||||
|
||||
* Improved documentation.
|
||||
- Documentation improvements.
|
||||
|
||||
## [0.1.8] - 2019-02-02
|
||||
|
||||
* Added the feature to create projected enums to `unsafe_project`.
|
||||
- Add the feature to create projected enums to `unsafe_project`.
|
||||
|
||||
* Added `project` attribute to support pattern matching.
|
||||
- Add `project` attribute to support pattern matching.
|
||||
|
||||
## [0.1.7] - 2019-01-19
|
||||
|
||||
* Fixed documentation.
|
||||
- Fix documentation.
|
||||
|
||||
## [0.1.6] - 2019-01-19
|
||||
|
||||
* `unsafe_fields` can now opt-out.
|
||||
- `unsafe_fields` can now opt-out.
|
||||
|
||||
* Added `unsafe_variants` attribute. This attribute is available if pin-project is built with the "unsafe_variants" feature.
|
||||
- Add `unsafe_variants` attribute. This attribute is available if pin-project is built with the "unsafe_variants" feature.
|
||||
|
||||
## [0.1.5] - 2019-01-17
|
||||
|
||||
* Added support for tuple struct to `unsafe_project`.
|
||||
- Add support for tuple struct to `unsafe_project`.
|
||||
|
||||
## [0.1.4] - 2019-01-12
|
||||
|
||||
* Added options for automatically implementing `Unpin` to both `unsafe_project` and `unsafe_fields`.
|
||||
- Add options for automatically implementing `Unpin` to both `unsafe_project` and `unsafe_fields`.
|
||||
|
||||
## [0.1.3] - 2019-01-11
|
||||
|
||||
* Fixed dependencies.
|
||||
- Fix dependencies.
|
||||
|
||||
* Added `unsafe_fields` attribute.
|
||||
- Add `unsafe_fields` attribute.
|
||||
|
||||
## [0.1.2] - 2019-01-09
|
||||
|
||||
* Improved documentation.
|
||||
- Documentation improvements.
|
||||
|
||||
## [0.1.1] - 2019-01-08
|
||||
|
||||
* Renamed from `unsafe_pin_project` to `unsafe_project`.
|
||||
- Rename from `unsafe_pin_project` to `unsafe_project`.
|
||||
|
||||
## [0.1.0] - 2019-01-08 - YANKED
|
||||
## [0.1.0] - 2019-01-08
|
||||
|
||||
**Note: This release has been yanked.**
|
||||
|
||||
Initial release
|
||||
|
||||
[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.9...HEAD
|
||||
[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.28...HEAD
|
||||
[0.4.28]: https://github.com/taiki-e/pin-project/compare/v0.4.27...v0.4.28
|
||||
[0.4.27]: https://github.com/taiki-e/pin-project/compare/v0.4.26...v0.4.27
|
||||
[0.4.26]: https://github.com/taiki-e/pin-project/compare/v0.4.25...v0.4.26
|
||||
[0.4.25]: https://github.com/taiki-e/pin-project/compare/v0.4.24...v0.4.25
|
||||
[0.4.24]: https://github.com/taiki-e/pin-project/compare/v0.4.23...v0.4.24
|
||||
[0.4.23]: https://github.com/taiki-e/pin-project/compare/v0.4.22...v0.4.23
|
||||
[0.4.22]: https://github.com/taiki-e/pin-project/compare/v0.4.21...v0.4.22
|
||||
[0.4.21]: https://github.com/taiki-e/pin-project/compare/v0.4.20...v0.4.21
|
||||
[0.4.20]: https://github.com/taiki-e/pin-project/compare/v0.4.19...v0.4.20
|
||||
[0.4.19]: https://github.com/taiki-e/pin-project/compare/v0.4.18...v0.4.19
|
||||
[0.4.18]: https://github.com/taiki-e/pin-project/compare/v0.4.17...v0.4.18
|
||||
[0.4.17]: https://github.com/taiki-e/pin-project/compare/v0.4.16...v0.4.17
|
||||
[0.4.16]: https://github.com/taiki-e/pin-project/compare/v0.4.15...v0.4.16
|
||||
[0.4.15]: https://github.com/taiki-e/pin-project/compare/v0.4.14...v0.4.15
|
||||
[0.4.14]: https://github.com/taiki-e/pin-project/compare/v0.4.13...v0.4.14
|
||||
[0.4.13]: https://github.com/taiki-e/pin-project/compare/v0.4.11...v0.4.13
|
||||
[0.4.12]: https://github.com/taiki-e/pin-project/compare/v0.4.10...v0.4.12
|
||||
[0.4.11]: https://github.com/taiki-e/pin-project/compare/v0.4.10...v0.4.11
|
||||
[0.4.10]: https://github.com/taiki-e/pin-project/compare/v0.4.9...v0.4.10
|
||||
[0.4.9]: https://github.com/taiki-e/pin-project/compare/v0.4.8...v0.4.9
|
||||
[0.4.8]: https://github.com/taiki-e/pin-project/compare/v0.4.7...v0.4.8
|
||||
[0.4.7]: https://github.com/taiki-e/pin-project/compare/v0.4.6...v0.4.7
|
||||
|
166
third_party/rust/pin-project/Cargo.lock
generated
vendored
166
third_party/rust/pin-project/Cargo.lock
generated
vendored
@ -1,56 +1,180 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
dependencies = [
|
||||
"pin-project-internal 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-internal",
|
||||
"rustversion",
|
||||
"trybuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.10"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.3"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.125"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.17"
|
||||
version = "1.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trybuild"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99471a206425fba51842a9186315f32d91c56eadc21ea4c21f847b59cf778f8b"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"termcolor",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[metadata]
|
||||
"checksum pin-project-internal 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"
|
||||
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
||||
"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
||||
"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
14
third_party/rust/pin-project/Cargo.toml
vendored
14
third_party/rust/pin-project/Cargo.toml
vendored
@ -13,16 +13,22 @@
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "pin-project"
|
||||
version = "0.4.9"
|
||||
version = "0.4.28"
|
||||
authors = ["Taiki Endo <te316e89@gmail.com>"]
|
||||
exclude = ["/.*", "/ci", "/tools"]
|
||||
description = "A crate for safe and ergonomic pin-projection.\n"
|
||||
homepage = "https://github.com/taiki-e/pin-project"
|
||||
documentation = "https://docs.rs/pin-project"
|
||||
readme = "README.md"
|
||||
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"]
|
||||
[dependencies.pin-project-internal]
|
||||
version = "=0.4.9"
|
||||
version = "=0.4.28"
|
||||
default-features = false
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0"
|
||||
|
35
third_party/rust/pin-project/README.md
vendored
35
third_party/rust/pin-project/README.md
vendored
@ -9,16 +9,12 @@
|
||||
[crates-url]: https://crates.io/crates/pin-project
|
||||
[docs-badge]: https://docs.rs/pin-project/badge.svg
|
||||
[docs-url]: https://docs.rs/pin-project
|
||||
[license-badge]: https://img.shields.io/crates/l/pin-project.svg
|
||||
[license-badge]: https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg
|
||||
[license]: #license
|
||||
[rustc-badge]: https://img.shields.io/badge/rustc-1.33+-lightgray.svg
|
||||
[rustc-url]: https://blog.rust-lang.org/2019/02/28/Rust-1.33.0.html
|
||||
[rustc-badge]: https://img.shields.io/badge/rustc-1.34+-lightgray.svg
|
||||
[rustc-url]: https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html
|
||||
|
||||
A crate for safe and ergonomic pin-projection.
|
||||
|
||||
[Documentation][docs-url]
|
||||
|
||||
[Examples](examples/README.md)
|
||||
A crate for safe and ergonomic [pin-projection].
|
||||
|
||||
## Usage
|
||||
|
||||
@ -29,11 +25,12 @@ Add this to your `Cargo.toml`:
|
||||
pin-project = "0.4"
|
||||
```
|
||||
|
||||
The current pin-project requires Rust 1.33 or later.
|
||||
The current pin-project requires Rust 1.34 or later.
|
||||
|
||||
## Examples
|
||||
|
||||
[`pin_project`] attribute creates a projection struct covering all the fields.
|
||||
[`#[pin_project]`][`pin_project`] attribute creates projection types
|
||||
covering all the fields of struct or enum.
|
||||
|
||||
```rust
|
||||
use pin_project::pin_project;
|
||||
@ -47,7 +44,7 @@ struct Struct<T, U> {
|
||||
}
|
||||
|
||||
impl<T, U> Struct<T, U> {
|
||||
fn foo(self: Pin<&mut Self>) {
|
||||
fn method(self: Pin<&mut Self>) {
|
||||
let this = self.project();
|
||||
let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
|
||||
let _: &mut U = this.unpinned; // Normal reference to the field
|
||||
@ -55,13 +52,21 @@ impl<T, U> Struct<T, U> {
|
||||
}
|
||||
```
|
||||
|
||||
[Code like this will be generated](examples/struct-default-expanded.rs)
|
||||
[*code like this will be generated*][struct-default-expanded]
|
||||
|
||||
See [API documentation][docs-url] for more details.
|
||||
|
||||
Also, there are examples and generated code of each feature in [examples](examples/README.md) directory.
|
||||
See [documentation][docs-url] for more details, and
|
||||
see [examples] directory for more examples and generated code.
|
||||
|
||||
[`pin_project`]: https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html
|
||||
[examples]: examples/README.md
|
||||
[pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
|
||||
[struct-default-expanded]: examples/struct-default-expanded.rs
|
||||
|
||||
## Related Projects
|
||||
|
||||
* [pin-project-lite]: A lightweight version of pin-project written with declarative macros.
|
||||
|
||||
[pin-project-lite]: https://github.com/taiki-e/pin-project-lite
|
||||
|
||||
## License
|
||||
|
||||
|
24
third_party/rust/pin-project/ci.sh
vendored
24
third_party/rust/pin-project/ci.sh
vendored
@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# A script to run a simplified version of the checks done by CI.
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
# ```sh
|
||||
# . ./ci.sh
|
||||
# ```
|
||||
|
||||
echo "Running 'cargo fmt -- --check'"
|
||||
cargo +nightly fmt --all -- --check
|
||||
|
||||
echo "Running 'cargo clippy'"
|
||||
cargo +nightly clippy --all --all-features
|
||||
|
||||
echo "Running 'cargo test'"
|
||||
cargo +nightly test --all --all-features
|
||||
|
||||
echo "Running 'cargo doc'"
|
||||
cargo +nightly doc --no-deps --all --all-features
|
||||
|
||||
echo "Running 'compiletest'"
|
||||
. ./compiletest.sh
|
@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
component="${1}"
|
||||
|
||||
if ! rustup component add "${component}" 2>/dev/null; then
|
||||
# If the component is unavailable on the latest nightly,
|
||||
# use the latest toolchain with the component available.
|
||||
# Refs: https://github.com/rust-lang/rustup-components-history#the-web-part
|
||||
target=$(curl -sSf "https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/${component}")
|
||||
echo "'${component}' is unavailable on the default toolchain, use the toolchain 'nightly-${target}' instead"
|
||||
|
||||
rustup update "nightly-${target}" --no-self-update
|
||||
rustup default "nightly-${target}"
|
||||
|
||||
echo "Query rust and cargo versions:"
|
||||
rustup -V
|
||||
rustc -V
|
||||
cargo -V
|
||||
|
||||
rustup component add "${component}"
|
||||
fi
|
||||
|
||||
echo "Query component versions:"
|
||||
case "${component}" in
|
||||
clippy | miri) cargo "${component}" -V ;;
|
||||
rustfmt) "${component}" -V ;;
|
||||
esac
|
20
third_party/rust/pin-project/ci/install-rust.sh
vendored
20
third_party/rust/pin-project/ci/install-rust.sh
vendored
@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
toolchain="${1:-nightly}"
|
||||
|
||||
if rustup -V 2>/dev/null; then
|
||||
rustup set profile minimal
|
||||
rustup update "${toolchain}" --no-self-update
|
||||
rustup default "${toolchain}"
|
||||
else
|
||||
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${toolchain}"
|
||||
export PATH=${PATH}:${HOME}/.cargo/bin
|
||||
echo "##[add-path]${HOME}/.cargo/bin"
|
||||
fi
|
||||
|
||||
echo "Query rust and cargo versions:"
|
||||
rustup -V
|
||||
rustc -V
|
||||
cargo -V
|
12
third_party/rust/pin-project/compiletest.sh
vendored
12
third_party/rust/pin-project/compiletest.sh
vendored
@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# A script to run compile tests with the same condition of the checks done by CI.
|
||||
#
|
||||
# Usage
|
||||
#
|
||||
# ```sh
|
||||
# . ./compiletest.sh
|
||||
# ```
|
||||
|
||||
TRYBUILD=overwrite RUSTFLAGS='--cfg pin_project_show_unpin_struct' cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
|
||||
# RUSTFLAGS='--cfg pin_project_show_unpin_struct' cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
|
36
third_party/rust/pin-project/examples/README.md
vendored
36
third_party/rust/pin-project/examples/README.md
vendored
@ -1,9 +1,35 @@
|
||||
## Examples and generated code of each feature of pin-project
|
||||
# Examples and generated code of each feature of pin-project
|
||||
|
||||
* [Basic usage of `#[pin_project]` on structs.](struct-default.rs) -- [generated code](struct-default-expanded.rs)
|
||||
### Basic usage of `#[pin_project]` on structs
|
||||
|
||||
* [Basic usage of `#[pin_project]` on enums.](enum-default.rs) -- [generated code](enum-default-expanded.rs)
|
||||
* [example](struct-default.rs)
|
||||
* [generated code](struct-default-expanded.rs)
|
||||
|
||||
* [Manual implementation of `Unpin` by `UnsafeUnpin`.](unsafe_unpin.rs) -- [generated code](unsafe_unpin-expanded.rs)
|
||||
### Basic usage of `#[pin_project]` on enums
|
||||
|
||||
* [Manual implementation of `Drop` by `#[pinned_drop]`.](pinned_drop.rs) -- [generated code](pinned_drop-expanded.rs)
|
||||
* [example](enum-default.rs)
|
||||
* [generated code](enum-default-expanded.rs)
|
||||
|
||||
### Manual implementation of `Unpin` by `UnsafeUnpin`
|
||||
|
||||
* [example](unsafe_unpin.rs)
|
||||
* [generated code](unsafe_unpin-expanded.rs)
|
||||
* [`UnsafeUnpin` documentation](https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html)
|
||||
|
||||
### Manual implementation of `Drop` by `#[pinned_drop]`
|
||||
|
||||
* [example](pinned_drop.rs)
|
||||
* [generated code](pinned_drop-expanded.rs)
|
||||
* [`#[pinned_drop]` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pinned_drop.html)
|
||||
|
||||
### `project_replace()` method
|
||||
|
||||
* [example](project_replace.rs)
|
||||
* [generated code](project_replace-expanded.rs)
|
||||
* [`project_replace()` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#project_replace)
|
||||
|
||||
### Ensure `!Unpin` by `#[pin_project(!Unpin)]`
|
||||
|
||||
* [example](not_unpin.rs)
|
||||
* [generated code](not_unpin-expanded.rs)
|
||||
* [`!Unpin` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#unpin)
|
||||
|
@ -5,7 +5,7 @@
|
||||
//
|
||||
// use pin_project::pin_project;
|
||||
//
|
||||
// #[pin_project]
|
||||
// #[pin_project(project = EnumProj)]
|
||||
// enum Enum<T, U> {
|
||||
// Pinned(#[pin] T),
|
||||
// Unpinned(U),
|
||||
@ -14,7 +14,8 @@
|
||||
// fn main() {}
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens)]
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::needless_lifetimes, clippy::just_underscores_and_digits)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
@ -23,64 +24,91 @@ enum Enum<T, U> {
|
||||
Unpinned(U),
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
enum __EnumProjection<'pin, T, U> {
|
||||
Pinned(::core::pin::Pin<&'pin mut (T)>),
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
enum EnumProj<'pin, T, U>
|
||||
where
|
||||
Enum<T, U>: 'pin,
|
||||
{
|
||||
Pinned(::pin_project::__private::Pin<&'pin mut (T)>),
|
||||
Unpinned(&'pin mut (U)),
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
enum __EnumProjectionRef<'pin, T, U> {
|
||||
Pinned(::core::pin::Pin<&'pin (T)>),
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
enum __EnumProjectionRef<'pin, T, U>
|
||||
where
|
||||
Enum<T, U>: 'pin,
|
||||
{
|
||||
Pinned(::pin_project::__private::Pin<&'pin (T)>),
|
||||
Unpinned(&'pin (U)),
|
||||
}
|
||||
|
||||
impl<T, U> Enum<T, U> {
|
||||
fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __EnumProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
match self.get_unchecked_mut() {
|
||||
Enum::Pinned(_0) => __EnumProjection::Pinned(::core::pin::Pin::new_unchecked(_0)),
|
||||
Enum::Unpinned(_0) => __EnumProjection::Unpinned(_0),
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __EnumProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
match self.get_ref() {
|
||||
Enum::Pinned(_0) => {
|
||||
__EnumProjectionRef::Pinned(::core::pin::Pin::new_unchecked(_0))
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<T, U> Enum<T, U> {
|
||||
fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> EnumProj<'pin, T, U> {
|
||||
unsafe {
|
||||
match self.get_unchecked_mut() {
|
||||
Enum::Pinned(_0) => {
|
||||
EnumProj::Pinned(::pin_project::__private::Pin::new_unchecked(_0))
|
||||
}
|
||||
Enum::Unpinned(_0) => EnumProj::Unpinned(_0),
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __EnumProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
match self.get_ref() {
|
||||
Enum::Pinned(_0) => __EnumProjectionRef::Pinned(
|
||||
::pin_project::__private::Pin::new_unchecked(_0),
|
||||
),
|
||||
Enum::Unpinned(_0) => __EnumProjectionRef::Unpinned(_0),
|
||||
}
|
||||
Enum::Unpinned(_0) => __EnumProjectionRef::Unpinned(_0),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
|
||||
// for details.
|
||||
#[allow(non_snake_case)]
|
||||
fn __unpin_scope_Enum() {
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
|
||||
// for details.
|
||||
struct __Enum<'pin, T, U> {
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
|
||||
'pin,
|
||||
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
|
||||
>,
|
||||
__field0: T,
|
||||
}
|
||||
impl<'pin, T, U> ::core::marker::Unpin for Enum<T, U> where __Enum<'pin, T, U>: ::core::marker::Unpin
|
||||
{}
|
||||
}
|
||||
impl<'pin, T, U> ::pin_project::__private::Unpin for Enum<T, U> where
|
||||
__Enum<'pin, T, U>: ::pin_project::__private::Unpin
|
||||
{
|
||||
}
|
||||
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Enum<T, U> {}
|
||||
|
||||
// Ensure that enum does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait EnumMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds)]
|
||||
impl<T: ::core::ops::Drop> EnumMustNotImplDrop for T {}
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl<T, U> EnumMustNotImplDrop for Enum<T, U> {}
|
||||
// Ensure that enum does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait EnumMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds, drop_bounds)]
|
||||
impl<T: ::pin_project::__private::Drop> EnumMustNotImplDrop for T {}
|
||||
impl<T, U> EnumMustNotImplDrop for Enum<T, U> {}
|
||||
impl<T, U> ::pin_project::__private::PinnedDrop for Enum<T, U> {
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
// We don't need to check for '#[repr(packed)]',
|
||||
// since it does not apply to enums.
|
||||
// We don't need to check for `#[repr(packed)]`,
|
||||
// since it does not apply to enums.
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project = EnumProj)]
|
||||
enum Enum<T, U> {
|
||||
Pinned(#[pin] T),
|
||||
Unpinned(U),
|
||||
|
129
third_party/rust/pin-project/examples/not_unpin-expanded.rs
vendored
Normal file
129
third_party/rust/pin-project/examples/not_unpin-expanded.rs
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
// Original code (./not_unpin.rs):
|
||||
//
|
||||
// ```rust
|
||||
// #![allow(dead_code)]
|
||||
//
|
||||
// use pin_project::pin_project;
|
||||
//
|
||||
// #[pin_project(!Unpin)]
|
||||
// pub struct Struct<T, U> {
|
||||
// #[pin]
|
||||
// pinned: T,
|
||||
// unpinned: U,
|
||||
// }
|
||||
//
|
||||
// fn main() {
|
||||
// fn _is_unpin<T: Unpin>() {}
|
||||
// // _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned
|
||||
// }
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::no_effect, clippy::needless_lifetimes)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
pub struct Struct<T, U> {
|
||||
// #[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjection<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
|
||||
unpinned: &'pin mut (U),
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjectionRef<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin (T)>,
|
||||
unpinned: &'pin (U),
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<T, U> Struct<T, U> {
|
||||
pub(crate) fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> __StructProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__StructProjection {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __StructProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_ref();
|
||||
__StructProjectionRef {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create `Unpin` impl that has trivial `Unpin` bounds.
|
||||
//
|
||||
// See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282
|
||||
// for details.
|
||||
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
|
||||
::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>:
|
||||
::pin_project::__private::Unpin
|
||||
{
|
||||
}
|
||||
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
|
||||
//
|
||||
// To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
|
||||
// impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
|
||||
// impl, they'll get a "conflicting implementations of trait" error when
|
||||
// coherence checks are run.
|
||||
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
|
||||
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait StructMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds, drop_bounds)]
|
||||
impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
|
||||
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
|
||||
impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
|
||||
// struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[forbid(unaligned_references, safe_packed_borrows)]
|
||||
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
|
||||
let _ = &this.pinned;
|
||||
let _ = &this.unpinned;
|
||||
}
|
||||
};
|
||||
|
||||
fn main() {
|
||||
fn _is_unpin<T: Unpin>() {}
|
||||
// _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned
|
||||
}
|
17
third_party/rust/pin-project/examples/not_unpin.rs
vendored
Normal file
17
third_party/rust/pin-project/examples/not_unpin.rs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// See ./not_unpin-expanded.rs for generated code.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
pub struct Struct<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn _is_unpin<T: Unpin>() {}
|
||||
// _is_unpin::<Struct<(), ()>>(); //~ ERROR `std::marker::PhantomPinned` cannot be unpinned
|
||||
}
|
@ -3,131 +3,158 @@
|
||||
// ```rust
|
||||
// #![allow(dead_code)]
|
||||
//
|
||||
// use pin_project::{pin_project, pinned_drop};
|
||||
// use std::pin::Pin;
|
||||
//
|
||||
// use pin_project::{pin_project, pinned_drop};
|
||||
//
|
||||
// #[pin_project(PinnedDrop)]
|
||||
// pub struct Foo<'a, T> {
|
||||
// pub struct Struct<'a, T> {
|
||||
// was_dropped: &'a mut bool,
|
||||
// #[pin]
|
||||
// field: T,
|
||||
// }
|
||||
//
|
||||
// #[pinned_drop]
|
||||
// fn drop_foo<T>(mut this: Pin<&mut Foo<'_, T>>) {
|
||||
// fn drop_Struct<T>(mut this: Pin<&mut Struct<'_, T>>) {
|
||||
// **this.project().was_dropped = true;
|
||||
// }
|
||||
//
|
||||
// fn main() {}
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens)]
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::no_effect, clippy::needless_lifetimes)]
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
use std::pin::Pin;
|
||||
|
||||
pub struct Foo<'a, T> {
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
pub struct Struct<'a, T> {
|
||||
was_dropped: &'a mut bool,
|
||||
// #[pin]
|
||||
field: T,
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
pub(crate) struct __FooProjection<'pin, 'a, T> {
|
||||
was_dropped: &'pin mut (&'a mut bool),
|
||||
field: ::core::pin::Pin<&'pin mut (T)>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
pub(crate) struct __FooProjectionRef<'pin, 'a, T> {
|
||||
was_dropped: &'pin (&'a mut bool),
|
||||
field: ::core::pin::Pin<&'pin (T)>,
|
||||
}
|
||||
|
||||
impl<'a, T> Foo<'a, T> {
|
||||
pub(crate) fn project<'pin>(
|
||||
self: ::core::pin::Pin<&'pin mut Self>,
|
||||
) -> __FooProjection<'pin, 'a, T> {
|
||||
unsafe {
|
||||
let Foo { was_dropped, field } = self.get_unchecked_mut();
|
||||
__FooProjection { was_dropped, field: ::core::pin::Pin::new_unchecked(field) }
|
||||
}
|
||||
}
|
||||
pub(crate) fn project_ref<'pin>(
|
||||
self: ::core::pin::Pin<&'pin Self>,
|
||||
) -> __FooProjectionRef<'pin, 'a, T> {
|
||||
unsafe {
|
||||
let Foo { was_dropped, field } = self.get_ref();
|
||||
__FooProjectionRef { was_dropped, field: ::core::pin::Pin::new_unchecked(field) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl<'a, T> ::core::ops::Drop for Foo<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
// Safety - we're in 'drop', so we know that 'self' will
|
||||
// never move again.
|
||||
let pinned_self = unsafe { ::core::pin::Pin::new_unchecked(self) };
|
||||
// We call `pinned_drop` only once. Since `PinnedDrop::drop`
|
||||
// is an unsafe function and a private API, it is never called again in safe
|
||||
// code *unless the user uses a maliciously crafted macro*.
|
||||
unsafe {
|
||||
::pin_project::__private::PinnedDrop::drop(pinned_self);
|
||||
}
|
||||
}
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjection<'pin, 'a, T>
|
||||
where
|
||||
Struct<'a, T>: 'pin,
|
||||
{
|
||||
was_dropped: &'pin mut (&'a mut bool),
|
||||
field: ::pin_project::__private::Pin<&'pin mut (T)>,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjectionRef<'pin, 'a, T>
|
||||
where
|
||||
Struct<'a, T>: 'pin,
|
||||
{
|
||||
was_dropped: &'pin (&'a mut bool),
|
||||
field: ::pin_project::__private::Pin<&'pin (T)>,
|
||||
}
|
||||
|
||||
// It is safe to implement PinnedDrop::drop, but it is not safe to call it.
|
||||
// This is because destructors can be called multiple times (double dropping
|
||||
// is unsound: rust-lang/rust#62360).
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<'a, T> Struct<'a, T> {
|
||||
pub(crate) fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> __StructProjection<'pin, 'a, T> {
|
||||
unsafe {
|
||||
let Self { was_dropped, field } = self.get_unchecked_mut();
|
||||
__StructProjection {
|
||||
was_dropped,
|
||||
field: ::pin_project::__private::Pin::new_unchecked(field),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __StructProjectionRef<'pin, 'a, T> {
|
||||
unsafe {
|
||||
let Self { was_dropped, field } = self.get_ref();
|
||||
__StructProjectionRef {
|
||||
was_dropped,
|
||||
field: ::pin_project::__private::Pin::new_unchecked(field),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> ::pin_project::__private::Drop for Struct<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
// Safety - we're in 'drop', so we know that 'self' will
|
||||
// never move again.
|
||||
let pinned_self = unsafe { ::pin_project::__private::Pin::new_unchecked(self) };
|
||||
// We call `pinned_drop` only once. Since `PinnedDrop::drop`
|
||||
// is an unsafe method and a private API, it is never called again in safe
|
||||
// code *unless the user uses a maliciously crafted macro*.
|
||||
unsafe {
|
||||
::pin_project::__private::PinnedDrop::drop(pinned_self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
|
||||
// for details.
|
||||
pub struct __Struct<'pin, 'a, T> {
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T)>,
|
||||
__field0: T,
|
||||
__lifetime0: &'a (),
|
||||
}
|
||||
impl<'pin, 'a, T> ::pin_project::__private::Unpin for Struct<'a, T> where
|
||||
__Struct<'pin, 'a, T>: ::pin_project::__private::Unpin
|
||||
{
|
||||
}
|
||||
unsafe impl<'a, T> ::pin_project::UnsafeUnpin for Struct<'a, T> {}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
|
||||
// struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[forbid(unaligned_references, safe_packed_borrows)]
|
||||
fn __assert_not_repr_packed<'a, T>(this: &Struct<'a, T>) {
|
||||
let _ = &this.was_dropped;
|
||||
let _ = &this.field;
|
||||
}
|
||||
};
|
||||
|
||||
// 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](https://github.com/rust-lang/rust/pull/62360).
|
||||
//
|
||||
// Ideally, it would be desirable to be able to prohibit manual calls in the
|
||||
// same way as Drop::drop, but the library cannot. So, by using macros and
|
||||
// replacing them with private traits, we prevent users from calling
|
||||
// PinnedDrop::drop.
|
||||
// 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, we prevent users from
|
||||
// calling `PinnedDrop::drop`.
|
||||
//
|
||||
// Users can implement `Drop` safely using `#[pinned_drop]`.
|
||||
// Users can implement [`Drop`] safely using `#[pinned_drop]` and can drop a
|
||||
// type that implements `PinnedDrop` using the [`drop`] function safely.
|
||||
// **Do not call or implement this trait directly.**
|
||||
impl<T> ::pin_project::__private::PinnedDrop for Foo<'_, T> {
|
||||
impl<T> ::pin_project::__private::PinnedDrop for Struct<'_, T> {
|
||||
// Since calling it twice on the same object would be UB,
|
||||
// this method is unsafe.
|
||||
unsafe fn drop(self: Pin<&mut Self>) {
|
||||
fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn __drop_inner<T>(__self: Pin<&mut Struct<'_, T>>) {
|
||||
// A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
|
||||
fn __drop_inner() {}
|
||||
|
||||
**__self.project().was_dropped = true;
|
||||
}
|
||||
__drop_inner(self);
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
|
||||
// for details.
|
||||
#[allow(non_snake_case)]
|
||||
fn __unpin_scope_Foo() {
|
||||
pub struct __Foo<'pin, 'a, T> {
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T)>,
|
||||
__field0: T,
|
||||
__lifetime0: &'a (),
|
||||
}
|
||||
impl<'pin, 'a, T> ::core::marker::Unpin for Foo<'a, T> where
|
||||
__Foo<'pin, 'a, T>: ::core::marker::Unpin
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(non_snake_case)]
|
||||
#[deny(safe_packed_borrows)]
|
||||
fn __pin_project_assert_not_repr_packed_Foo<'a, T>(val: &Foo<'a, T>) {
|
||||
&val.was_dropped;
|
||||
&val.field;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -2,18 +2,19 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Foo<'a, T> {
|
||||
pub struct Struct<'a, T> {
|
||||
was_dropped: &'a mut bool,
|
||||
#[pin]
|
||||
field: T,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T> PinnedDrop for Foo<'_, T> {
|
||||
impl<T> PinnedDrop for Struct<'_, T> {
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
**self.project().was_dropped = true;
|
||||
}
|
||||
|
165
third_party/rust/pin-project/examples/project_replace-expanded.rs
vendored
Normal file
165
third_party/rust/pin-project/examples/project_replace-expanded.rs
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
// Original code (./struct-default.rs):
|
||||
//
|
||||
// ```rust
|
||||
// #![allow(dead_code)]
|
||||
//
|
||||
// use pin_project::pin_project;
|
||||
//
|
||||
// #[pin_project(project_replace)]
|
||||
// struct Struct<T, U> {
|
||||
// #[pin]
|
||||
// pinned: T,
|
||||
// unpinned: U,
|
||||
// }
|
||||
//
|
||||
// fn main() {}
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::no_effect, clippy::needless_lifetimes)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
struct Struct<T, U> {
|
||||
// #[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
struct __StructProjection<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
|
||||
unpinned: &'pin mut (U),
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
struct __StructProjectionRef<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin (T)>,
|
||||
unpinned: &'pin (U),
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(unreachable_pub)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
struct __StructProjectionOwned<T, U> {
|
||||
pinned: ::pin_project::__private::PhantomData<T>,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<T, U> Struct<T, U> {
|
||||
fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> __StructProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__StructProjection {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __StructProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_ref();
|
||||
__StructProjectionRef {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_replace(
|
||||
self: ::pin_project::__private::Pin<&mut Self>,
|
||||
__replacement: Self,
|
||||
) -> __StructProjectionOwned<T, U> {
|
||||
unsafe {
|
||||
let __self_ptr: *mut Self = self.get_unchecked_mut();
|
||||
let Self { pinned, unpinned } = &mut *__self_ptr;
|
||||
|
||||
// First, extract all the unpinned fields
|
||||
let __result = __StructProjectionOwned {
|
||||
pinned: ::pin_project::__private::PhantomData,
|
||||
unpinned: ::pin_project::__private::ptr::read(unpinned),
|
||||
};
|
||||
|
||||
// Destructors will run in reverse order, so next create a guard to overwrite
|
||||
// `self` with the replacement value without calling destructors.
|
||||
let __guard = ::pin_project::__private::UnsafeOverwriteGuard {
|
||||
target: __self_ptr,
|
||||
value: ::pin_project::__private::ManuallyDrop::new(__replacement),
|
||||
};
|
||||
|
||||
// Now create guards to drop all the pinned fields
|
||||
//
|
||||
// Due to a compiler bug (https://github.com/rust-lang/rust/issues/47949)
|
||||
// this must be in its own scope, or else `__result` will not be dropped
|
||||
// if any of the destructors panic.
|
||||
{
|
||||
let __guard = ::pin_project::__private::UnsafeDropInPlaceGuard(pinned);
|
||||
}
|
||||
|
||||
// Finally, return the result
|
||||
__result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
|
||||
// for details.
|
||||
struct __Struct<'pin, T, U> {
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
|
||||
'pin,
|
||||
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
|
||||
>,
|
||||
__field0: T,
|
||||
}
|
||||
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
|
||||
__Struct<'pin, T, U>: ::pin_project::__private::Unpin
|
||||
{
|
||||
}
|
||||
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
|
||||
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait StructMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds, drop_bounds)]
|
||||
impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
|
||||
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
|
||||
impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
|
||||
// struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[forbid(unaligned_references, safe_packed_borrows)]
|
||||
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
|
||||
let _ = &this.pinned;
|
||||
let _ = &this.unpinned;
|
||||
}
|
||||
};
|
||||
|
||||
fn main() {}
|
14
third_party/rust/pin-project/examples/project_replace.rs
vendored
Normal file
14
third_party/rust/pin-project/examples/project_replace.rs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// See ./struct-default-expanded.rs for generated code.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -15,7 +15,8 @@
|
||||
// fn main() {}
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens)]
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::no_effect, clippy::needless_lifetimes)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
@ -25,104 +26,137 @@ struct Struct<T, U> {
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
struct __StructProjection<'pin, T, U> {
|
||||
pinned: ::core::pin::Pin<&'pin mut (T)>,
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
struct __StructProjection<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
|
||||
unpinned: &'pin mut (U),
|
||||
}
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
struct __StructProjectionRef<'pin, T, U> {
|
||||
pinned: ::core::pin::Pin<&'pin (T)>,
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
struct __StructProjectionRef<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin (T)>,
|
||||
unpinned: &'pin (U),
|
||||
}
|
||||
|
||||
impl<T, U> Struct<T, U> {
|
||||
fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __StructProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Struct { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__StructProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<T, U> Struct<T, U> {
|
||||
fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> __StructProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__StructProjection {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __StructProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_ref();
|
||||
__StructProjectionRef {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __StructProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Struct { pinned, unpinned } = self.get_ref();
|
||||
__StructProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// Basically this is equivalent to the following code:
|
||||
// ```rust
|
||||
// impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
|
||||
// ```
|
||||
//
|
||||
// However, if struct is public and there is a private type field,
|
||||
// this would cause an E0446 (private type in public interface).
|
||||
//
|
||||
// When RFC 2145 is implemented (rust-lang/rust#48054),
|
||||
// this will become a lint, rather then a hard error.
|
||||
//
|
||||
// As a workaround for this, we generate a new struct, containing all of the pinned
|
||||
// fields from our #[pin_project] type. This struct is declared within
|
||||
// a function, which makes it impossible to be named by user code.
|
||||
// This guarantees that it will use the default auto-trait impl for Unpin -
|
||||
// that is, it will implement Unpin iff all of its fields implement Unpin.
|
||||
// This type can be safely declared as 'public', satisfying the privacy
|
||||
// checker without actually allowing user code to access it.
|
||||
//
|
||||
// This allows users to apply the #[pin_project] attribute to types
|
||||
// regardless of the privacy of the types of their fields.
|
||||
//
|
||||
// See also https://github.com/taiki-e/pin-project/pull/53.
|
||||
#[allow(non_snake_case)]
|
||||
fn __unpin_scope_Struct() {
|
||||
// Automatically create the appropriate conditional `Unpin` implementation.
|
||||
//
|
||||
// Basically this is equivalent to the following code:
|
||||
//
|
||||
// ```rust
|
||||
// impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
|
||||
// ```
|
||||
//
|
||||
// However, if struct is public and there is a private type field,
|
||||
// this would cause an E0446 (private type in public interface).
|
||||
//
|
||||
// When RFC 2145 is implemented (rust-lang/rust#48054),
|
||||
// this will become a lint, rather then a hard error.
|
||||
//
|
||||
// As a workaround for this, we generate a new struct, containing all of
|
||||
// the pinned fields from our #[pin_project] type. This struct is declared
|
||||
// within a function, which makes it impossible to be named by user code.
|
||||
// This guarantees that it will use the default auto-trait impl for Unpin -
|
||||
// that is, it will implement Unpin iff all of its fields implement Unpin.
|
||||
// This type can be safely declared as 'public', satisfying the privacy
|
||||
// checker without actually allowing user code to access it.
|
||||
//
|
||||
// This allows users to apply the #[pin_project] attribute to types
|
||||
// regardless of the privacy of the types of their fields.
|
||||
//
|
||||
// See also https://github.com/taiki-e/pin-project/pull/53.
|
||||
struct __Struct<'pin, T, U> {
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
|
||||
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
|
||||
'pin,
|
||||
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
|
||||
>,
|
||||
__field0: T,
|
||||
}
|
||||
impl<'pin, T, U> ::core::marker::Unpin for Struct<T, U> where
|
||||
__Struct<'pin, T, U>: ::core::marker::Unpin
|
||||
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
|
||||
__Struct<'pin, T, U>: ::pin_project::__private::Unpin
|
||||
{
|
||||
}
|
||||
}
|
||||
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
|
||||
//
|
||||
// To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
|
||||
// impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
|
||||
// impl, they'll get a "conflicting implementations of trait" error when
|
||||
// coherence checks are run.
|
||||
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
|
||||
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// There are two possible cases:
|
||||
// 1. The user type does not implement Drop. In this case,
|
||||
// the first blanked impl will not apply to it. This code
|
||||
// will compile, as there is only one impl of MustNotImplDrop for the user type
|
||||
// 2. The user type does impl Drop. This will make the blanket impl applicable,
|
||||
// which will then conflict with the explicit MustNotImplDrop impl below.
|
||||
// This will result in a compilation error, which is exactly what we want.
|
||||
trait StructMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds)]
|
||||
impl<T: ::core::ops::Drop> StructMustNotImplDrop for T {}
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// 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.
|
||||
trait StructMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds, drop_bounds)]
|
||||
impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
|
||||
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
|
||||
// A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
|
||||
// write a non-functional `PinnedDrop` impls.
|
||||
impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
|
||||
//
|
||||
// Taking a reference to a packed field is unsafe, and applying
|
||||
// #[deny(safe_packed_borrows)] makes sure that doing this without
|
||||
// an 'unsafe' block (which we deliberately do not generate)
|
||||
// is a hard error.
|
||||
//
|
||||
// If the struct ends up having #[repr(packed)] applied somehow,
|
||||
// this will generate an (unfriendly) error message. Under all reasonable
|
||||
// circumstances, we'll detect the #[repr(packed)] attribute, and generate
|
||||
// a much nicer error above.
|
||||
//
|
||||
// See https://github.com/taiki-e/pin-project/pull/34 for more details.
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(non_snake_case)]
|
||||
#[deny(safe_packed_borrows)]
|
||||
fn __pin_project_assert_not_repr_packed_Struct<T, U>(val: &Struct<T, U>) {
|
||||
&val.pinned;
|
||||
&val.unpinned;
|
||||
}
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
|
||||
// struct.
|
||||
//
|
||||
// Taking a reference to a packed field is UB, and applying
|
||||
// `#[forbid(unaligned_references)]` makes sure that doing this is a hard error.
|
||||
//
|
||||
// If the struct ends up having #[repr(packed)] applied somehow,
|
||||
// this will generate an (unfriendly) error message. Under all reasonable
|
||||
// circumstances, we'll detect the #[repr(packed)] attribute, and generate
|
||||
// a much nicer error above.
|
||||
//
|
||||
// See https://github.com/taiki-e/pin-project/pull/34 for more details.
|
||||
#[forbid(unaligned_references, safe_packed_borrows)]
|
||||
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
|
||||
let _ = &this.pinned;
|
||||
let _ = &this.unpinned;
|
||||
}
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -6,85 +6,110 @@
|
||||
// use pin_project::{pin_project, UnsafeUnpin};
|
||||
//
|
||||
// #[pin_project(UnsafeUnpin)]
|
||||
// pub struct Foo<T, U> {
|
||||
// pub struct Struct<T, U> {
|
||||
// #[pin]
|
||||
// pinned: T,
|
||||
// unpinned: U,
|
||||
// }
|
||||
//
|
||||
// unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
|
||||
// unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {}
|
||||
//
|
||||
// fn main() {}
|
||||
// ```
|
||||
|
||||
#![allow(dead_code, unused_imports, unused_parens)]
|
||||
#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
|
||||
#![allow(clippy::no_effect, clippy::needless_lifetimes)]
|
||||
|
||||
use pin_project::{pin_project, UnsafeUnpin};
|
||||
|
||||
pub struct Foo<T, U> {
|
||||
pub struct Struct<T, U> {
|
||||
// #[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
pub(crate) struct __FooProjection<'pin, T, U> {
|
||||
pinned: ::core::pin::Pin<&'pin mut (T)>,
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::mut_mut)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjection<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
|
||||
unpinned: &'pin mut (U),
|
||||
}
|
||||
#[allow(dead_code)] // This lint warns unused fields/variants.
|
||||
pub(crate) struct __FooProjectionRef<'pin, T, U> {
|
||||
pinned: ::core::pin::Pin<&'pin (T)>,
|
||||
#[doc(hidden)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::type_repetition_in_bounds)]
|
||||
pub(crate) struct __StructProjectionRef<'pin, T, U>
|
||||
where
|
||||
Struct<T, U>: 'pin,
|
||||
{
|
||||
pinned: ::pin_project::__private::Pin<&'pin (T)>,
|
||||
unpinned: &'pin (U),
|
||||
}
|
||||
|
||||
impl<T, U> Foo<T, U> {
|
||||
pub(crate) fn project<'pin>(
|
||||
self: ::core::pin::Pin<&'pin mut Self>,
|
||||
) -> __FooProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Foo { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__FooProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::used_underscore_binding)]
|
||||
const _: () = {
|
||||
impl<T, U> Struct<T, U> {
|
||||
pub(crate) fn project<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin mut Self>,
|
||||
) -> __StructProjection<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_unchecked_mut();
|
||||
__StructProjection {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn project_ref<'pin>(
|
||||
self: ::pin_project::__private::Pin<&'pin Self>,
|
||||
) -> __StructProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Self { pinned, unpinned } = self.get_ref();
|
||||
__StructProjectionRef {
|
||||
pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
|
||||
unpinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) fn project_ref<'pin>(
|
||||
self: ::core::pin::Pin<&'pin Self>,
|
||||
) -> __FooProjectionRef<'pin, T, U> {
|
||||
unsafe {
|
||||
let Foo { pinned, unpinned } = self.get_ref();
|
||||
__FooProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
|
||||
}
|
||||
|
||||
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
|
||||
::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait StructMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds, drop_bounds)]
|
||||
impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
|
||||
impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
|
||||
impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
|
||||
unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl<'pin, T, U> ::core::marker::Unpin for Foo<T, U> where
|
||||
::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin
|
||||
{
|
||||
}
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)]
|
||||
// struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[forbid(unaligned_references, safe_packed_borrows)]
|
||||
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
|
||||
let _ = &this.pinned;
|
||||
let _ = &this.unpinned;
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure that struct does not implement `Drop`.
|
||||
//
|
||||
// See ./struct-default-expanded.rs for details.
|
||||
trait FooMustNotImplDrop {}
|
||||
#[allow(clippy::drop_bounds)]
|
||||
impl<T: ::core::ops::Drop> FooMustNotImplDrop for T {}
|
||||
#[allow(single_use_lifetimes)]
|
||||
impl<T, U> FooMustNotImplDrop for Foo<T, U> {}
|
||||
|
||||
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
|
||||
//
|
||||
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
|
||||
// for details.
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(non_snake_case)]
|
||||
#[deny(safe_packed_borrows)]
|
||||
fn __pin_project_assert_not_repr_packed_Foo<T, U>(val: &Foo<T, U>) {
|
||||
&val.pinned;
|
||||
&val.unpinned;
|
||||
}
|
||||
unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,16 +1,16 @@
|
||||
// See ./pinned_drop-expanded.rs for generated code.
|
||||
// See ./unsafe_unpin-expanded.rs for generated code.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pin_project::{pin_project, UnsafeUnpin};
|
||||
|
||||
#[pin_project(UnsafeUnpin)]
|
||||
pub struct Foo<T, U> {
|
||||
pub struct Struct<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
|
||||
unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {}
|
||||
|
||||
fn main() {}
|
||||
|
169
third_party/rust/pin-project/src/lib.rs
vendored
169
third_party/rust/pin-project/src/lib.rs
vendored
@ -1,13 +1,15 @@
|
||||
//! A crate for safe and ergonomic pin-projection.
|
||||
//! A crate for safe and ergonomic [pin-projection].
|
||||
//!
|
||||
//! ## Examples
|
||||
//! # Examples
|
||||
//!
|
||||
//! [`pin_project`] attribute creates a projection struct covering all the fields.
|
||||
//! [`#[pin_project]`][`pin_project`] attribute creates projection types
|
||||
//! covering all the fields of struct or enum.
|
||||
//!
|
||||
//! ```rust
|
||||
//! use pin_project::pin_project;
|
||||
//! use std::pin::Pin;
|
||||
//!
|
||||
//! use pin_project::pin_project;
|
||||
//!
|
||||
//! #[pin_project]
|
||||
//! struct Struct<T, U> {
|
||||
//! #[pin]
|
||||
@ -16,7 +18,7 @@
|
||||
//! }
|
||||
//!
|
||||
//! impl<T, U> Struct<T, U> {
|
||||
//! fn foo(self: Pin<&mut Self>) {
|
||||
//! fn method(self: Pin<&mut Self>) {
|
||||
//! let this = self.project();
|
||||
//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
|
||||
//! let _: &mut U = this.unpinned; // Normal reference to the field
|
||||
@ -24,43 +26,44 @@
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! [Code like this will be generated](https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs)
|
||||
//! [*code like this will be generated*][struct-default-expanded]
|
||||
//!
|
||||
//! See [`pin_project`] attribute for more details.
|
||||
//!
|
||||
//! Also, there are examples and generated code of each feature in [examples](https://github.com/taiki-e/pin-project/blob/master/examples/README.md) directory.
|
||||
//! See [`#[pin_project]`][`pin_project`] attribute for more details, and
|
||||
//! see [examples] directory for more examples and generated code.
|
||||
//!
|
||||
//! [`pin_project`]: attr.pin_project.html
|
||||
//! [examples]: https://github.com/taiki-e/pin-project/blob/master/examples/README.md
|
||||
//! [pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
|
||||
//! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs
|
||||
|
||||
#![no_std]
|
||||
#![recursion_limit = "256"]
|
||||
#![doc(html_root_url = "https://docs.rs/pin-project/0.4.9")]
|
||||
#![doc(test(
|
||||
no_crate_inject,
|
||||
attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
|
||||
))]
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(missing_docs, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
|
||||
#![warn(clippy::all)]
|
||||
// mem::take requires Rust 1.40
|
||||
#![allow(clippy::mem_replace_with_default)]
|
||||
#![warn(clippy::all, clippy::default_trait_access)]
|
||||
// mem::take and #[non_exhaustive] requires Rust 1.40
|
||||
#![allow(clippy::mem_replace_with_default, clippy::manual_non_exhaustive)]
|
||||
#![allow(clippy::needless_doctest_main)]
|
||||
|
||||
#[doc(inline)]
|
||||
pub use pin_project_internal::pin_project;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use pin_project_internal::pinned_drop;
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[doc(inline)]
|
||||
pub use pin_project_internal::project;
|
||||
|
||||
#[allow(deprecated)]
|
||||
#[doc(inline)]
|
||||
pub use pin_project_internal::project_ref;
|
||||
#[allow(deprecated)]
|
||||
#[doc(inline)]
|
||||
pub use pin_project_internal::project_replace;
|
||||
|
||||
/// A trait used for custom implementations of [`Unpin`].
|
||||
/// This trait is used in conjunction with the `UnsafeUnpin`
|
||||
/// argument to [`pin_project`]
|
||||
/// argument to [`#[pin_project]`][`pin_project`]
|
||||
///
|
||||
/// The Rust [`Unpin`] trait is safe to implement - by itself,
|
||||
/// implementing it cannot lead to undefined behavior. Undefined
|
||||
@ -73,9 +76,9 @@ pub use pin_project_internal::project_ref;
|
||||
///
|
||||
/// However, things change if you want to provide a custom [`Unpin`] impl
|
||||
/// for your `#[pin_project]` type. As stated in [the Rust
|
||||
/// documentation](https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning),
|
||||
/// you must be sure to only implement [`Unpin`] when all of your `#[pin]` fields (i.e. structurally
|
||||
/// pinned fields) are also [`Unpin`].
|
||||
/// documentation][pin-projection], you must be sure to only implement [`Unpin`]
|
||||
/// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also
|
||||
/// [`Unpin`].
|
||||
///
|
||||
/// To help highlight this unsafety, the `UnsafeUnpin` trait is provided.
|
||||
/// Implementing this trait is logically equivalent to implementing [`Unpin`] -
|
||||
@ -87,15 +90,16 @@ pub use pin_project_internal::project_ref;
|
||||
///
|
||||
/// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not*
|
||||
/// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`].
|
||||
/// This is effectively the same thing as adding a [`PhantomPinned`] to your type
|
||||
/// This is effectively the same thing as adding a [`PhantomPinned`] to your
|
||||
/// type.
|
||||
///
|
||||
/// Since this trait is `unsafe`, impls of it will be detected by the `unsafe_code` lint,
|
||||
/// and by tools like `cargo geiger`.
|
||||
/// Since this trait is `unsafe`, impls of it will be detected by the
|
||||
/// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger].
|
||||
///
|
||||
/// ## Examples
|
||||
/// # Examples
|
||||
///
|
||||
/// An `UnsafeUnpin` impl which, in addition to requiring that structurally pinned
|
||||
/// fields be [`Unpin`], imposes an additional requirement:
|
||||
/// An `UnsafeUnpin` impl which, in addition to requiring that structurally
|
||||
/// pinned fields be [`Unpin`], imposes an additional requirement:
|
||||
///
|
||||
/// ```rust
|
||||
/// use pin_project::{pin_project, UnsafeUnpin};
|
||||
@ -112,34 +116,41 @@ pub use pin_project_internal::project_ref;
|
||||
///
|
||||
/// [`PhantomPinned`]: core::marker::PhantomPinned
|
||||
/// [`pin_project`]: attr.pin_project.html
|
||||
#[allow(unsafe_code)]
|
||||
/// [pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
|
||||
/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger
|
||||
pub unsafe trait UnsafeUnpin {}
|
||||
|
||||
// Not public API.
|
||||
#[doc(hidden)]
|
||||
pub mod __private {
|
||||
use super::UnsafeUnpin;
|
||||
use core::{marker::PhantomData, pin::Pin};
|
||||
#[doc(hidden)]
|
||||
pub use core::{
|
||||
marker::{PhantomData, PhantomPinned, Unpin},
|
||||
mem::ManuallyDrop,
|
||||
ops::Drop,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub use pin_project_internal::__PinProjectInternalDerive;
|
||||
|
||||
// It is safe to implement PinnedDrop::drop, but it is not safe to call it.
|
||||
// This is because destructors can be called multiple times (double dropping
|
||||
// is unsound: rust-lang/rust#62360).
|
||||
use super::UnsafeUnpin;
|
||||
|
||||
// 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](https://github.com/rust-lang/rust/pull/62360).
|
||||
//
|
||||
// Ideally, it would be desirable to be able to prohibit manual calls in the
|
||||
// same way as Drop::drop, but the library cannot. So, by using macros and
|
||||
// replacing them with private traits, we prevent users from calling
|
||||
// PinnedDrop::drop.
|
||||
// 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, we prevent users from
|
||||
// calling `PinnedDrop::drop`.
|
||||
//
|
||||
// Users can implement `Drop` safely using `#[pinned_drop]`.
|
||||
// Users can implement [`Drop`] safely using `#[pinned_drop]` and can drop a
|
||||
// type that implements `PinnedDrop` using the [`drop`] function safely.
|
||||
// **Do not call or implement this trait directly.**
|
||||
#[doc(hidden)]
|
||||
pub trait PinnedDrop {
|
||||
// Since calling it twice on the same object would be UB,
|
||||
// this method is unsafe.
|
||||
#[allow(unsafe_code)]
|
||||
#[doc(hidden)]
|
||||
unsafe fn drop(self: Pin<&mut Self>);
|
||||
}
|
||||
@ -151,6 +162,7 @@ pub mod __private {
|
||||
//
|
||||
// Supposed we have the following code:
|
||||
//
|
||||
// ```rust
|
||||
// #[pin_project(UnsafeUnpin)]
|
||||
// struct MyStruct<T> {
|
||||
// #[pin] field: T
|
||||
@ -158,48 +170,81 @@ pub mod __private {
|
||||
//
|
||||
// impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal
|
||||
// impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
|
||||
// ```
|
||||
//
|
||||
// We want this code to be rejected - the user is completely bypassing `UnsafeUnpin`,
|
||||
// and providing an unsound Unpin impl in safe code!
|
||||
// We want this code to be rejected - the user is completely bypassing
|
||||
// `UnsafeUnpin`, and providing an unsound Unpin impl in safe code!
|
||||
//
|
||||
// Unfortunately, the Rust compiler will accept the above code.
|
||||
// Because MyStruct is declared in the same crate as the user-provided impl,
|
||||
// the compiler will notice that 'MyStruct<T>: UnsafeUnpin' never holds.
|
||||
// the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds.
|
||||
//
|
||||
// The solution is to introduce the 'Wrapper' struct, which is defined
|
||||
// in the 'pin-project' crate.
|
||||
// The solution is to introduce the `Wrapper` struct, which is defined
|
||||
// in the `pin-project` crate.
|
||||
//
|
||||
// We now have code that looks like this:
|
||||
//
|
||||
// ```rust
|
||||
// impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal
|
||||
// impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
|
||||
// ```
|
||||
//
|
||||
// We also have 'unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}' in the
|
||||
// 'pin-project' crate.
|
||||
// We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}`
|
||||
// in the `pin-project` crate.
|
||||
//
|
||||
// Now, our generated impl has a bound involving a type defined in another crate - Wrapper.
|
||||
// This will cause rust to conservatively assume that 'Wrapper<MyStruct<T>>: UnsafeUnpin'
|
||||
// holds, in the interest of preserving forwards compatibility (in case such an impl is added
|
||||
// for Wrapper<T> in a new version of the crate).
|
||||
// Now, our generated impl has a bound involving a type defined in another
|
||||
// crate - Wrapper. This will cause rust to conservatively assume that
|
||||
// `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving
|
||||
// forwards compatibility (in case such an impl is added for Wrapper<T> in
|
||||
// a new version of the crate).
|
||||
//
|
||||
// This will cause rust to reject any other Unpin impls for MyStruct<T>, since it will
|
||||
// assume that our generated impl could potentially apply in any situation.
|
||||
// This will cause rust to reject any other `Unpin` impls for MyStruct<T>,
|
||||
// since it will assume that our generated impl could potentially apply in
|
||||
// any situation.
|
||||
//
|
||||
// This achieves the desired effect - when the user writes `#[pin_project(UnsafeUnpin)]`,
|
||||
// the user must either provide no impl of `UnsafeUnpin` (which is equivalent
|
||||
// to making the type never implement Unpin), or provide an impl of `UnsafeUnpin`.
|
||||
// It is impossible for them to provide an impl of `Unpin`
|
||||
// This achieves the desired effect - when the user writes
|
||||
// `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of
|
||||
// `UnsafeUnpin` (which is equivalent to making the type never implement
|
||||
// Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to
|
||||
// provide an impl of `Unpin`
|
||||
#[doc(hidden)]
|
||||
pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T);
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl<T: ?Sized> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {}
|
||||
|
||||
// This is an internal helper struct used by `pin-project-internal`.
|
||||
//
|
||||
// See https://github.com/taiki-e/pin-project/pull/53 for more details.
|
||||
#[doc(hidden)]
|
||||
pub struct AlwaysUnpin<'a, T: ?Sized>(PhantomData<&'a ()>, PhantomData<T>);
|
||||
pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>);
|
||||
|
||||
impl<T: ?Sized> Unpin for AlwaysUnpin<'_, T> {}
|
||||
impl<T> Unpin for AlwaysUnpin<'_, T> {}
|
||||
|
||||
// This is an internal helper used to ensure a value is dropped.
|
||||
#[doc(hidden)]
|
||||
pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T);
|
||||
|
||||
impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ptr::drop_in_place(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is an internal helper used to ensure a value is overwritten without
|
||||
// its destructor being called.
|
||||
#[doc(hidden)]
|
||||
pub struct UnsafeOverwriteGuard<T> {
|
||||
pub value: ManuallyDrop<T>,
|
||||
pub target: *mut T,
|
||||
}
|
||||
|
||||
impl<T> Drop for UnsafeOverwriteGuard<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ptr::write(self.target, ptr::read(&*self.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
third_party/rust/pin-project/tests/cfg.rs
vendored
40
third_party/rust/pin-project/tests/cfg.rs
vendored
@ -1,29 +1,29 @@
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
// Refs: https://doc.rust-lang.org/nightly/reference/attributes.html
|
||||
|
||||
use pin_project::pin_project;
|
||||
use std::{marker::PhantomPinned, pin::Pin};
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
fn is_unpin<T: Unpin>() {}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct Linux;
|
||||
struct Linux;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub struct Other;
|
||||
struct Other;
|
||||
|
||||
// Use this type to check that `cfg(any())` is working properly.
|
||||
// If `cfg(any())` is not working properly, `is_unpin` will fail.
|
||||
pub struct Any(PhantomPinned);
|
||||
struct Any(PhantomPinned);
|
||||
|
||||
#[test]
|
||||
fn cfg() {
|
||||
// structs
|
||||
|
||||
#[pin_project]
|
||||
pub struct SameName {
|
||||
#[pin_project(project_replace)]
|
||||
struct SameName {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pin]
|
||||
inner: Linux,
|
||||
@ -42,8 +42,8 @@ fn cfg() {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let _x = SameName { inner: Other };
|
||||
|
||||
#[pin_project]
|
||||
pub struct DifferentName {
|
||||
#[pin_project(project_replace)]
|
||||
struct DifferentName {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pin]
|
||||
l: Linux,
|
||||
@ -62,8 +62,8 @@ fn cfg() {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let _x = DifferentName { o: Other };
|
||||
|
||||
#[pin_project]
|
||||
pub struct TupleStruct(
|
||||
#[pin_project(project_replace)]
|
||||
struct TupleStruct(
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pin]
|
||||
Linux,
|
||||
@ -84,8 +84,8 @@ fn cfg() {
|
||||
|
||||
// enums
|
||||
|
||||
#[pin_project]
|
||||
pub enum Variant {
|
||||
#[pin_project(project_replace)]
|
||||
enum Variant {
|
||||
#[cfg(target_os = "linux")]
|
||||
Inner(#[pin] Linux),
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
@ -111,8 +111,8 @@ fn cfg() {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let _x = Variant::Other(Other);
|
||||
|
||||
#[pin_project]
|
||||
pub enum Field {
|
||||
#[pin_project(project_replace)]
|
||||
enum Field {
|
||||
SameName {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[pin]
|
||||
@ -168,8 +168,8 @@ fn cfg() {
|
||||
|
||||
#[test]
|
||||
fn cfg_attr() {
|
||||
#[pin_project]
|
||||
pub struct SameCfg {
|
||||
#[pin_project(project_replace)]
|
||||
struct SameCfg {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(target_os = "linux", pin)]
|
||||
inner: Linux,
|
||||
@ -194,8 +194,8 @@ fn cfg_attr() {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let _: Pin<&mut Other> = x.inner;
|
||||
|
||||
#[pin_project]
|
||||
pub struct DifferentCfg {
|
||||
#[pin_project(project_replace)]
|
||||
struct DifferentCfg {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg_attr(target_os = "linux", pin)]
|
||||
inner: Linux,
|
||||
@ -234,7 +234,7 @@ fn cfg_attr() {
|
||||
#[test]
|
||||
fn cfg_attr_any_packed() {
|
||||
// Since `cfg(any())` can never be true, it is okay for this to pass.
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
#[cfg_attr(any(), repr(packed))]
|
||||
struct Struct {
|
||||
#[pin]
|
||||
|
@ -1,12 +1,11 @@
|
||||
#![cfg(pin_project_show_unpin_struct)]
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
|
||||
#[ignore]
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/cfg/*.rs");
|
||||
t.compile_fail("tests/ui/not_unpin/*.rs");
|
||||
t.compile_fail("tests/ui/pin_project/*.rs");
|
||||
t.compile_fail("tests/ui/pinned_drop/*.rs");
|
||||
t.compile_fail("tests/ui/project/*.rs");
|
||||
|
158
third_party/rust/pin-project/tests/drop_order.rs
vendored
Normal file
158
third_party/rust/pin-project/tests/drop_order.rs
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
|
||||
use std::{cell::Cell, pin::Pin, thread};
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
struct D<'a>(&'a Cell<usize>, usize);
|
||||
|
||||
impl Drop for D<'_> {
|
||||
fn drop(&mut self) {
|
||||
if !thread::panicking() {
|
||||
let old = self.0.replace(self.1);
|
||||
assert_eq!(old, self.1 - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct StructPinned<'a> {
|
||||
#[pin]
|
||||
f1: D<'a>,
|
||||
#[pin]
|
||||
f2: D<'a>,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct StructUnpinned<'a> {
|
||||
f1: D<'a>,
|
||||
f2: D<'a>,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct TuplePinned<'a>(#[pin] D<'a>, #[pin] D<'a>);
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct TupleUnpinned<'a>(D<'a>, D<'a>);
|
||||
|
||||
#[pin_project(project_replace= EnumProj)]
|
||||
enum Enum<'a> {
|
||||
StructPinned {
|
||||
#[pin]
|
||||
f1: D<'a>,
|
||||
#[pin]
|
||||
f2: D<'a>,
|
||||
},
|
||||
StructUnpinned {
|
||||
f1: D<'a>,
|
||||
f2: D<'a>,
|
||||
},
|
||||
TuplePinned(#[pin] D<'a>, #[pin] D<'a>),
|
||||
TupleUnpinned(D<'a>, D<'a>),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_pinned() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn struct_unpinned() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_pinned() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = TuplePinned(D(&c, 1), D(&c, 2));
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = TuplePinned(D(&c, 1), D(&c, 2));
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(TuplePinned(D(&c, 3), D(&c, 4)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_unpinned() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = TupleUnpinned(D(&c, 1), D(&c, 2));
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = TupleUnpinned(D(&c, 1), D(&c, 2));
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(TupleUnpinned(D(&c, 3), D(&c, 4)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enum_struct() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
|
||||
}
|
||||
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enum_tuple() {
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(Enum::TuplePinned(D(&c, 3), D(&c, 4)));
|
||||
}
|
||||
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
|
||||
}
|
||||
{
|
||||
let c = Cell::new(0);
|
||||
let mut _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
|
||||
let _y = Pin::new(&mut _x);
|
||||
let _z = _y.project_replace(Enum::TupleUnpinned(D(&c, 3), D(&c, 4)));
|
||||
}
|
||||
}
|
136
third_party/rust/pin-project/tests/include/basic-safe-part.rs
vendored
Normal file
136
third_party/rust/pin-project/tests/include/basic-safe-part.rs
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
// default #[pin_project], PinnedDrop, project_replace, !Unpin, and UnsafeUnpin without UnsafeUnpin impl are completely safe.
|
||||
|
||||
#[::pin_project::pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct DefaultStruct<T, U> {
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct DefaultTupleStruct<T, U>(#[pin] pub T, pub U);
|
||||
|
||||
#[::pin_project::pin_project]
|
||||
#[derive(Debug)]
|
||||
pub enum DefaultEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(PinnedDrop)]
|
||||
#[derive(Debug)]
|
||||
pub struct PinnedDropStruct<T, U> {
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[::pin_project::pinned_drop]
|
||||
impl<T, U> PinnedDrop for PinnedDropStruct<T, U> {
|
||||
fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(PinnedDrop)]
|
||||
#[derive(Debug)]
|
||||
pub struct PinnedDropTupleStruct<T, U>(#[pin] pub T, pub U);
|
||||
|
||||
#[::pin_project::pinned_drop]
|
||||
impl<T, U> PinnedDrop for PinnedDropTupleStruct<T, U> {
|
||||
fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(PinnedDrop)]
|
||||
#[derive(Debug)]
|
||||
pub enum PinnedDropEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[::pin_project::pinned_drop]
|
||||
impl<T, U> PinnedDrop for PinnedDropEnum<T, U> {
|
||||
fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct ReplaceStruct<T, U> {
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct ReplaceTupleStruct<T, U>(#[pin] pub T, pub U);
|
||||
|
||||
#[::pin_project::pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub enum ReplaceEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(UnsafeUnpin)]
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeUnpinStruct<T, U> {
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(UnsafeUnpin)]
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
|
||||
|
||||
#[::pin_project::pin_project(UnsafeUnpin)]
|
||||
#[derive(Debug)]
|
||||
pub enum UnsafeUnpinEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(!Unpin)]
|
||||
#[derive(Debug)]
|
||||
pub struct NotUnpinStruct<T, U> {
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[::pin_project::pin_project(!Unpin)]
|
||||
#[derive(Debug)]
|
||||
pub struct NotUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
|
||||
|
||||
#[::pin_project::pin_project(!Unpin)]
|
||||
#[derive(Debug)]
|
||||
pub enum NotUnpinEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
14
third_party/rust/pin-project/tests/include/basic.rs
vendored
Normal file
14
third_party/rust/pin-project/tests/include/basic.rs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
include!("basic-safe-part.rs");
|
||||
|
||||
unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
|
||||
::pin_project::UnsafeUnpin for UnsafeUnpinStruct<T, U>
|
||||
{
|
||||
}
|
||||
unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
|
||||
::pin_project::UnsafeUnpin for UnsafeUnpinTupleStruct<T, U>
|
||||
{
|
||||
}
|
||||
unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
|
||||
::pin_project::UnsafeUnpin for UnsafeUnpinEnum<T, U>
|
||||
{
|
||||
}
|
127
third_party/rust/pin-project/tests/lint.rs
vendored
Normal file
127
third_party/rust/pin-project/tests/lint.rs
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
#![warn(nonstandard_style, rust_2018_idioms, unused)]
|
||||
// Note: This does not guarantee compatibility with forbidding these lints in the future.
|
||||
// If rustc adds a new lint, we may not be able to keep this.
|
||||
#![forbid(future_incompatible, rust_2018_compatibility)]
|
||||
#![allow(unknown_lints)] // for old compilers
|
||||
#![warn(
|
||||
box_pointers,
|
||||
deprecated_in_future,
|
||||
elided_lifetimes_in_paths,
|
||||
explicit_outlives_requirements,
|
||||
macro_use_extern_crate,
|
||||
meta_variable_misuse,
|
||||
missing_copy_implementations,
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
non_ascii_idents,
|
||||
single_use_lifetimes,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unaligned_references,
|
||||
unreachable_pub,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
unused_lifetimes,
|
||||
unused_qualifications,
|
||||
unused_results,
|
||||
variant_size_differences
|
||||
)]
|
||||
// absolute_paths_not_starting_with_crate, anonymous_parameters, keyword_idents, pointer_structural_match: forbidden as a part of future_incompatible
|
||||
// unsafe_block_in_unsafe_fn: unstable: https://github.com/rust-lang/rust/issues/71668
|
||||
// unsafe_code: checked in forbid_unsafe module
|
||||
// unstable_features: deprecated: https://doc.rust-lang.org/beta/rustc/lints/listing/allowed-by-default.html#unstable-features
|
||||
// unused_crate_dependencies: unrelated
|
||||
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
|
||||
|
||||
// Check interoperability with rustc and clippy lints.
|
||||
|
||||
pub mod basic {
|
||||
include!("include/basic.rs");
|
||||
}
|
||||
|
||||
pub mod forbid_unsafe {
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
include!("include/basic-safe-part.rs");
|
||||
}
|
||||
|
||||
pub mod clippy {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct MutMutStruct<'a, T, U> {
|
||||
#[pin]
|
||||
pub pinned: &'a mut T,
|
||||
pub unpinned: &'a mut U,
|
||||
}
|
||||
|
||||
#[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct MutMutTupleStruct<'a, T, U>(#[pin] &'a mut T, &'a mut U);
|
||||
|
||||
#[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub enum MutMutEnum<'a, T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: &'a mut T,
|
||||
unpinned: &'a mut U,
|
||||
},
|
||||
Tuple(#[pin] &'a mut T, &'a mut U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct TypeRepetitionInBoundsStruct<T, U>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#[pin]
|
||||
pub pinned: T,
|
||||
pub unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct TypeRepetitionInBoundsTupleStruct<T, U>(#[pin] T, U)
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub enum TypeRepetitionInBoundsEnum<T, U>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Struct {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
},
|
||||
Tuple(#[pin] T, U),
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub struct UsedUnderscoreBindingStruct<T, U> {
|
||||
#[pin]
|
||||
pub _pinned: T,
|
||||
pub _unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Debug)]
|
||||
pub enum UsedUnderscoreBindingEnum<T, U> {
|
||||
Struct {
|
||||
#[pin]
|
||||
_pinned: T,
|
||||
_unpinned: U,
|
||||
},
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
use pin_project::{pin_project, project};
|
||||
|
||||
trait Bar<X> {
|
||||
type Y;
|
||||
}
|
||||
|
||||
struct Example<A>(A);
|
||||
|
||||
impl<X, T> Bar<X> for Example<T> {
|
||||
type Y = Option<T>;
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct Foo<A, B> {
|
||||
_x: <Example<A> as Bar<B>>::Y,
|
||||
}
|
||||
|
||||
#[project]
|
||||
impl<A, B> Foo<A, B> {}
|
614
third_party/rust/pin-project/tests/pin_project.rs
vendored
614
third_party/rust/pin-project/tests/pin_project.rs
vendored
@ -1,56 +1,71 @@
|
||||
#![no_std]
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use core::{marker::PhantomPinned, pin::Pin};
|
||||
use std::{
|
||||
marker::{PhantomData, PhantomPinned},
|
||||
pin::Pin,
|
||||
};
|
||||
|
||||
use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
|
||||
|
||||
#[test]
|
||||
fn test_pin_project() {
|
||||
#[pin_project]
|
||||
fn projection() {
|
||||
#[pin_project(
|
||||
project = StructProj,
|
||||
project_ref = StructProjRef,
|
||||
project_replace = StructProjOwn,
|
||||
)]
|
||||
struct Struct<T, U> {
|
||||
#[pin]
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
|
||||
let mut foo = Struct { field1: 1, field2: 2 };
|
||||
let mut s = Struct { field1: 1, field2: 2 };
|
||||
let mut s_orig = Pin::new(&mut s);
|
||||
let s = s_orig.as_mut().project();
|
||||
|
||||
let mut foo_orig = Pin::new(&mut foo);
|
||||
let foo = foo_orig.as_mut().project();
|
||||
|
||||
let x: Pin<&mut i32> = foo.field1;
|
||||
let x: Pin<&mut i32> = s.field1;
|
||||
assert_eq!(*x, 1);
|
||||
|
||||
let y: &mut i32 = foo.field2;
|
||||
let y: &mut i32 = s.field2;
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
assert_eq!(foo_orig.as_ref().field1, 1);
|
||||
assert_eq!(foo_orig.as_ref().field2, 2);
|
||||
assert_eq!(s_orig.as_ref().field1, 1);
|
||||
assert_eq!(s_orig.as_ref().field2, 2);
|
||||
|
||||
let mut foo = Struct { field1: 1, field2: 2 };
|
||||
let mut s = Struct { field1: 1, field2: 2 };
|
||||
|
||||
let foo = Pin::new(&mut foo).project();
|
||||
|
||||
let __StructProjection { field1, field2 } = foo;
|
||||
let StructProj { field1, field2 } = Pin::new(&mut s).project();
|
||||
let _: Pin<&mut i32> = field1;
|
||||
let _: &mut i32 = field2;
|
||||
|
||||
#[pin_project]
|
||||
let StructProjRef { field1, field2 } = Pin::new(&s).project_ref();
|
||||
let _: Pin<&i32> = field1;
|
||||
let _: &i32 = field2;
|
||||
|
||||
let mut s = Pin::new(&mut s);
|
||||
let StructProjOwn { field1, field2 } =
|
||||
s.as_mut().project_replace(Struct { field1: 3, field2: 4 });
|
||||
let _: PhantomData<i32> = field1;
|
||||
let _: i32 = field2;
|
||||
assert_eq!(field2, 2);
|
||||
assert_eq!(s.field1, 3);
|
||||
assert_eq!(s.field2, 4);
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct TupleStruct<T, U>(#[pin] T, U);
|
||||
|
||||
let mut bar = TupleStruct(1, 2);
|
||||
let mut s = TupleStruct(1, 2);
|
||||
let s = Pin::new(&mut s).project();
|
||||
|
||||
let bar = Pin::new(&mut bar).project();
|
||||
|
||||
let x: Pin<&mut i32> = bar.0;
|
||||
let x: Pin<&mut i32> = s.0;
|
||||
assert_eq!(*x, 1);
|
||||
|
||||
let y: &mut i32 = bar.1;
|
||||
let y: &mut i32 = s.1;
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace, project = EnumProj)]
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
enum Enum<A, B, C, D> {
|
||||
Variant1(#[pin] A, B),
|
||||
@ -62,48 +77,46 @@ fn test_pin_project() {
|
||||
None,
|
||||
}
|
||||
|
||||
let mut baz = Enum::Variant1(1, 2);
|
||||
let mut e = Enum::Variant1(1, 2);
|
||||
let mut e_orig = Pin::new(&mut e);
|
||||
let e = e_orig.as_mut().project();
|
||||
|
||||
let mut baz_orig = Pin::new(&mut baz);
|
||||
let baz = baz_orig.as_mut().project();
|
||||
|
||||
match baz {
|
||||
__EnumProjection::Variant1(x, y) => {
|
||||
match e {
|
||||
EnumProj::Variant1(x, y) => {
|
||||
let x: Pin<&mut i32> = x;
|
||||
assert_eq!(*x, 1);
|
||||
|
||||
let y: &mut i32 = y;
|
||||
assert_eq!(*y, 2);
|
||||
}
|
||||
__EnumProjection::Variant2 { field1, field2 } => {
|
||||
EnumProj::Variant2 { field1, field2 } => {
|
||||
let _x: Pin<&mut i32> = field1;
|
||||
let _y: &mut i32 = field2;
|
||||
}
|
||||
__EnumProjection::None => {}
|
||||
EnumProj::None => {}
|
||||
}
|
||||
|
||||
assert_eq!(Pin::into_ref(baz_orig).get_ref(), &Enum::Variant1(1, 2));
|
||||
assert_eq!(Pin::into_ref(e_orig).get_ref(), &Enum::Variant1(1, 2));
|
||||
|
||||
let mut baz = Enum::Variant2 { field1: 3, field2: 4 };
|
||||
let mut e = Enum::Variant2 { field1: 3, field2: 4 };
|
||||
let mut e = Pin::new(&mut e).project();
|
||||
|
||||
let mut baz = Pin::new(&mut baz).project();
|
||||
|
||||
match &mut baz {
|
||||
__EnumProjection::Variant1(x, y) => {
|
||||
match &mut e {
|
||||
EnumProj::Variant1(x, y) => {
|
||||
let _x: &mut Pin<&mut i32> = x;
|
||||
let _y: &mut &mut i32 = y;
|
||||
}
|
||||
__EnumProjection::Variant2 { field1, field2 } => {
|
||||
EnumProj::Variant2 { field1, field2 } => {
|
||||
let x: &mut Pin<&mut i32> = field1;
|
||||
assert_eq!(**x, 3);
|
||||
|
||||
let y: &mut &mut i32 = field2;
|
||||
assert_eq!(**y, 4);
|
||||
}
|
||||
__EnumProjection::None => {}
|
||||
EnumProj::None => {}
|
||||
}
|
||||
|
||||
if let __EnumProjection::Variant2 { field1, field2 } = baz {
|
||||
if let EnumProj::Variant2 { field1, field2 } = e {
|
||||
let x: Pin<&mut i32> = field1;
|
||||
assert_eq!(*x, 3);
|
||||
|
||||
@ -114,31 +127,55 @@ fn test_pin_project() {
|
||||
|
||||
#[test]
|
||||
fn enum_project_set() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace, project = EnumProj)]
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
enum Bar {
|
||||
enum Enum {
|
||||
Variant1(#[pin] u8),
|
||||
Variant2(bool),
|
||||
}
|
||||
|
||||
let mut bar = Bar::Variant1(25);
|
||||
let mut bar_orig = Pin::new(&mut bar);
|
||||
let bar_proj = bar_orig.as_mut().project();
|
||||
let mut e = Enum::Variant1(25);
|
||||
let mut e_orig = Pin::new(&mut e);
|
||||
let e_proj = e_orig.as_mut().project();
|
||||
|
||||
match bar_proj {
|
||||
__BarProjection::Variant1(val) => {
|
||||
let new_bar = Bar::Variant2(val.as_ref().get_ref() == &25);
|
||||
bar_orig.set(new_bar);
|
||||
match e_proj {
|
||||
EnumProj::Variant1(val) => {
|
||||
let new_e = Enum::Variant2(val.as_ref().get_ref() == &25);
|
||||
e_orig.set(new_e);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
assert_eq!(bar, Bar::Variant2(true));
|
||||
assert_eq!(e, Enum::Variant2(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn where_clause_and_associated_type_fields() {
|
||||
fn where_clause() {
|
||||
#[pin_project]
|
||||
struct Struct<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
field: T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct<T>(T)
|
||||
where
|
||||
T: Copy;
|
||||
|
||||
#[pin_project]
|
||||
enum EnumWhere<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
Variant(T),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn where_clause_and_associated_type_field() {
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct1<I>
|
||||
where
|
||||
I: Iterator,
|
||||
@ -148,7 +185,7 @@ fn where_clause_and_associated_type_fields() {
|
||||
field2: I::Item,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct2<I, J>
|
||||
where
|
||||
I: Iterator<Item = J>,
|
||||
@ -158,8 +195,8 @@ fn where_clause_and_associated_type_fields() {
|
||||
field2: J,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct Struct3<T>
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct3<T>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
@ -170,7 +207,12 @@ fn where_clause_and_associated_type_fields() {
|
||||
|
||||
impl<T> Static for Struct3<T> {}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct TupleStruct<I>(#[pin] I, I::Item)
|
||||
where
|
||||
I: Iterator;
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<I>
|
||||
where
|
||||
I: Iterator,
|
||||
@ -180,22 +222,9 @@ fn where_clause_and_associated_type_fields() {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
|
||||
#[test]
|
||||
fn unsized_in_where_clause() {
|
||||
#[pin_project]
|
||||
struct Struct<I>
|
||||
where
|
||||
I: ?Sized,
|
||||
{
|
||||
#[pin]
|
||||
field: I,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_copy() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
#[derive(Clone, Copy)]
|
||||
struct Struct<T> {
|
||||
val: T,
|
||||
@ -210,60 +239,61 @@ fn derive_copy() {
|
||||
fn move_out() {
|
||||
struct NotCopy;
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct {
|
||||
val: NotCopy,
|
||||
}
|
||||
|
||||
let foo = Struct { val: NotCopy };
|
||||
let _val: NotCopy = foo.val;
|
||||
let x = Struct { val: NotCopy };
|
||||
let _val: NotCopy = x.val;
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum {
|
||||
Variant(NotCopy),
|
||||
}
|
||||
|
||||
let bar = Enum::Variant(NotCopy);
|
||||
let _val: NotCopy = match bar {
|
||||
let x = Enum::Variant(NotCopy);
|
||||
#[allow(clippy::infallible_destructuring_match)]
|
||||
let _val: NotCopy = match x {
|
||||
Enum::Variant(val) => val,
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trait_bounds_on_type_generics() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct1<'a, T: ?Sized> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct2<'a, T: ::core::fmt::Debug> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct3<'a, T: core::fmt::Debug> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
|
||||
field: &'a mut T,
|
||||
}
|
||||
|
||||
let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct7<T: 'static> {
|
||||
field: T,
|
||||
}
|
||||
@ -272,16 +302,16 @@ fn trait_bounds_on_type_generics() {
|
||||
|
||||
impl<T> Static for Struct7<T> {}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct8<'a, 'b: 'a> {
|
||||
field1: &'a u8,
|
||||
field2: &'b u8,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct TupleStruct<'a, T: ?Sized>(&'a mut T);
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<'a, T: ?Sized> {
|
||||
Variant(&'a mut T),
|
||||
}
|
||||
@ -289,34 +319,77 @@ fn trait_bounds_on_type_generics() {
|
||||
|
||||
#[test]
|
||||
fn overlapping_lifetime_names() {
|
||||
#[pin_project]
|
||||
pub struct Foo<'pin, T> {
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct1<'pin, T> {
|
||||
#[pin]
|
||||
field: &'pin mut T,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct2<'pin, 'pin_, 'pin__> {
|
||||
#[pin]
|
||||
field: &'pin &'pin_ &'pin__ (),
|
||||
}
|
||||
|
||||
pub trait A<'a> {}
|
||||
|
||||
#[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
|
||||
#[pin_project(project_replace)]
|
||||
pub struct HRTB<'pin___, T>
|
||||
where
|
||||
for<'pin> &'pin T: Unpin,
|
||||
T: for<'pin> A<'pin>,
|
||||
for<'pin, 'pin_, 'pin__> &'pin &'pin_ &'pin__ T: Unpin,
|
||||
{
|
||||
#[pin]
|
||||
field: &'pin___ mut T,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn combine() {
|
||||
#[pin_project(PinnedDrop, UnsafeUnpin)]
|
||||
pub struct Foo<T> {
|
||||
field1: u8,
|
||||
pub struct PinnedDropWithUnsafeUnpin<T> {
|
||||
#[pin]
|
||||
field2: T,
|
||||
field: T,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T> PinnedDrop for Foo<T> {
|
||||
impl<T> PinnedDrop for PinnedDropWithUnsafeUnpin<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl<T: Unpin> UnsafeUnpin for Foo<T> {}
|
||||
unsafe impl<T: Unpin> UnsafeUnpin for PinnedDropWithUnsafeUnpin<T> {}
|
||||
|
||||
#[pin_project(PinnedDrop, !Unpin)]
|
||||
pub struct PinnedDropWithNotUnpin<T> {
|
||||
#[pin]
|
||||
field: T,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T> PinnedDrop for PinnedDropWithNotUnpin<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[pin_project(UnsafeUnpin, project_replace)]
|
||||
pub struct UnsafeUnpinWithReplace<T> {
|
||||
#[pin]
|
||||
field: T,
|
||||
}
|
||||
|
||||
unsafe impl<T: Unpin> UnsafeUnpin for UnsafeUnpinWithReplace<T> {}
|
||||
|
||||
#[pin_project(!Unpin, project_replace)]
|
||||
pub struct NotUnpinWithReplace<T> {
|
||||
#[pin]
|
||||
field: T,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private_type_in_public_type() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct PublicStruct<T> {
|
||||
#[pin]
|
||||
inner: PrivateStruct<T>,
|
||||
@ -325,23 +398,24 @@ fn private_type_in_public_type() {
|
||||
struct PrivateStruct<T>(T);
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
#[test]
|
||||
fn lifetime_project() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct1<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct2<'a, T, U> {
|
||||
#[pin]
|
||||
pinned: &'a mut T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
|
||||
enum Enum<T, U> {
|
||||
Variant {
|
||||
#[pin]
|
||||
@ -371,35 +445,35 @@ fn lifetime_project() {
|
||||
impl<T, U> Enum<T, U> {
|
||||
fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {
|
||||
match self.project_ref() {
|
||||
__EnumProjectionRef::Variant { pinned, .. } => pinned,
|
||||
EnumProjRef::Variant { pinned, .. } => pinned,
|
||||
}
|
||||
}
|
||||
fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
|
||||
match self.project() {
|
||||
__EnumProjection::Variant { pinned, .. } => pinned,
|
||||
EnumProj::Variant { pinned, .. } => pinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::since(1.36)]
|
||||
#[rustversion::since(1.36)] // https://github.com/rust-lang/rust/pull/61207
|
||||
#[test]
|
||||
fn lifetime_project_elided() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct1<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct2<'a, T, U> {
|
||||
#[pin]
|
||||
pinned: &'a mut T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
|
||||
enum Enum<T, U> {
|
||||
Variant {
|
||||
#[pin]
|
||||
@ -429,12 +503,12 @@ fn lifetime_project_elided() {
|
||||
impl<T, U> Enum<T, U> {
|
||||
fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
|
||||
match self.project_ref() {
|
||||
__EnumProjectionRef::Variant { pinned, .. } => pinned,
|
||||
EnumProjRef::Variant { pinned, .. } => pinned,
|
||||
}
|
||||
}
|
||||
fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
|
||||
match self.project() {
|
||||
__EnumProjection::Variant { pinned, .. } => pinned,
|
||||
EnumProj::Variant { pinned, .. } => pinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -443,7 +517,7 @@ fn lifetime_project_elided() {
|
||||
mod visibility {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub(crate) struct A {
|
||||
pub b: u8,
|
||||
}
|
||||
@ -461,7 +535,7 @@ fn visibility() {
|
||||
|
||||
#[test]
|
||||
fn trivial_bounds() {
|
||||
#[pin_project]
|
||||
#[pin_project(project_replace)]
|
||||
pub struct NoGenerics {
|
||||
#[pin]
|
||||
field: PhantomPinned,
|
||||
@ -471,82 +545,342 @@ fn trivial_bounds() {
|
||||
#[test]
|
||||
fn dst() {
|
||||
#[pin_project]
|
||||
pub struct A<T: ?Sized> {
|
||||
struct Struct1<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
let _: &mut A<dyn core::fmt::Debug> = &mut A { x: 0u8 } as _;
|
||||
let mut x = Struct1 { x: 0_u8 };
|
||||
let x: Pin<&mut Struct1<dyn core::fmt::Debug>> = Pin::new(&mut x as _);
|
||||
let _y: &mut (dyn core::fmt::Debug) = x.project().x;
|
||||
|
||||
#[pin_project]
|
||||
pub struct B<T: ?Sized> {
|
||||
struct Struct2<T: ?Sized> {
|
||||
#[pin]
|
||||
x: T,
|
||||
}
|
||||
|
||||
let mut x = Struct2 { x: 0_u8 };
|
||||
let x: Pin<&mut Struct2<dyn core::fmt::Debug + Unpin>> = Pin::new(&mut x as _);
|
||||
let _y: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().x;
|
||||
|
||||
#[pin_project(UnsafeUnpin)]
|
||||
struct Struct5<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project(UnsafeUnpin)]
|
||||
struct Struct6<T: ?Sized> {
|
||||
#[pin]
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct Struct7<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T: ?Sized> PinnedDrop for Struct7<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct Struct8<T: ?Sized> {
|
||||
#[pin]
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T: ?Sized> PinnedDrop for Struct8<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct Struct9<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct Struct10<T: ?Sized> {
|
||||
#[pin]
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct C<T: ?Sized>(T);
|
||||
struct TupleStruct1<T: ?Sized>(T);
|
||||
|
||||
#[pin_project]
|
||||
pub struct D<T: ?Sized>(#[pin] T);
|
||||
struct TupleStruct2<T: ?Sized>(#[pin] T);
|
||||
|
||||
#[pin_project(UnsafeUnpin)]
|
||||
struct TupleStruct5<T: ?Sized>(T);
|
||||
|
||||
#[pin_project(UnsafeUnpin)]
|
||||
struct TupleStruct6<T: ?Sized>(#[pin] T);
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct TupleStruct7<T: ?Sized>(T);
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T: ?Sized> PinnedDrop for TupleStruct7<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct TupleStruct8<T: ?Sized>(#[pin] T);
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T: ?Sized> PinnedDrop for TupleStruct8<T> {
|
||||
fn drop(self: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct TupleStruct9<T: ?Sized>(T);
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct TupleStruct10<T: ?Sized>(#[pin] T);
|
||||
}
|
||||
|
||||
#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
|
||||
#[test]
|
||||
fn unsized_in_where_clause() {
|
||||
#[pin_project]
|
||||
struct Struct3<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct Struct4<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
#[pin]
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct3<T>(T)
|
||||
where
|
||||
T: ?Sized;
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct4<T>(#[pin] T)
|
||||
where
|
||||
T: ?Sized;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dyn_type() {
|
||||
#[pin_project]
|
||||
struct Struct1 {
|
||||
a: i32,
|
||||
f: dyn core::fmt::Debug,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct Struct2 {
|
||||
a: i32,
|
||||
#[pin]
|
||||
f: dyn core::fmt::Debug,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct Struct3 {
|
||||
a: i32,
|
||||
f: dyn core::fmt::Debug + Send,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct Struct4 {
|
||||
a: i32,
|
||||
#[pin]
|
||||
f: dyn core::fmt::Debug + Send,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct1(dyn core::fmt::Debug);
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct2(#[pin] dyn core::fmt::Debug);
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct3(dyn core::fmt::Debug + Send);
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct4(#[pin] dyn core::fmt::Debug + Send);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_self() {
|
||||
macro_rules! mac {
|
||||
($($tt:tt)*) => {
|
||||
$($tt)*
|
||||
};
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Generics<T: Trait<Assoc = Self>>
|
||||
where
|
||||
Self: Trait<Assoc = Self>,
|
||||
<Self as Trait>::Assoc: Sized,
|
||||
mac!(Self): Trait<Assoc = mac!(Self)>,
|
||||
{
|
||||
_f: T,
|
||||
}
|
||||
|
||||
impl<T: Trait<Assoc = Self>> Trait for Generics<T> {
|
||||
type Assoc = Self;
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
pub struct Struct {
|
||||
_f1: Box<Self>,
|
||||
_f2: Box<<Self as Trait>::Assoc>,
|
||||
_f3: Box<mac!(Self)>,
|
||||
_f4: [(); Self::ASSOC],
|
||||
_f5: [(); Self::assoc()],
|
||||
_f6: [(); mac!(Self::assoc())],
|
||||
}
|
||||
|
||||
impl Struct {
|
||||
const ASSOC: usize = 1;
|
||||
const fn assoc() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for Struct {
|
||||
type Assoc = Self;
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct Tuple(
|
||||
Box<Self>,
|
||||
Box<<Self as Trait>::Assoc>,
|
||||
Box<mac!(Self)>,
|
||||
[(); Self::ASSOC],
|
||||
[(); Self::assoc()],
|
||||
[(); mac!(Self::assoc())],
|
||||
);
|
||||
|
||||
impl Tuple {
|
||||
const ASSOC: usize = 1;
|
||||
const fn assoc() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for Tuple {
|
||||
type Assoc = Self;
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum {
|
||||
Struct {
|
||||
_f1: Box<Self>,
|
||||
_f2: Box<<Self as Trait>::Assoc>,
|
||||
_f3: Box<mac!(Self)>,
|
||||
_f4: [(); Self::ASSOC],
|
||||
_f5: [(); Self::assoc()],
|
||||
_f6: [(); mac!(Self::assoc())],
|
||||
},
|
||||
Tuple(
|
||||
Box<Self>,
|
||||
Box<<Self as Trait>::Assoc>,
|
||||
Box<mac!(Self)>,
|
||||
[(); Self::ASSOC],
|
||||
[(); Self::assoc()],
|
||||
[(); mac!(Self::assoc())],
|
||||
),
|
||||
}
|
||||
|
||||
impl Enum {
|
||||
const ASSOC: usize = 1;
|
||||
const fn assoc() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for Enum {
|
||||
type Assoc = Self;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_in_where_clause() {
|
||||
pub trait Trait {}
|
||||
|
||||
#[pin_project]
|
||||
pub struct Struct1<T>
|
||||
where
|
||||
Self: Trait,
|
||||
{
|
||||
x: T,
|
||||
fn no_infer_outlives() {
|
||||
trait Bar<X> {
|
||||
type Y;
|
||||
}
|
||||
|
||||
impl<T> Trait for Struct1<T> {}
|
||||
struct Example<A>(A);
|
||||
|
||||
pub trait Trait2 {
|
||||
type Foo;
|
||||
impl<X, T> Bar<X> for Example<T> {
|
||||
type Y = Option<T>;
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct Struct2<T>
|
||||
where
|
||||
Self: Trait2<Foo = Struct1<T>>,
|
||||
<Self as Trait2>::Foo: Trait,
|
||||
{
|
||||
x: T,
|
||||
}
|
||||
|
||||
impl<T> Trait2 for Struct2<T> {
|
||||
type Foo = Struct1<T>;
|
||||
#[pin_project(project_replace)]
|
||||
struct Foo<A, B> {
|
||||
_x: <Example<A> as Bar<B>>::Y,
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/47949
|
||||
// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111
|
||||
#[allow(clippy::many_single_char_names)]
|
||||
#[test]
|
||||
fn project_replace_panic() {
|
||||
use std::panic;
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct S<T, U> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
unpinned: U,
|
||||
}
|
||||
|
||||
struct D<'a>(&'a mut bool, bool);
|
||||
impl Drop for D<'_> {
|
||||
fn drop(&mut self) {
|
||||
*self.0 = true;
|
||||
if self.1 {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (mut a, mut b, mut c, mut d) = (false, false, false, false);
|
||||
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };
|
||||
let _y = Pin::new(&mut x)
|
||||
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
|
||||
// Previous `x.pinned` was dropped and panicked when `project_replace` is
|
||||
// called, so this is unreachable.
|
||||
unreachable!();
|
||||
}));
|
||||
assert!(res.is_err());
|
||||
assert!(a);
|
||||
assert!(b);
|
||||
assert!(c);
|
||||
assert!(d);
|
||||
|
||||
let (mut a, mut b, mut c, mut d) = (false, false, false, false);
|
||||
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) };
|
||||
{
|
||||
let _y = Pin::new(&mut x)
|
||||
.project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
|
||||
// `_y` (previous `x.unpinned`) live to the end of this scope, so
|
||||
// this is not unreachable.
|
||||
// unreachable!();
|
||||
}
|
||||
unreachable!();
|
||||
}));
|
||||
assert!(res.is_err());
|
||||
assert!(a);
|
||||
assert!(b);
|
||||
assert!(c);
|
||||
assert!(d);
|
||||
}
|
||||
|
280
third_party/rust/pin-project/tests/pinned_drop.rs
vendored
280
third_party/rust/pin-project/tests/pinned_drop.rs
vendored
@ -1,9 +1,8 @@
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
use std::pin::Pin;
|
||||
|
||||
#[test]
|
||||
fn safe_project() {
|
||||
@ -27,66 +26,64 @@ fn safe_project() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mut_self_argument() {
|
||||
fn self_argument_in_macro() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct Struct {
|
||||
data: usize,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
let _: &mut _ = &mut self.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_in_vec() {
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct Struct {
|
||||
data: usize,
|
||||
x: (),
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
let _: Vec<_> = vec![self.data];
|
||||
let _: Vec<_> = vec![self.x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_in_macro_containing_fn() {
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
data: usize,
|
||||
}
|
||||
use std::pin::Pin;
|
||||
|
||||
macro_rules! emit {
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
macro_rules! mac {
|
||||
($($tt:tt)*) => {
|
||||
$($tt)*
|
||||
};
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
_x: (),
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
let _ = emit!({
|
||||
let _ = mac!({
|
||||
impl Struct {
|
||||
pub fn f(self) {}
|
||||
pub fn _f(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
});
|
||||
self.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_call() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
data: usize,
|
||||
pub struct Struct<T> {
|
||||
_x: T,
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
@ -97,10 +94,10 @@ fn self_call() {
|
||||
fn assoc_fn(_this: Pin<&mut Self>) {}
|
||||
}
|
||||
|
||||
impl Trait for Struct {}
|
||||
impl<T> Trait for Struct<T> {}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
impl<T> PinnedDrop for Struct<T> {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
self.self_ref();
|
||||
self.as_ref().self_pin_ref();
|
||||
@ -112,74 +109,45 @@ fn self_call() {
|
||||
}
|
||||
}
|
||||
|
||||
// See also `ui/pinned_drop/self.rs`.
|
||||
#[test]
|
||||
fn self_expr() {
|
||||
fn self_struct() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
x: usize,
|
||||
pub x: (),
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
#[allow(clippy::match_single_binding)]
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
let _: Self = Self { x: 0 };
|
||||
// expr
|
||||
let _: Self = Self { x: () };
|
||||
|
||||
// pat
|
||||
match *self {
|
||||
Self { x: _ } => {}
|
||||
}
|
||||
if let Self { x: _ } = *self {}
|
||||
let Self { x: _ } = *self;
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct TupleStruct(usize);
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for TupleStruct {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
let _: Self = Self(0);
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::since(1.37)]
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub enum Enum {
|
||||
StructVariant { x: usize },
|
||||
TupleVariant(usize),
|
||||
}
|
||||
|
||||
#[rustversion::since(1.37)]
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Enum {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
// let _: Self = Self::StructVariant { x: 0 }; //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
let _: Self = Self::TupleVariant(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See also `ui/pinned_drop/self.rs`.
|
||||
#[test]
|
||||
fn self_pat() {
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
x: usize,
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
// match *self {
|
||||
// Self { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// }
|
||||
// if let Self { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// let Self { x: _ } = *self; //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct TupleStruct(usize);
|
||||
pub struct TupleStruct(());
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for TupleStruct {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
// expr
|
||||
let _: Self = Self(());
|
||||
|
||||
// pat
|
||||
match *self {
|
||||
Self(_) => {}
|
||||
}
|
||||
@ -187,24 +155,148 @@ fn self_pat() {
|
||||
let Self(_) = *self;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::since(1.37)] // type_alias_enum_variants requires Rust 1.37
|
||||
#[test]
|
||||
fn self_enum() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[rustversion::since(1.37)]
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub enum Enum {
|
||||
StructVariant { x: usize },
|
||||
TupleVariant(usize),
|
||||
Struct { x: () },
|
||||
Tuple(()),
|
||||
}
|
||||
|
||||
#[rustversion::since(1.37)]
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Enum {
|
||||
fn drop(mut self: Pin<&mut Self>) {
|
||||
// match *self {
|
||||
// Self::StructVariant { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// Self::TupleVariant(_) => {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// }
|
||||
// if let Self::StructVariant { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// if let Self::TupleVariant(_) = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
|
||||
// expr
|
||||
let _: Self = Self::Struct { x: () };
|
||||
let _: Self = Self::Tuple(());
|
||||
|
||||
// pat
|
||||
match *self {
|
||||
Self::Struct { x: _ } => {}
|
||||
Self::Tuple(_) => {}
|
||||
}
|
||||
if let Self::Struct { x: _ } = *self {}
|
||||
if let Self::Tuple(_) = *self {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See also `ui/pinned_drop/self.rs`.
|
||||
#[rustversion::since(1.40)] // https://github.com/rust-lang/rust/pull/64690
|
||||
#[test]
|
||||
fn self_in_macro_def() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct {
|
||||
_x: (),
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
macro_rules! mac {
|
||||
() => {{
|
||||
let _ = self;
|
||||
}};
|
||||
}
|
||||
mac!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn self_inside_macro() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
macro_rules! mac {
|
||||
($($tt:tt)*) => {
|
||||
$($tt)*
|
||||
};
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
pub struct Struct<T: Send>
|
||||
where
|
||||
mac!(Self): Send,
|
||||
{
|
||||
_x: T,
|
||||
}
|
||||
|
||||
impl<T: Send> Struct<T> {
|
||||
const ASSOCIATED1: &'static str = "1";
|
||||
fn associated1() {}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type Associated2;
|
||||
const ASSOCIATED2: &'static str;
|
||||
fn associated2();
|
||||
}
|
||||
|
||||
impl<T: Send> Trait for Struct<T> {
|
||||
type Associated2 = ();
|
||||
const ASSOCIATED2: &'static str = "2";
|
||||
fn associated2() {}
|
||||
}
|
||||
|
||||
#[pinned_drop]
|
||||
impl<T: Send> PinnedDrop for Struct<T>
|
||||
where
|
||||
mac!(Self): Send,
|
||||
{
|
||||
#[allow(path_statements)]
|
||||
#[allow(clippy::no_effect)]
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
// inherent items
|
||||
mac!(Self::ASSOCIATED1;);
|
||||
mac!(<Self>::ASSOCIATED1;);
|
||||
mac!(Self::associated1(););
|
||||
mac!(<Self>::associated1(););
|
||||
|
||||
// trait items
|
||||
mac!(let _: <Self as Trait>::Associated2;);
|
||||
mac!(Self::ASSOCIATED2;);
|
||||
mac!(<Self>::ASSOCIATED2;);
|
||||
mac!(<Self as Trait>::ASSOCIATED2;);
|
||||
mac!(Self::associated2(););
|
||||
mac!(<Self>::associated2(););
|
||||
mac!(<Self as Trait>::associated2(););
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inside_macro() {
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, pinned_drop};
|
||||
|
||||
#[pin_project(PinnedDrop)]
|
||||
struct Struct(());
|
||||
|
||||
macro_rules! mac {
|
||||
($expr:expr) => {
|
||||
#[pinned_drop]
|
||||
impl PinnedDrop for Struct {
|
||||
#[allow(clippy::no_effect)]
|
||||
fn drop(self: Pin<&mut Self>) {
|
||||
$expr;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mac!(1);
|
||||
}
|
||||
|
184
third_party/rust/pin-project/tests/project.rs
vendored
184
third_party/rust/pin-project/tests/project.rs
vendored
@ -1,36 +1,33 @@
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
// This hack is needed until https://github.com/rust-lang/rust/pull/69201
|
||||
// makes it way into stable.
|
||||
// Ceurrently, `#[attr] if true {}` doesn't even *parse* on stable,
|
||||
// which means that it will error even behind a `#[rustversion::nightly]`
|
||||
// Ceurrently, `#[attr] if true {}` doesn't even *parse* on MSRV,
|
||||
// which means that it will error even behind a `#[rustversion::since(..)]`
|
||||
//
|
||||
// This trick makes sure that we don't even attempt to parse
|
||||
// the `#[project] if let _` test on stable.
|
||||
#[rustversion::nightly]
|
||||
// the `#[project] if let _` test on MSRV.
|
||||
#[rustversion::since(1.43)]
|
||||
include!("project_if_attr.rs.in");
|
||||
|
||||
use pin_project::{pin_project, project};
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, project, project_ref, project_replace};
|
||||
|
||||
#[project] // Nightly does not need a dummy attribute to the function.
|
||||
#[test]
|
||||
fn project_stmt_expr() {
|
||||
// struct
|
||||
|
||||
#[pin_project]
|
||||
struct Foo<T, U> {
|
||||
struct Struct<T, U> {
|
||||
#[pin]
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
|
||||
let mut foo = Foo { field1: 1, field2: 2 };
|
||||
let mut s = Struct { field1: 1, field2: 2 };
|
||||
|
||||
#[project]
|
||||
let Foo { field1, field2 } = Pin::new(&mut foo).project();
|
||||
let Struct { field1, field2 } = Pin::new(&mut s).project();
|
||||
|
||||
let x: Pin<&mut i32> = field1;
|
||||
assert_eq!(*x, 1);
|
||||
@ -38,15 +35,13 @@ fn project_stmt_expr() {
|
||||
let y: &mut i32 = field2;
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
// tuple struct
|
||||
|
||||
#[pin_project]
|
||||
struct Bar<T, U>(#[pin] T, U);
|
||||
struct TupleStruct<T, U>(#[pin] T, U);
|
||||
|
||||
let mut bar = Bar(1, 2);
|
||||
let mut s = TupleStruct(1, 2);
|
||||
|
||||
#[project]
|
||||
let Bar(x, y) = Pin::new(&mut bar).project();
|
||||
let TupleStruct(x, y) = Pin::new(&mut s).project();
|
||||
|
||||
let x: Pin<&mut i32> = x;
|
||||
assert_eq!(*x, 1);
|
||||
@ -54,10 +49,8 @@ fn project_stmt_expr() {
|
||||
let y: &mut i32 = y;
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
// enum
|
||||
|
||||
#[pin_project]
|
||||
enum Baz<A, B, C, D> {
|
||||
enum Enum<A, B, C, D> {
|
||||
Variant1(#[pin] A, B),
|
||||
Variant2 {
|
||||
#[pin]
|
||||
@ -67,31 +60,31 @@ fn project_stmt_expr() {
|
||||
None,
|
||||
}
|
||||
|
||||
let mut baz = Baz::Variant1(1, 2);
|
||||
let mut e = Enum::Variant1(1, 2);
|
||||
|
||||
let mut baz = Pin::new(&mut baz).project();
|
||||
let mut e = Pin::new(&mut e).project();
|
||||
|
||||
#[project]
|
||||
match &mut baz {
|
||||
Baz::Variant1(x, y) => {
|
||||
match &mut e {
|
||||
Enum::Variant1(x, y) => {
|
||||
let x: &mut Pin<&mut i32> = x;
|
||||
assert_eq!(**x, 1);
|
||||
|
||||
let y: &mut &mut i32 = y;
|
||||
assert_eq!(**y, 2);
|
||||
}
|
||||
Baz::Variant2 { field1, field2 } => {
|
||||
Enum::Variant2 { field1, field2 } => {
|
||||
let _x: &mut Pin<&mut i32> = field1;
|
||||
let _y: &mut &mut i32 = field2;
|
||||
}
|
||||
Baz::None => {}
|
||||
Enum::None => {}
|
||||
}
|
||||
|
||||
#[project]
|
||||
let val = match &mut baz {
|
||||
Baz::Variant1(_, _) => true,
|
||||
Baz::Variant2 { .. } => false,
|
||||
Baz::None => false,
|
||||
let val = match &mut e {
|
||||
Enum::Variant1(_, _) => true,
|
||||
Enum::Variant2 { .. } => false,
|
||||
Enum::None => false,
|
||||
};
|
||||
assert_eq!(val, true);
|
||||
}
|
||||
@ -154,6 +147,7 @@ fn project_impl() {
|
||||
}
|
||||
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
#[project]
|
||||
impl<T, U> HasOverlappingLifetimes2<T, U> {
|
||||
fn foo<'pin>(&'pin self) {}
|
||||
@ -167,10 +161,11 @@ struct A {
|
||||
}
|
||||
|
||||
mod project_use_1 {
|
||||
use crate::A;
|
||||
use core::pin::Pin;
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::project;
|
||||
|
||||
use crate::A;
|
||||
#[project]
|
||||
use crate::A;
|
||||
|
||||
@ -185,9 +180,10 @@ mod project_use_1 {
|
||||
}
|
||||
|
||||
mod project_use_2 {
|
||||
use pin_project::project;
|
||||
|
||||
#[project]
|
||||
use crate::A;
|
||||
use pin_project::project;
|
||||
|
||||
#[project]
|
||||
impl A {
|
||||
@ -195,23 +191,111 @@ mod project_use_2 {
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct StructWhereClause<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
field: T,
|
||||
#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
|
||||
#[test]
|
||||
#[project]
|
||||
fn non_stmt_expr_match() {
|
||||
#[pin_project]
|
||||
enum Enum<A> {
|
||||
Variant(#[pin] A),
|
||||
}
|
||||
|
||||
let mut x = Enum::Variant(1);
|
||||
let x = Pin::new(&mut x).project();
|
||||
|
||||
Some(
|
||||
#[project]
|
||||
match x {
|
||||
Enum::Variant(_x) => {}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStructWhereClause<T>(T)
|
||||
where
|
||||
T: Copy;
|
||||
// https://github.com/taiki-e/pin-project/issues/206
|
||||
#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
|
||||
#[test]
|
||||
#[project]
|
||||
fn issue_206() {
|
||||
#[pin_project]
|
||||
enum Enum<A> {
|
||||
Variant(#[pin] A),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum EnumWhereClause<T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
Variant(T),
|
||||
let mut x = Enum::Variant(1);
|
||||
let x = Pin::new(&mut x).project();
|
||||
|
||||
Some({
|
||||
#[project]
|
||||
match &x {
|
||||
Enum::Variant(_) => {}
|
||||
}
|
||||
});
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
loop {
|
||||
let _ = {
|
||||
#[project]
|
||||
match &x {
|
||||
Enum::Variant(_) => {}
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#[project]
|
||||
#[test]
|
||||
fn combine() {
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<A> {
|
||||
V1(#[pin] A),
|
||||
V2,
|
||||
}
|
||||
|
||||
let mut x = Enum::V1(1);
|
||||
#[project]
|
||||
match Pin::new(&mut x).project() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_ref]
|
||||
match Pin::new(&x).project_ref() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_replace]
|
||||
match Pin::new(&mut x).project_replace(Enum::V2) {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This should be denied, but allowed for compatibility at this time.
|
||||
#[project]
|
||||
#[project_ref]
|
||||
#[project_replace]
|
||||
#[test]
|
||||
fn combine_compat() {
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<A> {
|
||||
V1(#[pin] A),
|
||||
V2,
|
||||
}
|
||||
|
||||
let mut x = Enum::V1(1);
|
||||
#[project]
|
||||
match Pin::new(&mut x).project() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_ref]
|
||||
match Pin::new(&x).project_ref() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_replace]
|
||||
match Pin::new(&mut x).project_replace(Enum::V2) {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
// FIXME: Once https://github.com/rust-lang/rust/pull/69201 makes its
|
||||
// way into stable, move this back into `project.rs
|
||||
|
||||
#[test]
|
||||
#[project]
|
||||
fn project_if_let() {
|
||||
@ -9,21 +6,40 @@ fn project_if_let() {
|
||||
Variant1(#[pin] A),
|
||||
Variant2(u8),
|
||||
Variant3 {
|
||||
#[pin] field: B
|
||||
}
|
||||
#[pin]
|
||||
field: B,
|
||||
},
|
||||
}
|
||||
|
||||
let mut foo: Foo<bool, f32> = Foo::Variant1(true);
|
||||
let foo = Pin::new(&mut foo).project();
|
||||
let mut x: Foo<bool, f32> = Foo::Variant1(true);
|
||||
let x = Pin::new(&mut x).project();
|
||||
|
||||
#[project]
|
||||
if let Foo::Variant1(a) = foo {
|
||||
if let Foo::Variant1(a) = x {
|
||||
let a: Pin<&mut bool> = a;
|
||||
assert_eq!(*a, true);
|
||||
} else if let Foo::Variant2(_) = foo {
|
||||
} else if let Foo::Variant2(_) = x {
|
||||
unreachable!();
|
||||
} else if let Foo::Variant3 { .. } = foo {
|
||||
} else if let Foo::Variant3 { .. } = x {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
|
||||
#[test]
|
||||
#[project]
|
||||
fn non_stmt_expr_if_let() {
|
||||
#[pin_project]
|
||||
enum Enum<A> {
|
||||
Variant(#[pin] A),
|
||||
}
|
||||
|
||||
let mut x = Enum::Variant(1);
|
||||
let x = Pin::new(&mut x).project();
|
||||
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
Some(
|
||||
#[project]
|
||||
if let Enum::Variant(_x) = x {},
|
||||
);
|
||||
}
|
||||
|
@ -1,26 +1,25 @@
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::pin::Pin;
|
||||
|
||||
use pin_project::{pin_project, project_ref};
|
||||
use std::pin::Pin;
|
||||
|
||||
#[project_ref] // Nightly does not need a dummy attribute to the function.
|
||||
#[test]
|
||||
fn project_stmt_expr() {
|
||||
// struct
|
||||
|
||||
#[pin_project]
|
||||
struct Foo<T, U> {
|
||||
struct Struct<T, U> {
|
||||
#[pin]
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
|
||||
let foo = Foo { field1: 1, field2: 2 };
|
||||
let s = Struct { field1: 1, field2: 2 };
|
||||
|
||||
#[project_ref]
|
||||
let Foo { field1, field2 } = Pin::new(&foo).project_ref();
|
||||
let Struct { field1, field2 } = Pin::new(&s).project_ref();
|
||||
|
||||
let x: Pin<&i32> = field1;
|
||||
assert_eq!(*x, 1);
|
||||
@ -31,12 +30,12 @@ fn project_stmt_expr() {
|
||||
// tuple struct
|
||||
|
||||
#[pin_project]
|
||||
struct Bar<T, U>(#[pin] T, U);
|
||||
struct TupleStruct<T, U>(#[pin] T, U);
|
||||
|
||||
let bar = Bar(1, 2);
|
||||
let s = TupleStruct(1, 2);
|
||||
|
||||
#[project_ref]
|
||||
let Bar(x, y) = Pin::new(&bar).project_ref();
|
||||
let TupleStruct(x, y) = Pin::new(&s).project_ref();
|
||||
|
||||
let x: Pin<&i32> = x;
|
||||
assert_eq!(*x, 1);
|
||||
@ -44,10 +43,8 @@ fn project_stmt_expr() {
|
||||
let y: &i32 = y;
|
||||
assert_eq!(*y, 2);
|
||||
|
||||
// enum
|
||||
|
||||
#[pin_project]
|
||||
enum Baz<A, B, C, D> {
|
||||
enum Enum<A, B, C, D> {
|
||||
Variant1(#[pin] A, B),
|
||||
Variant2 {
|
||||
#[pin]
|
||||
@ -57,31 +54,31 @@ fn project_stmt_expr() {
|
||||
None,
|
||||
}
|
||||
|
||||
let baz = Baz::Variant1(1, 2);
|
||||
let e = Enum::Variant1(1, 2);
|
||||
|
||||
let baz = Pin::new(&baz).project_ref();
|
||||
let e = Pin::new(&e).project_ref();
|
||||
|
||||
#[project_ref]
|
||||
match &baz {
|
||||
Baz::Variant1(x, y) => {
|
||||
match &e {
|
||||
Enum::Variant1(x, y) => {
|
||||
let x: &Pin<&i32> = x;
|
||||
assert_eq!(**x, 1);
|
||||
|
||||
let y: &&i32 = y;
|
||||
assert_eq!(**y, 2);
|
||||
}
|
||||
Baz::Variant2 { field1, field2 } => {
|
||||
Enum::Variant2 { field1, field2 } => {
|
||||
let _x: &Pin<&i32> = field1;
|
||||
let _y: &&i32 = field2;
|
||||
}
|
||||
Baz::None => {}
|
||||
Enum::None => {}
|
||||
}
|
||||
|
||||
#[project_ref]
|
||||
let val = match &baz {
|
||||
Baz::Variant1(_, _) => true,
|
||||
Baz::Variant2 { .. } => false,
|
||||
Baz::None => false,
|
||||
let val = match &e {
|
||||
Enum::Variant1(_, _) => true,
|
||||
Enum::Variant2 { .. } => false,
|
||||
Enum::None => false,
|
||||
};
|
||||
assert_eq!(val, true);
|
||||
}
|
||||
@ -144,8 +141,36 @@ fn project_impl() {
|
||||
}
|
||||
|
||||
#[allow(single_use_lifetimes)]
|
||||
#[allow(clippy::needless_lifetimes)]
|
||||
#[project_ref]
|
||||
impl<T, U> HasOverlappingLifetimes2<T, U> {
|
||||
fn foo<'pin>(&'pin self) {}
|
||||
}
|
||||
}
|
||||
|
||||
#[project_ref]
|
||||
#[test]
|
||||
fn combine() {
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<A> {
|
||||
V1(#[pin] A),
|
||||
V2,
|
||||
}
|
||||
|
||||
let mut x = Enum::V1(1);
|
||||
#[project]
|
||||
match Pin::new(&mut x).project() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_ref]
|
||||
match Pin::new(&x).project_ref() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_replace]
|
||||
match Pin::new(&mut x).project_replace(Enum::V2) {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
100
third_party/rust/pin-project/tests/project_replace.rs
vendored
Normal file
100
third_party/rust/pin-project/tests/project_replace.rs
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::{marker::PhantomData, pin::Pin};
|
||||
|
||||
use pin_project::{pin_project, project_replace};
|
||||
|
||||
#[project_replace] // Nightly does not need a dummy attribute to the function.
|
||||
#[test]
|
||||
fn project_replace_stmt_expr() {
|
||||
#[pin_project(project_replace)]
|
||||
struct Struct<T, U> {
|
||||
#[pin]
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
|
||||
let mut s = Struct { field1: 1, field2: 2 };
|
||||
|
||||
#[project_replace]
|
||||
let Struct { field1, field2 } =
|
||||
Pin::new(&mut s).project_replace(Struct { field1: 42, field2: 43 });
|
||||
|
||||
let _x: PhantomData<i32> = field1;
|
||||
|
||||
let y: i32 = field2;
|
||||
assert_eq!(y, 2);
|
||||
|
||||
// tuple struct
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
struct TupleStruct<T, U>(#[pin] T, U);
|
||||
|
||||
let mut s = TupleStruct(1, 2);
|
||||
|
||||
#[project_replace]
|
||||
let TupleStruct(x, y) = Pin::new(&mut s).project_replace(TupleStruct(42, 43));
|
||||
|
||||
let _x: PhantomData<i32> = x;
|
||||
let y: i32 = y;
|
||||
assert_eq!(y, 2);
|
||||
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<A, B, C, D> {
|
||||
Variant1(#[pin] A, B),
|
||||
Variant2 {
|
||||
#[pin]
|
||||
field1: C,
|
||||
field2: D,
|
||||
},
|
||||
None,
|
||||
}
|
||||
|
||||
let mut e = Enum::Variant1(1, 2);
|
||||
|
||||
let e = Pin::new(&mut e).project_replace(Enum::None);
|
||||
|
||||
#[project_replace]
|
||||
match e {
|
||||
Enum::Variant1(x, y) => {
|
||||
let _x: PhantomData<i32> = x;
|
||||
let y: i32 = y;
|
||||
assert_eq!(y, 2);
|
||||
}
|
||||
Enum::Variant2 { field1, field2 } => {
|
||||
let _x: PhantomData<i32> = field1;
|
||||
let _y: i32 = field2;
|
||||
panic!()
|
||||
}
|
||||
Enum::None => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[project_replace]
|
||||
#[test]
|
||||
fn combine() {
|
||||
#[pin_project(project_replace)]
|
||||
enum Enum<A> {
|
||||
V1(#[pin] A),
|
||||
V2,
|
||||
}
|
||||
|
||||
let mut x = Enum::V1(1);
|
||||
#[project]
|
||||
match Pin::new(&mut x).project() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_ref]
|
||||
match Pin::new(&x).project_ref() {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
#[project_replace]
|
||||
match Pin::new(&mut x).project_replace(Enum::V2) {
|
||||
Enum::V1(_) => {}
|
||||
Enum::V2 => unreachable!(),
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
#![warn(unsafe_code)]
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
#![deny(safe_packed_borrows)]
|
||||
// unaligned_references did not exist in older compilers and safe_packed_borrows was removed in the latest compilers.
|
||||
// https://github.com/rust-lang/rust/pull/82525
|
||||
#![allow(unknown_lints, renamed_and_removed_lints)]
|
||||
#![forbid(unaligned_references, safe_packed_borrows)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -36,14 +37,15 @@ fn weird_repr_packed() {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::let_and_return)]
|
||||
let field_addr = {
|
||||
// We let this field drop by going out of scope,
|
||||
// rather than explicitly calling drop(foo).
|
||||
// Calling drop(foo) causes 'foo' to be moved
|
||||
// into the 'drop' function, resulting in a different
|
||||
// address.
|
||||
let foo = Foo { field: 27 };
|
||||
let field_addr = &foo.field as *const u8 as usize;
|
||||
let x = Foo { field: 27 };
|
||||
let field_addr = &x.field as *const u8 as usize;
|
||||
field_addr
|
||||
};
|
||||
assert_eq!(field_addr, FIELD_ADDR.with(|f| f.get()));
|
||||
|
13
third_party/rust/pin-project/tests/sized.rs
vendored
Normal file
13
third_party/rust/pin-project/tests/sized.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#![warn(rust_2018_idioms, single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
struct Foo<'a, I: ?Sized, Item>
|
||||
where
|
||||
I: Iterator,
|
||||
{
|
||||
iter: &'a mut I,
|
||||
item: Option<Item>,
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo<u8>>` in the current scope
|
||||
error[E0599]: no method named `project` found for struct `Pin<&mut Foo<u8>>` in the current scope
|
||||
--> $DIR/cfg_attr-resolve.rs:10:31
|
||||
|
|
||||
10 | let _x = Pin::new(&mut x).project(); //~ ERROR E0599
|
||||
| ^^^^^^^ method not found in `std::pin::Pin<&mut Foo<u8>>`
|
||||
| ^^^^^^^ method not found in `Pin<&mut Foo<u8>>`
|
||||
|
@ -2,11 +2,11 @@ error[E0308]: mismatched types
|
||||
--> $DIR/cfg_attr-type-mismatch.rs:19:27
|
||||
|
|
||||
19 | let _: Pin<&mut u8> = x.inner; //~ ERROR E0308
|
||||
| ------------ ^^^^^^^ expected struct `std::pin::Pin`, found `&mut u8`
|
||||
| ------------ ^^^^^^^ expected struct `Pin`, found `&mut u8`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `std::pin::Pin<&mut u8>`
|
||||
= note: expected struct `Pin<&mut u8>`
|
||||
found mutable reference `&mut u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
@ -15,9 +15,9 @@ error[E0308]: mismatched types
|
||||
23 | let _: &mut u8 = x.inner; //~ ERROR E0308
|
||||
| ------- ^^^^^^^
|
||||
| | |
|
||||
| | expected `&mut u8`, found struct `std::pin::Pin`
|
||||
| | expected `&mut u8`, found struct `Pin`
|
||||
| | help: consider mutably borrowing here: `&mut x.inner`
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected mutable reference `&mut u8`
|
||||
found struct `std::pin::Pin<&mut u8>`
|
||||
found struct `Pin<&mut u8>`
|
||||
|
@ -1,22 +1,22 @@
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/cfg_attr-unpin.rs:18:5
|
||||
|
|
||||
15 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
18 | is_unpin::<Foo<PhantomPinned>>(); // ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Foo<std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Foo<PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Foo<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `Foo<PhantomPinned>`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/cfg_attr-unpin.rs:20:5
|
||||
|
|
||||
15 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
20 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__Bar<'_, std::marker::PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `__Bar<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Bar<PhantomPinned>`
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::hidden_repr;
|
||||
use auxiliary_macro::hidden_repr;
|
||||
use pin_project::pin_project;
|
||||
|
||||
//~ ERROR may not be used on #[repr(packed)] types
|
||||
|
@ -1 +1,7 @@
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/packed_sneaky-span-issue-1.rs:8:1
|
||||
|
|
||||
8 | #[hidden_repr(packed)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::hidden_repr;
|
||||
use auxiliary_macro::hidden_repr;
|
||||
use pin_project::pin_project;
|
||||
|
||||
//~ ERROR may not be used on #[repr(packed)] types
|
||||
|
@ -1 +1,7 @@
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/packed_sneaky-span-issue-2.rs:8:1
|
||||
|
|
||||
8 | #[hidden_repr(packed)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::hidden_repr_cfg_not_any;
|
||||
use auxiliary_macro::hidden_repr_cfg_not_any;
|
||||
use pin_project::pin_project;
|
||||
|
||||
// `#[hidden_repr_cfg_not_any(packed)]` generates `#[cfg_attr(not(any()), repr(packed))]`.
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/proper_unpin.rs:27:5
|
||||
|
|
||||
22 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
27 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__Bar<'_, std::marker::PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `__Bar<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Bar<PhantomPinned>`
|
||||
|
@ -1 +1,9 @@
|
||||
error: #[pin_project] attribute may not be used on structs with zero fields
|
||||
--> $DIR/unsupported.rs:7:1
|
||||
|
|
||||
7 | / struct Struct {
|
||||
8 | | #[cfg(any())]
|
||||
9 | | #[pin]
|
||||
10 | | f: u8,
|
||||
11 | | }
|
||||
| |_^
|
||||
|
40
third_party/rust/pin-project/tests/ui/not_unpin/assert-not-unpin.rs
vendored
Normal file
40
third_party/rust/pin-project/tests/ui/not_unpin/assert-not-unpin.rs
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
use pin_project::pin_project;
|
||||
use std::marker::PhantomPinned;
|
||||
|
||||
struct Inner<T> {
|
||||
val: T,
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct Foo<T, U> {
|
||||
#[pin]
|
||||
inner: Inner<T>,
|
||||
other: U,
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct TrivialBounds {
|
||||
#[pin]
|
||||
field1: PhantomPinned,
|
||||
}
|
||||
|
||||
#[pin_project(!Unpin)]
|
||||
struct Bar<'a, T, U> {
|
||||
#[pin]
|
||||
inner: &'a mut Inner<T>,
|
||||
other: U,
|
||||
}
|
||||
|
||||
fn is_unpin<T: Unpin>() {}
|
||||
|
||||
fn main() {
|
||||
is_unpin::<Foo<(), ()>>(); //~ ERROR E0277
|
||||
is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
|
||||
is_unpin::<Foo<(), PhantomPinned>>(); //~ ERROR E0277
|
||||
is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
|
||||
|
||||
is_unpin::<TrivialBounds>(); //~ ERROR E0277
|
||||
|
||||
is_unpin::<Bar<'_, (), ()>>(); //~ ERROR E0277
|
||||
is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
|
||||
}
|
83
third_party/rust/pin-project/tests/ui/not_unpin/assert-not-unpin.stderr
vendored
Normal file
83
third_party/rust/pin-project/tests/ui/not_unpin/assert-not-unpin.stderr
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:31:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
31 | is_unpin::<Foo<(), ()>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<(), ()>`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:32:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
32 | is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned, ()>`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:33:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
33 | is_unpin::<Foo<(), PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<(), PhantomPinned>`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:34:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
34 | is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned, PhantomPinned>`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:36:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
36 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `TrivialBounds`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:38:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
38 | is_unpin::<Bar<'_, (), ()>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Bar<'_, (), ()>`
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/assert-not-unpin.rs:39:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
39 | is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Wrapper<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Wrapper<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Bar<'_, PhantomPinned, PhantomPinned>`
|
30
third_party/rust/pin-project/tests/ui/not_unpin/conflict-unpin.rs
vendored
Normal file
30
third_party/rust/pin-project/tests/ui/not_unpin/conflict-unpin.rs
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Foo<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Bar<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
impl<T, U> Unpin for Bar<T, U> {}
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Baz<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
|
||||
|
||||
fn main() {}
|
26
third_party/rust/pin-project/tests/ui/not_unpin/conflict-unpin.stderr
vendored
Normal file
26
third_party/rust/pin-project/tests/ui/not_unpin/conflict-unpin.stderr
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
|
||||
--> $DIR/conflict-unpin.rs:3:15
|
||||
|
|
||||
3 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^ conflicting implementation for `Foo<_, _>`
|
||||
...
|
||||
10 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
|
||||
| --------------------------------------------- first implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
|
||||
--> $DIR/conflict-unpin.rs:12:15
|
||||
|
|
||||
12 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^ conflicting implementation for `Bar<_, _>`
|
||||
...
|
||||
19 | impl<T, U> Unpin for Bar<T, U> {}
|
||||
| ------------------------------ first implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
|
||||
--> $DIR/conflict-unpin.rs:21:15
|
||||
|
|
||||
21 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^ conflicting implementation for `Baz<_, _>`
|
||||
...
|
||||
28 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
|
||||
| -------------------------------------------- first implementation here
|
30
third_party/rust/pin-project/tests/ui/not_unpin/impl-unsafe-unpin.rs
vendored
Normal file
30
third_party/rust/pin-project/tests/ui/not_unpin/impl-unsafe-unpin.rs
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
use pin_project::{pin_project, UnsafeUnpin};
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Foo<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Bar<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
|
||||
|
||||
#[pin_project(!Unpin)] //~ ERROR E0119
|
||||
struct Baz<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
|
||||
|
||||
fn main() {}
|
32
third_party/rust/pin-project/tests/ui/not_unpin/impl-unsafe-unpin.stderr
vendored
Normal file
32
third_party/rust/pin-project/tests/ui/not_unpin/impl-unsafe-unpin.stderr
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Foo<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:3:1
|
||||
|
|
||||
3 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
|
||||
...
|
||||
10 | unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
|
||||
| ---------------------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Bar<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:12:1
|
||||
|
|
||||
12 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
|
||||
...
|
||||
19 | unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
|
||||
| ------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Baz<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:21:1
|
||||
|
|
||||
21 | #[pin_project(!Unpin)] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
|
||||
...
|
||||
28 | unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
|
||||
| --------------------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
@ -1,15 +1,15 @@
|
||||
use auxiliary_macros::add_attr;
|
||||
use auxiliary_macro::add_pin_attr;
|
||||
use pin_project::pin_project;
|
||||
use std::marker::PhantomPinned;
|
||||
|
||||
#[pin_project]
|
||||
#[add_attr(struct)] //~ ERROR duplicate #[pin] attribute
|
||||
#[add_pin_attr(struct)] //~ ERROR duplicate #[pin] attribute
|
||||
struct Foo {
|
||||
#[pin]
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
#[add_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
|
||||
#[add_pin_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
|
||||
#[pin_project]
|
||||
struct Bar {
|
||||
#[pin]
|
||||
|
@ -1,15 +1,15 @@
|
||||
error: duplicate #[pin] attribute
|
||||
--> $DIR/add-attr-to-struct.rs:6:1
|
||||
|
|
||||
6 | #[add_attr(struct)] //~ ERROR duplicate #[pin] attribute
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
6 | #[add_pin_attr(struct)] //~ ERROR duplicate #[pin] attribute
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/add-attr-to-struct.rs:12:1
|
||||
|
|
||||
12 | #[add_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
12 | #[add_pin_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::add_pinned_field;
|
||||
use auxiliary_macro::add_pinned_field;
|
||||
use pin_project::pin_project;
|
||||
|
||||
fn is_unpin<T: Unpin>() {}
|
||||
|
@ -1,23 +1,23 @@
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/add-pinned-field.rs:21:5
|
||||
|
|
||||
4 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
21 | is_unpin::<Foo>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ within `__Foo<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^ within `__Foo<'_>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__Foo<'_>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/add-pinned-field.rs:22:5
|
||||
|
|
||||
4 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
22 | is_unpin::<Bar>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ within `__Bar<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^ within `__Bar<'_>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__Bar<'_>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Bar`
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0119]: conflicting implementations of trait `FooMustNotImplDrop` for type `Foo<_, _>`:
|
||||
error[E0119]: conflicting implementations of trait `_::FooMustNotImplDrop` for type `Foo<_, _>`:
|
||||
--> $DIR/conflict-drop.rs:4:1
|
||||
|
|
||||
4 | #[pin_project] //~ ERROR E0119
|
||||
@ -10,12 +10,10 @@ error[E0119]: conflicting implementations of trait `FooMustNotImplDrop` for type
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `Bar<_, _>`:
|
||||
--> $DIR/conflict-drop.rs:15:1
|
||||
--> $DIR/conflict-drop.rs:15:15
|
||||
|
|
||||
15 | #[pin_project(PinnedDrop)] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
|
||||
| ^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
|
||||
...
|
||||
27 | impl<T, U> Drop for Bar<T, U> {
|
||||
| ----------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
@ -1,27 +0,0 @@
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
struct UnsafeUnpin<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
struct PinnedDrop<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
struct Duplicate3<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
#[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
struct Duplicate4<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,23 +0,0 @@
|
||||
error: duplicate `UnsafeUnpin` argument
|
||||
--> $DIR/duplicate-argument.rs:3:28
|
||||
|
|
||||
3 | #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `PinnedDrop` argument
|
||||
--> $DIR/duplicate-argument.rs:9:27
|
||||
|
|
||||
9 | #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: duplicate `UnsafeUnpin` argument
|
||||
--> $DIR/duplicate-argument.rs:15:40
|
||||
|
|
||||
15 | #[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `PinnedDrop` argument
|
||||
--> $DIR/duplicate-argument.rs:21:40
|
||||
|
|
||||
21 | #[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
| ^^^^^^^^^^
|
30
third_party/rust/pin-project/tests/ui/pin_project/impl-unsafe-unpin.rs
vendored
Normal file
30
third_party/rust/pin-project/tests/ui/pin_project/impl-unsafe-unpin.rs
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
use pin_project::{pin_project, UnsafeUnpin};
|
||||
|
||||
#[pin_project] //~ ERROR E0119
|
||||
struct Foo<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
|
||||
|
||||
#[pin_project] //~ ERROR E0119
|
||||
struct Bar<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
|
||||
|
||||
#[pin_project] //~ ERROR E0119
|
||||
struct Baz<T, U> {
|
||||
#[pin]
|
||||
future: T,
|
||||
field: U,
|
||||
}
|
||||
|
||||
unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
|
||||
|
||||
fn main() {}
|
32
third_party/rust/pin-project/tests/ui/pin_project/impl-unsafe-unpin.stderr
vendored
Normal file
32
third_party/rust/pin-project/tests/ui/pin_project/impl-unsafe-unpin.stderr
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Foo<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:3:1
|
||||
|
|
||||
3 | #[pin_project] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
|
||||
...
|
||||
10 | unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
|
||||
| ---------------------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Bar<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:12:1
|
||||
|
|
||||
12 | #[pin_project] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
|
||||
...
|
||||
19 | unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
|
||||
| ------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `pin_project::UnsafeUnpin` for type `Baz<_, _>`:
|
||||
--> $DIR/impl-unsafe-unpin.rs:21:1
|
||||
|
|
||||
21 | #[pin_project] //~ ERROR E0119
|
||||
| ^^^^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
|
||||
...
|
||||
28 | unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
|
||||
| --------------------------------------------------------- first implementation here
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
@ -1,56 +1,275 @@
|
||||
use pin_project::pin_project;
|
||||
mod pin_argument {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
struct A<T> {
|
||||
#[pin()] //~ ERROR unexpected token
|
||||
pinned: T,
|
||||
#[pin_project]
|
||||
struct Struct {
|
||||
#[pin()] //~ ERROR unexpected token
|
||||
field: (),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct(#[pin(foo)] ()); //~ ERROR unexpected token
|
||||
|
||||
#[pin_project]
|
||||
enum EnumTuple {
|
||||
V(#[pin(foo)] ()), //~ ERROR unexpected token
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum EnumStruct {
|
||||
V {
|
||||
#[pin(foo)] //~ ERROR unexpected token
|
||||
field: (),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
|
||||
mod pin_attribute {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
enum C<T> {
|
||||
A(#[pin(foo)] T), //~ ERROR unexpected token
|
||||
#[pin_project]
|
||||
struct DuplicateStruct {
|
||||
#[pin]
|
||||
#[pin] //~ ERROR duplicate #[pin] attribute
|
||||
field: (),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct DuplicateTupleStruct(
|
||||
#[pin]
|
||||
#[pin]
|
||||
(),
|
||||
//~^^ ERROR duplicate #[pin] attribute
|
||||
);
|
||||
|
||||
#[pin_project]
|
||||
enum DuplicateEnumTuple {
|
||||
V(
|
||||
#[pin]
|
||||
#[pin]
|
||||
(),
|
||||
//~^^ ERROR duplicate #[pin] attribute
|
||||
),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum DuplicateEnumStruct {
|
||||
V {
|
||||
#[pin]
|
||||
#[pin] //~ ERROR duplicate #[pin] attribute
|
||||
field: (),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum D<T> {
|
||||
A {
|
||||
#[pin(foo)] //~ ERROR unexpected token
|
||||
pinned: T,
|
||||
},
|
||||
}
|
||||
mod pin_item {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
|
||||
struct E<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
#[pin_project(Foo)] //~ ERROR unexpected argument
|
||||
struct F<T> {
|
||||
#[pin]
|
||||
pinned: T,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum G<T> {
|
||||
#[pin_project]
|
||||
#[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
A(T),
|
||||
struct Struct {
|
||||
#[pin]
|
||||
field: (),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum Variant {
|
||||
#[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
V(()),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
enum Enum {
|
||||
V(()),
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
enum H<T> {
|
||||
A(T),
|
||||
mod pin_project_argument {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
|
||||
struct Unexpected1(#[pin] ());
|
||||
|
||||
#[pin_project(Foo)] //~ ERROR unexpected argument
|
||||
struct Unexpected2(#[pin] ());
|
||||
|
||||
#[pin_project(,UnsafeUnpin)] //~ ERROR expected identifier
|
||||
struct Unexpected3(#[pin] ());
|
||||
|
||||
#[pin_project()] // Ok
|
||||
struct Unexpected4(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
|
||||
struct Unexpected5(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
struct DuplicatePinnedDrop(#[pin] ());
|
||||
|
||||
#[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
|
||||
struct DuplicateReplace(#[pin] ());
|
||||
|
||||
#[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
struct DuplicateUnsafeUnpin(#[pin] ());
|
||||
|
||||
#[pin_project(!Unpin, !Unpin)] //~ ERROR duplicate `!Unpin` argument
|
||||
struct DuplicateNotUnpin(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
struct Duplicate3(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, UnsafeUnpin)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
struct Duplicate4(#[pin] ());
|
||||
|
||||
#[pin_project(project = A, project = B)] //~ ERROR duplicate `project` argument
|
||||
struct DuplicateProject(#[pin] ());
|
||||
|
||||
#[pin_project(project = A, project_ref = A, project = B)] //~ ERROR duplicate `project` argument
|
||||
struct DuplicateProject2(#[pin] ());
|
||||
|
||||
#[pin_project(project_ref = A, project_ref = B)] //~ ERROR duplicate `project_ref` argument
|
||||
struct DuplicateProjectRef(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = A, project_replace = B)] //~ ERROR duplicate `project_replace` argument
|
||||
struct DuplicateProjectReplace1(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace, project_replace = B)] //~ ERROR duplicate `project_replace` argument
|
||||
struct DuplicateProjectReplace2(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = A, project_replace)] //~ ERROR duplicate `project_replace` argument
|
||||
struct DuplicateProjectReplace3(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = A)] // Ok
|
||||
struct ProjectReplaceWithoutReplace(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
struct PinnedDropWithReplace1(#[pin] ());
|
||||
|
||||
#[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
struct PinnedDropWithReplace2(#[pin] ());
|
||||
|
||||
#[pin_project(PinnedDrop, project_replace)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
struct PinnedDropWithProjectReplace1(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
struct PinnedDropWithProjectReplace2(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace, Replace)] // Ok
|
||||
struct ProjectReplaceWithReplace1(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = B, Replace)] // Ok
|
||||
struct ProjectReplaceWithReplace2(#[pin] ());
|
||||
|
||||
#[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
struct UnsafeUnpinWithNotUnpin1(#[pin] ());
|
||||
|
||||
#[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
struct UnsafeUnpinWithNotUnpin2(#[pin] ());
|
||||
|
||||
#[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
|
||||
struct NotUnpin1(#[pin] ());
|
||||
|
||||
#[pin_project(Unpin)] //~ ERROR unexpected argument
|
||||
struct NotUnpin2(#[pin] ());
|
||||
|
||||
#[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
|
||||
struct Project1(#[pin] ());
|
||||
|
||||
#[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
|
||||
struct Project2(#[pin] ());
|
||||
|
||||
#[pin_project(project = !)] //~ ERROR expected identifier
|
||||
struct Project3(#[pin] ());
|
||||
|
||||
#[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
|
||||
struct ProjectRef1(#[pin] ());
|
||||
|
||||
#[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
|
||||
struct ProjectRef2(#[pin] ());
|
||||
|
||||
#[pin_project(project_ref = !)] //~ ERROR expected identifier
|
||||
struct ProjectRef3(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace)] // Ok
|
||||
struct ProjectReplace1(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
|
||||
struct ProjectReplace2(#[pin] ());
|
||||
|
||||
#[pin_project(project_replace = !)] //~ ERROR expected identifier
|
||||
struct ProjectReplace3(#[pin] ());
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
struct I<T> {
|
||||
#[pin]
|
||||
#[pin] //~ ERROR duplicate #[pin] attribute
|
||||
pinned: T,
|
||||
mod pin_project_conflict_naming {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
|
||||
struct ProjAndProjRef(#[pin] ());
|
||||
|
||||
#[pin_project(project = A, project_replace = A)] //~ ERROR name `A` is already specified by `project` argument
|
||||
struct ProjAndProjOwn(#[pin] ());
|
||||
|
||||
#[pin_project(project_ref = A, project_replace = A)] //~ ERROR name `A` is already specified by `project_ref` argument
|
||||
struct ProjRefAndProjOwn(#[pin] ());
|
||||
}
|
||||
|
||||
mod pin_project_attribute {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
#[pin_project] //~ ERROR duplicate #[pin_project] attribute
|
||||
struct Duplicate(#[pin] ());
|
||||
}
|
||||
|
||||
mod pin_project_item {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
struct Struct {} //~ ERROR may not be used on structs with zero fields
|
||||
|
||||
#[pin_project]
|
||||
struct TupleStruct(); //~ ERROR may not be used on structs with zero fields
|
||||
|
||||
#[pin_project]
|
||||
struct UnitStruct; //~ ERROR may not be used on structs with zero fields
|
||||
|
||||
#[pin_project]
|
||||
enum EnumEmpty {} //~ ERROR may not be used on enums without variants
|
||||
|
||||
#[pin_project]
|
||||
enum EnumDiscriminant {
|
||||
V = 2, //~ ERROR may not be used on enums with discriminants
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
enum EnumZeroFields {
|
||||
Unit, //~ ERROR may not be used on enums with zero fields
|
||||
Tuple(),
|
||||
Struct {},
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
union Union {
|
||||
//~^ ERROR may only be used on structs or enums
|
||||
f: (),
|
||||
}
|
||||
}
|
||||
|
||||
// #[repr(packed)] is always detected first, even on unsupported structs.
|
||||
mod pin_project_item_packed {
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed)]
|
||||
struct Struct {} //~ ERROR may not be used on #[repr(packed)] types
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed)]
|
||||
struct TupleStruct(); //~ ERROR may not be used on #[repr(packed)] types
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed)]
|
||||
struct UnitStruct; //~ ERROR may not be used on #[repr(packed)] types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,53 +1,346 @@
|
||||
error: unexpected token: ()
|
||||
--> $DIR/invalid.rs:5:10
|
||||
--> $DIR/invalid.rs:6:14
|
||||
|
|
||||
5 | #[pin()] //~ ERROR unexpected token
|
||||
| ^^
|
||||
6 | #[pin()] //~ ERROR unexpected token
|
||||
| ^^
|
||||
|
||||
error: unexpected token: (foo)
|
||||
--> $DIR/invalid.rs:10:18
|
||||
--> $DIR/invalid.rs:11:29
|
||||
|
|
||||
10 | struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
|
||||
11 | struct TupleStruct(#[pin(foo)] ()); //~ ERROR unexpected token
|
||||
| ^^^^^
|
||||
|
||||
error: unexpected token: (foo)
|
||||
--> $DIR/invalid.rs:15:16
|
||||
|
|
||||
15 | V(#[pin(foo)] ()), //~ ERROR unexpected token
|
||||
| ^^^^^
|
||||
|
||||
error: unexpected token: (foo)
|
||||
--> $DIR/invalid.rs:21:18
|
||||
|
|
||||
21 | #[pin(foo)] //~ ERROR unexpected token
|
||||
| ^^^^^
|
||||
|
||||
error: unexpected token: (foo)
|
||||
--> $DIR/invalid.rs:14:12
|
||||
error: duplicate #[pin] attribute
|
||||
--> $DIR/invalid.rs:33:9
|
||||
|
|
||||
14 | A(#[pin(foo)] T), //~ ERROR unexpected token
|
||||
| ^^^^^
|
||||
|
||||
error: unexpected token: (foo)
|
||||
--> $DIR/invalid.rs:20:14
|
||||
|
|
||||
20 | #[pin(foo)] //~ ERROR unexpected token
|
||||
| ^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:25:27
|
||||
|
|
||||
25 | #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: unexpected argument: Foo
|
||||
--> $DIR/invalid.rs:31:15
|
||||
|
|
||||
31 | #[pin_project(Foo)] //~ ERROR unexpected argument
|
||||
| ^^^
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/invalid.rs:39:5
|
||||
|
|
||||
39 | #[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/invalid.rs:44:1
|
||||
|
|
||||
44 | #[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
| ^^^^^^
|
||||
33 | #[pin] //~ ERROR duplicate #[pin] attribute
|
||||
| ^^^^^^
|
||||
|
||||
error: duplicate #[pin] attribute
|
||||
--> $DIR/invalid.rs:52:5
|
||||
--> $DIR/invalid.rs:40:9
|
||||
|
|
||||
52 | #[pin] //~ ERROR duplicate #[pin] attribute
|
||||
40 | #[pin]
|
||||
| ^^^^^^
|
||||
|
||||
error: duplicate #[pin] attribute
|
||||
--> $DIR/invalid.rs:49:13
|
||||
|
|
||||
49 | #[pin]
|
||||
| ^^^^^^
|
||||
|
||||
error: duplicate #[pin] attribute
|
||||
--> $DIR/invalid.rs:59:13
|
||||
|
|
||||
59 | #[pin] //~ ERROR duplicate #[pin] attribute
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/invalid.rs:69:5
|
||||
|
|
||||
69 | #[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/invalid.rs:77:9
|
||||
|
|
||||
77 | #[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin] attribute may only be used on fields of structs or variants
|
||||
--> $DIR/invalid.rs:82:5
|
||||
|
|
||||
82 | #[pin] //~ ERROR may only be used on fields of structs or variants
|
||||
| ^^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:91:31
|
||||
|
|
||||
91 | #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: unexpected argument: Foo
|
||||
--> $DIR/invalid.rs:94:19
|
||||
|
|
||||
94 | #[pin_project(Foo)] //~ ERROR unexpected argument
|
||||
| ^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:97:19
|
||||
|
|
||||
97 | #[pin_project(,UnsafeUnpin)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: expected `,`
|
||||
--> $DIR/invalid.rs:103:30
|
||||
|
|
||||
103 | #[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: duplicate `PinnedDrop` argument
|
||||
--> $DIR/invalid.rs:106:31
|
||||
|
|
||||
106 | #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: duplicate `Replace` argument
|
||||
--> $DIR/invalid.rs:109:28
|
||||
|
|
||||
109 | #[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
|
||||
| ^^^^^^^
|
||||
|
||||
error: duplicate `UnsafeUnpin` argument
|
||||
--> $DIR/invalid.rs:112:32
|
||||
|
|
||||
112 | #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `!Unpin` argument
|
||||
--> $DIR/invalid.rs:115:27
|
||||
|
|
||||
115 | #[pin_project(!Unpin, !Unpin)] //~ ERROR duplicate `!Unpin` argument
|
||||
| ^^^^^^
|
||||
|
||||
error: duplicate `UnsafeUnpin` argument
|
||||
--> $DIR/invalid.rs:118:44
|
||||
|
|
||||
118 | #[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `PinnedDrop` argument
|
||||
--> $DIR/invalid.rs:121:44
|
||||
|
|
||||
121 | #[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, UnsafeUnpin)] //~ ERROR duplicate `PinnedDrop` argument
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: duplicate `project` argument
|
||||
--> $DIR/invalid.rs:124:32
|
||||
|
|
||||
124 | #[pin_project(project = A, project = B)] //~ ERROR duplicate `project` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `project` argument
|
||||
--> $DIR/invalid.rs:127:49
|
||||
|
|
||||
127 | #[pin_project(project = A, project_ref = A, project = B)] //~ ERROR duplicate `project` argument
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: duplicate `project_ref` argument
|
||||
--> $DIR/invalid.rs:130:36
|
||||
|
|
||||
130 | #[pin_project(project_ref = A, project_ref = B)] //~ ERROR duplicate `project_ref` argument
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: duplicate `project_replace` argument
|
||||
--> $DIR/invalid.rs:133:40
|
||||
|
|
||||
133 | #[pin_project(project_replace = A, project_replace = B)] //~ ERROR duplicate `project_replace` argument
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: duplicate `project_replace` argument
|
||||
--> $DIR/invalid.rs:136:36
|
||||
|
|
||||
136 | #[pin_project(project_replace, project_replace = B)] //~ ERROR duplicate `project_replace` argument
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: duplicate `project_replace` argument
|
||||
--> $DIR/invalid.rs:139:40
|
||||
|
|
||||
139 | #[pin_project(project_replace = A, project_replace)] //~ ERROR duplicate `project_replace` argument
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
--> $DIR/invalid.rs:145:19
|
||||
|
|
||||
145 | #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
--> $DIR/invalid.rs:148:41
|
||||
|
|
||||
148 | #[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
--> $DIR/invalid.rs:151:19
|
||||
|
|
||||
151 | #[pin_project(PinnedDrop, project_replace)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
--> $DIR/invalid.rs:154:49
|
||||
|
|
||||
154 | #[pin_project(project_replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
--> $DIR/invalid.rs:163:19
|
||||
|
|
||||
163 | #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
--> $DIR/invalid.rs:166:39
|
||||
|
|
||||
166 | #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: expected `!Unpin`, found `!`
|
||||
--> $DIR/invalid.rs:169:19
|
||||
|
|
||||
169 | #[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
|
||||
| ^
|
||||
|
||||
error: unexpected argument: Unpin
|
||||
--> $DIR/invalid.rs:172:19
|
||||
|
|
||||
172 | #[pin_project(Unpin)] //~ ERROR unexpected argument
|
||||
| ^^^^^
|
||||
|
||||
error: expected `project = <identifier>`, found `project`
|
||||
--> $DIR/invalid.rs:175:19
|
||||
|
|
||||
175 | #[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `project = <identifier>`, found `project =`
|
||||
--> $DIR/invalid.rs:178:19
|
||||
|
|
||||
178 | #[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:181:29
|
||||
|
|
||||
181 | #[pin_project(project = !)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: expected `project_ref = <identifier>`, found `project_ref`
|
||||
--> $DIR/invalid.rs:184:19
|
||||
|
|
||||
184 | #[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: expected `project_ref = <identifier>`, found `project_ref =`
|
||||
--> $DIR/invalid.rs:187:19
|
||||
|
|
||||
187 | #[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:190:33
|
||||
|
|
||||
190 | #[pin_project(project_ref = !)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: expected `project_replace = <identifier>`, found `project_replace =`
|
||||
--> $DIR/invalid.rs:196:19
|
||||
|
|
||||
196 | #[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/invalid.rs:199:37
|
||||
|
|
||||
199 | #[pin_project(project_replace = !)] //~ ERROR expected identifier
|
||||
| ^
|
||||
|
||||
error: name `A` is already specified by `project` argument
|
||||
--> $DIR/invalid.rs:206:46
|
||||
|
|
||||
206 | #[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
|
||||
| ^
|
||||
|
||||
error: name `A` is already specified by `project` argument
|
||||
--> $DIR/invalid.rs:209:50
|
||||
|
|
||||
209 | #[pin_project(project = A, project_replace = A)] //~ ERROR name `A` is already specified by `project` argument
|
||||
| ^
|
||||
|
||||
error: name `A` is already specified by `project_ref` argument
|
||||
--> $DIR/invalid.rs:212:54
|
||||
|
|
||||
212 | #[pin_project(project_ref = A, project_replace = A)] //~ ERROR name `A` is already specified by `project_ref` argument
|
||||
| ^
|
||||
|
||||
error: duplicate #[pin_project] attribute
|
||||
--> $DIR/invalid.rs:220:5
|
||||
|
|
||||
220 | #[pin_project] //~ ERROR duplicate #[pin_project] attribute
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on structs with zero fields
|
||||
--> $DIR/invalid.rs:228:19
|
||||
|
|
||||
228 | struct Struct {} //~ ERROR may not be used on structs with zero fields
|
||||
| ^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on structs with zero fields
|
||||
--> $DIR/invalid.rs:231:23
|
||||
|
|
||||
231 | struct TupleStruct(); //~ ERROR may not be used on structs with zero fields
|
||||
| ^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on structs with zero fields
|
||||
--> $DIR/invalid.rs:234:12
|
||||
|
|
||||
234 | struct UnitStruct; //~ ERROR may not be used on structs with zero fields
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on enums without variants
|
||||
--> $DIR/invalid.rs:237:20
|
||||
|
|
||||
237 | enum EnumEmpty {} //~ ERROR may not be used on enums without variants
|
||||
| ^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on enums with discriminants
|
||||
--> $DIR/invalid.rs:241:13
|
||||
|
|
||||
241 | V = 2, //~ ERROR may not be used on enums with discriminants
|
||||
| ^
|
||||
|
||||
error: #[pin_project] attribute may not be used on enums with zero fields
|
||||
--> $DIR/invalid.rs:246:9
|
||||
|
|
||||
246 | / Unit, //~ ERROR may not be used on enums with zero fields
|
||||
247 | | Tuple(),
|
||||
248 | | Struct {},
|
||||
| |__________________^
|
||||
|
||||
error: #[pin_project] attribute may only be used on structs or enums
|
||||
--> $DIR/invalid.rs:252:5
|
||||
|
|
||||
252 | / union Union {
|
||||
253 | | //~^ ERROR may only be used on structs or enums
|
||||
254 | | f: (),
|
||||
255 | | }
|
||||
| |_____^
|
||||
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/invalid.rs:263:12
|
||||
|
|
||||
263 | #[repr(packed)]
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/invalid.rs:267:12
|
||||
|
|
||||
267 | #[repr(packed)]
|
||||
| ^^^^^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/invalid.rs:271:12
|
||||
|
|
||||
271 | #[repr(packed)]
|
||||
| ^^^^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/overlapping_unpin_struct.rs:17:5
|
||||
|
|
||||
14 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
17 | is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Foo<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `_::__Foo<'_, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned>`
|
||||
|
20
third_party/rust/pin-project/tests/ui/pin_project/packed-enum.rs
vendored
Normal file
20
third_party/rust/pin-project/tests/ui/pin_project/packed-enum.rs
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[repr(packed)] //~ ERROR E0517
|
||||
enum E1 {
|
||||
V(()),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed)] //~ ERROR E0517
|
||||
enum E2 {
|
||||
V(()),
|
||||
}
|
||||
|
||||
#[repr(packed)] //~ ERROR E0517
|
||||
#[pin_project]
|
||||
enum E3 {
|
||||
V(()),
|
||||
}
|
||||
|
||||
fn main() {}
|
30
third_party/rust/pin-project/tests/ui/pin_project/packed-enum.stderr
vendored
Normal file
30
third_party/rust/pin-project/tests/ui/pin_project/packed-enum.stderr
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
error[E0517]: attribute should be applied to a struct or union
|
||||
--> $DIR/packed-enum.rs:3:8
|
||||
|
|
||||
3 | #[repr(packed)] //~ ERROR E0517
|
||||
| ^^^^^^
|
||||
4 | / enum E1 {
|
||||
5 | | V(()),
|
||||
6 | | }
|
||||
| |_- not a struct or union
|
||||
|
||||
error[E0517]: attribute should be applied to a struct or union
|
||||
--> $DIR/packed-enum.rs:9:8
|
||||
|
|
||||
9 | #[repr(packed)] //~ ERROR E0517
|
||||
| ^^^^^^
|
||||
10 | / enum E2 {
|
||||
11 | | V(()),
|
||||
12 | | }
|
||||
| |_- not a struct or union
|
||||
|
||||
error[E0517]: attribute should be applied to a struct or union
|
||||
--> $DIR/packed-enum.rs:14:8
|
||||
|
|
||||
14 | #[repr(packed)] //~ ERROR E0517
|
||||
| ^^^^^^
|
||||
15 | #[pin_project]
|
||||
16 | / enum E3 {
|
||||
17 | | V(()),
|
||||
18 | | }
|
||||
| |_- not a struct or union
|
20
third_party/rust/pin-project/tests/ui/pin_project/packed-name-value.rs
vendored
Normal file
20
third_party/rust/pin-project/tests/ui/pin_project/packed-name-value.rs
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[repr(packed = "")] //~ ERROR E0552
|
||||
struct S1 {
|
||||
f: (),
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed = "")] //~ ERROR E0552
|
||||
struct S2 {
|
||||
f: (),
|
||||
}
|
||||
|
||||
#[repr(packed = "")] //~ ERROR E0552
|
||||
#[pin_project]
|
||||
struct S3 {
|
||||
f: (),
|
||||
}
|
||||
|
||||
fn main() {}
|
17
third_party/rust/pin-project/tests/ui/pin_project/packed-name-value.stderr
vendored
Normal file
17
third_party/rust/pin-project/tests/ui/pin_project/packed-name-value.stderr
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
error[E0552]: unrecognized representation hint
|
||||
--> $DIR/packed-name-value.rs:3:8
|
||||
|
|
||||
3 | #[repr(packed = "")] //~ ERROR E0552
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0552]: unrecognized representation hint
|
||||
--> $DIR/packed-name-value.rs:9:8
|
||||
|
|
||||
9 | #[repr(packed = "")] //~ ERROR E0552
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0552]: unrecognized representation hint
|
||||
--> $DIR/packed-name-value.rs:14:8
|
||||
|
|
||||
14 | #[repr(packed = "")] //~ ERROR E0552
|
||||
| ^^^^^^^^^^^
|
@ -2,24 +2,32 @@ use pin_project::pin_project;
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
|
||||
struct A {
|
||||
struct Packed1 {
|
||||
#[pin]
|
||||
field: u8,
|
||||
f: u8,
|
||||
}
|
||||
|
||||
// Test putting 'repr' before the 'pin_project' attribute
|
||||
#[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
|
||||
#[pin_project]
|
||||
struct B {
|
||||
struct Packed2 {
|
||||
#[pin]
|
||||
field: u8,
|
||||
f: u8,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
|
||||
struct C {
|
||||
struct PackedN1 {
|
||||
#[pin]
|
||||
field: u32,
|
||||
f: u32,
|
||||
}
|
||||
|
||||
// Test putting 'repr' before the 'pin_project' attribute
|
||||
#[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
|
||||
#[pin_project]
|
||||
struct PackedN2 {
|
||||
#[pin]
|
||||
f: u32,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -15,3 +15,9 @@ error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
|
|
||||
19 | #[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: #[pin_project] attribute may not be used on #[repr(packed)] types
|
||||
--> $DIR/packed.rs:26:8
|
||||
|
|
||||
26 | #[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
|
||||
| ^^^^^^^^^
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::hidden_repr;
|
||||
use auxiliary_macro::hidden_repr;
|
||||
use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
|
||||
use std::pin::Pin;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use auxiliary_macros::hidden_repr_macro;
|
||||
use auxiliary_macro::hidden_repr_macro;
|
||||
use pin_project::pin_project;
|
||||
|
||||
hidden_repr_macro! { //~ ERROR may not be used on #[repr(packed)] types
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![allow(private_in_public)]
|
||||
|
||||
pub enum PublicEnum {
|
||||
Variant(PrivateEnum),
|
||||
Variant(PrivateEnum), //~ ERROR E0446
|
||||
}
|
||||
|
||||
enum PrivateEnum {
|
||||
@ -12,7 +12,7 @@ enum PrivateEnum {
|
||||
|
||||
mod foo {
|
||||
pub(crate) enum CrateEnum {
|
||||
Variant(PrivateEnum),
|
||||
Variant(PrivateEnum), //~ ERROR E0446
|
||||
}
|
||||
|
||||
enum PrivateEnum {
|
||||
|
@ -1,17 +1,17 @@
|
||||
error[E0446]: private type `PrivateEnum` in public interface
|
||||
--> $DIR/private_in_public-enum.rs:6:13
|
||||
|
|
||||
6 | Variant(PrivateEnum),
|
||||
6 | Variant(PrivateEnum), //~ ERROR E0446
|
||||
| ^^^^^^^^^^^ can't leak private type
|
||||
...
|
||||
9 | enum PrivateEnum {
|
||||
| - `PrivateEnum` declared as private
|
||||
| ---------------- `PrivateEnum` declared as private
|
||||
|
||||
error[E0446]: private type `foo::PrivateEnum` in public interface
|
||||
--> $DIR/private_in_public-enum.rs:15:17
|
||||
|
|
||||
15 | Variant(PrivateEnum),
|
||||
15 | Variant(PrivateEnum), //~ ERROR E0446
|
||||
| ^^^^^^^^^^^ can't leak private type
|
||||
...
|
||||
18 | enum PrivateEnum {
|
||||
| - `foo::PrivateEnum` declared as private
|
||||
| ---------------- `foo::PrivateEnum` declared as private
|
||||
|
11
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized.rs
vendored
Normal file
11
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized.rs
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(project_replace)] //~ ERROR E0277
|
||||
struct Struct<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)] //~ ERROR E0277
|
||||
struct TupleStruct<T: ?Sized>(T);
|
||||
|
||||
fn main() {}
|
70
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized.stderr
vendored
Normal file
70
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized.stderr
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:3:15
|
||||
|
|
||||
3 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
4 | struct Struct<T: ?Sized> {
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: required because it appears within the type `Struct<T>`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
3 | #[pin_project(&project_replace)] //~ ERROR E0277
|
||||
| ^
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:5:5
|
||||
|
|
||||
4 | struct Struct<T: ?Sized> {
|
||||
| - this type parameter needs to be `Sized`
|
||||
5 | x: T,
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:3:1
|
||||
|
|
||||
3 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
4 | struct Struct<T: ?Sized> {
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: required because it appears within the type `__StructProjectionOwned<T>`
|
||||
= note: structs must have a statically known size to be initialized
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:8:15
|
||||
|
|
||||
8 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
9 | struct TupleStruct<T: ?Sized>(T);
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: required because it appears within the type `TupleStruct<T>`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
8 | #[pin_project(&project_replace)] //~ ERROR E0277
|
||||
| ^
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:8:1
|
||||
|
|
||||
8 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
9 | struct TupleStruct<T: ?Sized>(T);
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized.rs:9:8
|
||||
|
|
||||
9 | struct TupleStruct<T: ?Sized>(T);
|
||||
| ^^^^^^^^^^^ - this type parameter needs to be `Sized`
|
||||
| |
|
||||
| doesn't have a size known at compile-time
|
||||
|
|
||||
= note: all function arguments must have a statically known size
|
||||
= help: unsized fn params are gated as an unstable feature
|
13
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized_fn_params.rs
vendored
Normal file
13
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized_fn_params.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(unsized_fn_params)]
|
||||
|
||||
use pin_project::pin_project;
|
||||
|
||||
#[pin_project(project_replace)] //~ ERROR E0277
|
||||
struct Struct<T: ?Sized> {
|
||||
x: T,
|
||||
}
|
||||
|
||||
#[pin_project(project_replace)] //~ ERROR E0277
|
||||
struct TupleStruct<T: ?Sized>(T);
|
||||
|
||||
fn main() {}
|
53
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized_fn_params.stderr
vendored
Normal file
53
third_party/rust/pin-project/tests/ui/pin_project/project_replace_unsized_fn_params.stderr
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized_fn_params.rs:6:8
|
||||
|
|
||||
6 | struct Struct<T: ?Sized> {
|
||||
| ^^^^^^^-^^^^^^^^^
|
||||
| | |
|
||||
| | this type parameter needs to be `Sized`
|
||||
| doesn't have a size known at compile-time
|
||||
|
|
||||
= note: required because it appears within the type `__StructProjectionOwned<T>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized_fn_params.rs:7:5
|
||||
|
|
||||
6 | struct Struct<T: ?Sized> {
|
||||
| - this type parameter needs to be `Sized`
|
||||
7 | x: T,
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized_fn_params.rs:5:1
|
||||
|
|
||||
5 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
6 | struct Struct<T: ?Sized> {
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: required because it appears within the type `__StructProjectionOwned<T>`
|
||||
= note: structs must have a statically known size to be initialized
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized_fn_params.rs:11:8
|
||||
|
|
||||
11 | struct TupleStruct<T: ?Sized>(T);
|
||||
| ^^^^^^^^^^^^-^^^^^^^^^
|
||||
| | |
|
||||
| | this type parameter needs to be `Sized`
|
||||
| doesn't have a size known at compile-time
|
||||
|
|
||||
= note: required because it appears within the type `__TupleStructProjectionOwned<T>`
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/project_replace_unsized_fn_params.rs:10:1
|
||||
|
|
||||
10 | #[pin_project(project_replace)] //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
11 | struct TupleStruct<T: ?Sized>(T);
|
||||
| - this type parameter needs to be `Sized`
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
@ -13,7 +13,7 @@ struct Foo<T, U> {
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
pub struct TrivialBounds {
|
||||
struct TrivialBounds {
|
||||
#[pin]
|
||||
field1: PhantomPinned,
|
||||
}
|
||||
@ -34,5 +34,5 @@ fn main() {
|
||||
|
||||
is_unpin::<TrivialBounds>(); //~ ERROR E0277
|
||||
|
||||
is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ Ok
|
||||
is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); // Ok
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/proper_unpin.rs:31:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
31 | is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, PhantomPinned, ()>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned, ()>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, ()>`
|
||||
= note: required because it appears within the type `Inner<PhantomPinned>`
|
||||
= note: required because it appears within the type `__Foo<'_, PhantomPinned, ()>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned, ()>`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/proper_unpin.rs:33:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
33 | is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, PhantomPinned, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, std::marker::PhantomPinned>`
|
||||
= note: required because it appears within the type `Inner<PhantomPinned>`
|
||||
= note: required because it appears within the type `__Foo<'_, PhantomPinned, PhantomPinned>`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned, PhantomPinned>`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/proper_unpin.rs:35:5
|
||||
|
|
||||
28 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
35 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `__TrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `__TrivialBounds<'_>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `__TrivialBounds<'_>`
|
||||
= note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
|
||||
= note: required because of the requirements on the impl of `Unpin` for `TrivialBounds`
|
||||
|
@ -1,32 +1,32 @@
|
||||
use auxiliary_macros::remove_attr;
|
||||
use auxiliary_macro::remove_attr;
|
||||
use pin_project::pin_project;
|
||||
use std::{marker::PhantomPinned, pin::Pin};
|
||||
|
||||
fn is_unpin<T: Unpin>() {}
|
||||
|
||||
#[pin_project]
|
||||
#[remove_attr(field)]
|
||||
struct Foo {
|
||||
#[remove_attr(field_all)]
|
||||
struct A {
|
||||
#[pin]
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
#[remove_attr(field)]
|
||||
#[remove_attr(field_all)]
|
||||
#[pin_project]
|
||||
struct Bar {
|
||||
struct B {
|
||||
#[pin]
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
is_unpin::<Foo>();
|
||||
is_unpin::<Bar>();
|
||||
is_unpin::<A>();
|
||||
is_unpin::<B>();
|
||||
|
||||
let mut x = Foo { field: PhantomPinned };
|
||||
let mut x = A { field: PhantomPinned };
|
||||
let x = Pin::new(&mut x).project();
|
||||
let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
|
||||
|
||||
let mut x = Bar { field: PhantomPinned };
|
||||
let mut x = B { field: PhantomPinned };
|
||||
let x = Pin::new(&mut x).project();
|
||||
let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
|
||||
}
|
||||
|
@ -2,20 +2,20 @@ error[E0308]: mismatched types
|
||||
--> $DIR/remove-attr-from-field.rs:27:38
|
||||
|
|
||||
27 | let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
|
||||
| ----------------------- ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
|
||||
| ----------------------- ^^^^^^^ expected struct `Pin`, found `&mut PhantomPinned`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
|
||||
found mutable reference `&mut std::marker::PhantomPinned`
|
||||
= note: expected struct `Pin<&mut PhantomPinned>`
|
||||
found mutable reference `&mut PhantomPinned`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/remove-attr-from-field.rs:31:38
|
||||
|
|
||||
31 | let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
|
||||
| ----------------------- ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
|
||||
| ----------------------- ^^^^^^^ expected struct `Pin`, found `&mut PhantomPinned`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
|
||||
found mutable reference `&mut std::marker::PhantomPinned`
|
||||
= note: expected struct `Pin<&mut PhantomPinned>`
|
||||
found mutable reference `&mut PhantomPinned`
|
||||
|
@ -1,30 +1,46 @@
|
||||
use auxiliary_macros::remove_attr;
|
||||
use auxiliary_macro::remove_attr;
|
||||
use pin_project::pin_project;
|
||||
use std::{marker::PhantomPinned, pin::Pin};
|
||||
|
||||
fn is_unpin<T: Unpin>() {}
|
||||
|
||||
#[pin_project]
|
||||
#[remove_attr(struct)]
|
||||
struct Foo {
|
||||
#[remove_attr(struct_all)]
|
||||
struct A {
|
||||
#[pin] //~ ERROR cannot find attribute `pin` in this scope
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
#[remove_attr(struct)]
|
||||
#[remove_attr(struct_all)]
|
||||
#[pin_project]
|
||||
struct Bar {
|
||||
struct B {
|
||||
#[pin] //~ ERROR cannot find attribute `pin` in this scope
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
#[pin_project] //~ ERROR has been removed
|
||||
#[remove_attr(struct_pin)]
|
||||
struct C {
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
#[remove_attr(struct_pin)]
|
||||
#[pin_project] // Ok
|
||||
struct D {
|
||||
field: PhantomPinned,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
is_unpin::<Foo>(); //~ ERROR E0277
|
||||
is_unpin::<Bar>(); //~ ERROR E0277
|
||||
is_unpin::<A>(); //~ ERROR E0277
|
||||
is_unpin::<B>(); //~ ERROR E0277
|
||||
is_unpin::<D>(); // Ok
|
||||
|
||||
let mut x = Foo { field: PhantomPinned };
|
||||
let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
let mut x = A { field: PhantomPinned };
|
||||
let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
|
||||
let mut x = Bar { field: PhantomPinned };
|
||||
let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
let mut x = B { field: PhantomPinned };
|
||||
let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
|
||||
let mut x = D { field: PhantomPinned };
|
||||
let _ = Pin::new(&mut x).project(); //~ Ok
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
error: cannot find attribute `pin` in this scope
|
||||
--> $DIR/remove-attr-from-struct.rs:10:7
|
||||
error: #[pin_project] attribute has been removed
|
||||
--> $DIR/remove-attr-from-struct.rs:21:1
|
||||
|
|
||||
10 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
|
||||
| ^^^
|
||||
21 | #[pin_project] //~ ERROR has been removed
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: cannot find attribute `pin` in this scope
|
||||
--> $DIR/remove-attr-from-struct.rs:17:7
|
||||
@ -10,54 +12,60 @@ error: cannot find attribute `pin` in this scope
|
||||
17 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
|
||||
| ^^^
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:22:5
|
||||
error: cannot find attribute `pin` in this scope
|
||||
--> $DIR/remove-attr-from-struct.rs:10:7
|
||||
|
|
||||
10 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
|
||||
| ^^^
|
||||
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:34:5
|
||||
|
|
||||
5 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
22 | is_unpin::<Foo>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
34 | is_unpin::<A>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^ within `A`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Foo`
|
||||
= note: required because it appears within the type `A`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:23:5
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:35:5
|
||||
|
|
||||
5 | fn is_unpin<T: Unpin>() {}
|
||||
| ----- required by this bound in `is_unpin`
|
||||
...
|
||||
23 | is_unpin::<Bar>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
35 | is_unpin::<B>(); //~ ERROR E0277
|
||||
| ^^^^^^^^^^^^^ within `B`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Bar`
|
||||
= note: required because it appears within the type `B`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:26:14
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:39:13
|
||||
|
|
||||
26 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
39 | let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^^ within `A`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Foo`
|
||||
= note: required by `std::pin::Pin::<P>::new`
|
||||
= note: required because it appears within the type `A`
|
||||
= note: required by `Pin::<P>::new`
|
||||
|
||||
error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo>` in the current scope
|
||||
--> $DIR/remove-attr-from-struct.rs:26:31
|
||||
error[E0599]: no method named `project` found for struct `Pin<&mut A>` in the current scope
|
||||
--> $DIR/remove-attr-from-struct.rs:39:30
|
||||
|
|
||||
26 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^ method not found in `std::pin::Pin<&mut Foo>`
|
||||
39 | let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^ method not found in `Pin<&mut A>`
|
||||
|
||||
error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:29:14
|
||||
error[E0277]: `PhantomPinned` cannot be unpinned
|
||||
--> $DIR/remove-attr-from-struct.rs:42:13
|
||||
|
|
||||
29 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
|
||||
42 | let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^^ within `B`, the trait `Unpin` is not implemented for `PhantomPinned`
|
||||
|
|
||||
= note: required because it appears within the type `Bar`
|
||||
= note: required by `std::pin::Pin::<P>::new`
|
||||
= note: required because it appears within the type `B`
|
||||
= note: required by `Pin::<P>::new`
|
||||
|
||||
error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Bar>` in the current scope
|
||||
--> $DIR/remove-attr-from-struct.rs:29:31
|
||||
error[E0599]: no method named `project` found for struct `Pin<&mut B>` in the current scope
|
||||
--> $DIR/remove-attr-from-struct.rs:42:30
|
||||
|
|
||||
29 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^ method not found in `std::pin::Pin<&mut Bar>`
|
||||
42 | let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
|
||||
| ^^^^^^^ method not found in `Pin<&mut B>`
|
||||
|
@ -1,21 +1,27 @@
|
||||
#![deny(safe_packed_borrows)]
|
||||
#![forbid(safe_packed_borrows)]
|
||||
#![allow(unaligned_references)]
|
||||
|
||||
// Refs: https://github.com/rust-lang/rust/issues/46043
|
||||
// This lint was removed in https://github.com/rust-lang/rust/pull/82525 (nightly-2021-03-28).
|
||||
// Refs:
|
||||
// - https://github.com/rust-lang/rust/pull/82525
|
||||
// - https://github.com/rust-lang/rust/issues/46043
|
||||
|
||||
#[repr(packed)]
|
||||
struct A {
|
||||
field: u32,
|
||||
struct Packed {
|
||||
f: u32,
|
||||
}
|
||||
|
||||
#[repr(packed(2))]
|
||||
struct B {
|
||||
field: u32,
|
||||
struct PackedN {
|
||||
f: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = A { field: 1 };
|
||||
&a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
let a = Packed { f: 1 };
|
||||
&a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
let _ = &a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
|
||||
let b = B { field: 1 };
|
||||
&b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
let b = PackedN { f: 1 };
|
||||
&b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
let _ = &b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
}
|
||||
|
@ -1,23 +1,43 @@
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/safe_packed_borrows.rs:17:5
|
||||
--> $DIR/safe_packed_borrows.rs:21:5
|
||||
|
|
||||
17 | &a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^^^^^
|
||||
21 | &a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/safe_packed_borrows.rs:1:9
|
||||
--> $DIR/safe_packed_borrows.rs:1:11
|
||||
|
|
||||
1 | #![deny(safe_packed_borrows)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
1 | #![forbid(safe_packed_borrows)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
|
||||
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/safe_packed_borrows.rs:20:5
|
||||
--> $DIR/safe_packed_borrows.rs:22:13
|
||||
|
|
||||
20 | &b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^^^^^
|
||||
22 | let _ = &a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
|
||||
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/safe_packed_borrows.rs:25:5
|
||||
|
|
||||
25 | &b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
= note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
|
||||
|
||||
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
|
||||
--> $DIR/safe_packed_borrows.rs:26:13
|
||||
|
|
||||
26 | let _ = &b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
|
||||
|
24
third_party/rust/pin-project/tests/ui/pin_project/unaligned_references.rs
vendored
Normal file
24
third_party/rust/pin-project/tests/ui/pin_project/unaligned_references.rs
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
#![forbid(unaligned_references)]
|
||||
#![allow(safe_packed_borrows)]
|
||||
|
||||
// Refs: https://github.com/rust-lang/rust/issues/82523
|
||||
|
||||
#[repr(packed)]
|
||||
struct Packed {
|
||||
f: u32,
|
||||
}
|
||||
|
||||
#[repr(packed(2))]
|
||||
struct PackedN {
|
||||
f: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Packed { f: 1 };
|
||||
&a.f; //~ ERROR reference to packed field is unaligned
|
||||
let _ = &a.f; //~ ERROR reference to packed field is unaligned
|
||||
|
||||
let b = PackedN { f: 1 };
|
||||
&b.f; //~ ERROR reference to packed field is unaligned
|
||||
let _ = &b.f; //~ ERROR reference to packed field is unaligned
|
||||
}
|
36
third_party/rust/pin-project/tests/ui/pin_project/unaligned_references.stderr
vendored
Normal file
36
third_party/rust/pin-project/tests/ui/pin_project/unaligned_references.stderr
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:18:5
|
||||
|
|
||||
18 | &a.f; //~ ERROR reference to packed field is unaligned
|
||||
| ^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unaligned_references.rs:1:11
|
||||
|
|
||||
1 | #![forbid(unaligned_references)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:19:13
|
||||
|
|
||||
19 | let _ = &a.f; //~ ERROR reference to packed field is unaligned
|
||||
| ^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:22:5
|
||||
|
|
||||
22 | &b.f; //~ ERROR reference to packed field is unaligned
|
||||
| ^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
|
||||
error: reference to packed field is unaligned
|
||||
--> $DIR/unaligned_references.rs:23:13
|
||||
|
|
||||
23 | let _ = &b.f; //~ ERROR reference to packed field is unaligned
|
||||
| ^^^^
|
||||
|
|
||||
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user