Skip to content

Commit

Permalink
Support ?Sized bounds in generic parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jan 20, 2020
1 parent b219910 commit 5eb45b9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 32 deletions.
26 changes: 13 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ macro_rules! pin_project {
pub struct $ident:ident
$(<
$( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
$( $generics:ident $(: $generics_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)?
$( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)?
>)?
$(where
$($where_clause_ty:ty : $where_clause_bound:path),* $(,)?
Expand All @@ -166,7 +166,7 @@ macro_rules! pin_project {
pub struct $ident
$(<
$( $lifetime $(: $lifetime_bound)? ),*
$( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
$( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
>)?
$(where
$($where_clause_ty : $where_clause_bound),*
Expand All @@ -184,7 +184,7 @@ macro_rules! pin_project {
$vis:vis struct $ident:ident
$(<
$( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
$( $generics:ident $(: $generics_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)?
$( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)?
>)?
$(where
$($where_clause_ty:ty : $where_clause_bound:path),* $(,)?
Expand All @@ -201,7 +201,7 @@ macro_rules! pin_project {
$vis struct $ident
$(<
$( $lifetime $(: $lifetime_bound)? ),*
$( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
$( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
>)?
$(where
$($where_clause_ty : $where_clause_bound),*
Expand All @@ -223,7 +223,7 @@ macro_rules! pin_project {
$(<
$( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),*
// limitation: does not support multiple trait/lifetime bounds and ? trait bounds.
$( $generics:ident $(: $generics_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),*
$( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),*
>)?
$(where
// limitation: does not support multiple trait/lifetime bounds and ? trait bounds.
Expand All @@ -239,7 +239,7 @@ macro_rules! pin_project {
) => {
$(#[$attrs])*
$vis struct $ident
$(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ,)* >)?
$(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ,)* >)?
$(where
$($where_clause_ty: $where_clause_bound),*
)*
Expand All @@ -254,7 +254,7 @@ macro_rules! pin_project {
#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
#[allow(dead_code)] // This lint warns unused fields/variants.
$proj_vis struct Projection
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* )?>
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
$(where
$($where_clause_ty: $where_clause_bound),*
)*
Expand All @@ -265,7 +265,7 @@ macro_rules! pin_project {
}
#[allow(dead_code)] // This lint warns unused fields/variants.
$proj_vis struct ProjectionRef
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* )?>
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
$(where
$($where_clause_ty: $where_clause_bound),*
)*
Expand All @@ -275,7 +275,7 @@ macro_rules! pin_project {
),+
}

impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* >)?
impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* >)?
$ident $(< $($lifetime,)* $($generics),* >)?
$(where
$($where_clause_ty: $where_clause_bound),*
Expand Down Expand Up @@ -333,7 +333,7 @@ macro_rules! pin_project {
//
// See also https://github.com/taiki-e/pin-project/pull/53.
$vis struct __Origin
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* )?>
<'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
$(where
$($where_clause_ty: $where_clause_bound),*
)*
Expand All @@ -343,7 +343,7 @@ macro_rules! pin_project {
$field: $crate::pin_project!(@make_unpin_bound $(#[$pin])? $field_ty)
),+
}
impl <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* )?> ::core::marker::Unpin
impl <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?> ::core::marker::Unpin
for $ident $(< $($lifetime,)* $($generics),* >)?
where
__Origin <'__pin $(, $($lifetime,)* $($generics),* )?>: ::core::marker::Unpin
Expand All @@ -366,7 +366,7 @@ macro_rules! pin_project {
#[allow(clippy::drop_bounds)]
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
#[allow(single_use_lifetimes)]
impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),*>)? MustNotImplDrop
impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),*>)? MustNotImplDrop
for $ident $(< $($lifetime,)* $($generics),* >)?
$(where
$($where_clause_ty: $where_clause_bound),*
Expand All @@ -390,7 +390,7 @@ macro_rules! pin_project {
#[allow(non_snake_case)]
#[deny(safe_packed_borrows)]
fn __assert_not_repr_packed
$(< $($lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: $generics_lifetime_bound)? ),* >)?
$(< $($lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* >)?
(
this: &$ident $(< $($lifetime,)* $($generics),* >)?
)
Expand Down
54 changes: 35 additions & 19 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ fn where_clause_and_associated_type_fields() {
// impl<T> Static for Struct3<T> {}
}

// #[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! {
Expand Down Expand Up @@ -110,11 +124,11 @@ fn move_out() {

#[test]
fn trait_bounds_on_type_generics() {
// pin_project! {
// pub struct Struct1<'a, T: ?Sized> {
// field: &'a mut T,
// }
// }
pin_project! {
pub struct Struct1<'a, T: ?Sized> {
field: &'a mut T,
}
}

pin_project! {
pub struct Struct2<'a, T: ::core::fmt::Debug> {
Expand Down Expand Up @@ -282,21 +296,23 @@ fn trivial_bounds() {
}
}

// #[test]
// fn dst() {
// pin_project! {
// pub struct A<T: ?Sized> {
// x: T,
// }
// }
#[test]
fn dst() {
pin_project! {
pub struct A<T: ?Sized> {
x: T,
}
}

// pin_project! {
// pub struct B<T: ?Sized> {
// #[pin]
// x: T,
// }
// }
// }
let _: &mut A<dyn core::fmt::Debug> = &mut A { x: 0u8 } as _;

pin_project! {
pub struct B<T: ?Sized> {
#[pin]
x: T,
}
}
}

#[test]
fn dyn_type() {
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/invalid-bounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use pin_project_lite::pin_project;

pin_project! {
struct A<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
field: T,
}
}

pin_project! {
struct B<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
field: T,
}
}

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/invalid-bounds.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: no rules expected the token `:`
--> $DIR/invalid-bounds.rs:4:25
|
4 | struct A<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
| ^ no rules expected this token in macro call

error: expected one of `+`, `,`, `=`, or `>`, found `:`
--> $DIR/invalid-bounds.rs:9:1
|
9 | / pin_project! {
10 | | struct B<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
11 | | field: T,
12 | | }
13 | | }
| | ^
| | |
| | expected one of `+`, `,`, `=`, or `>`
| |_unexpected token
| in this macro invocation
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

0 comments on commit 5eb45b9

Please sign in to comment.