Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 66fd488

Browse files
bors[bot]taiki-e
andauthoredSep 26, 2019
Merge #111
111: Add a dummy lifetime to UnpinStruct r=taiki-e a=taiki-e Basically the same as #107. This fixes #102 completely. cc #108 Co-authored-by: Taiki Endo <te316e89@gmail.com>
2 parents 0cf5990 + 9d0e875 commit 66fd488

17 files changed

+158
-96
lines changed
 

‎examples/enum-default-expanded.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use pin_project::pin_project;
2020

2121
enum Enum<T, U> {
22-
Pinned(T),
22+
Pinned(/* #[pin] */ T),
2323
Unpinned(U),
2424
}
2525

@@ -63,17 +63,16 @@ impl<T, U> Enum<T, U> {
6363
// for details.
6464
#[allow(non_snake_case)]
6565
fn __unpin_scope_Enum() {
66-
struct AlwaysUnpinEnum<T: ?Sized> {
67-
val: ::core::marker::PhantomData<T>,
68-
}
69-
impl<T: ?Sized> ::core::marker::Unpin for AlwaysUnpinEnum<T> {}
7066
#[allow(dead_code)]
7167
#[doc(hidden)]
72-
struct __UnpinStructEnum<T, U> {
73-
__pin_project_use_generics: AlwaysUnpinEnum<(T, U)>,
68+
struct __UnpinStructEnum<'_pin, T, U> {
69+
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'_pin, (T, U)>,
7470
__field0: T,
7571
}
76-
impl<T, U> ::core::marker::Unpin for Enum<T, U> where __UnpinStructEnum<T, U>: ::core::marker::Unpin {}
72+
impl<'_pin, T, U> ::core::marker::Unpin for Enum<T, U> where
73+
__UnpinStructEnum<'_pin, T, U>: ::core::marker::Unpin
74+
{
75+
}
7776
}
7877

7978
// Ensure that enum does not implement `Drop`.

‎examples/pinned_drop-expanded.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use std::pin::Pin;
2828

2929
pub struct Foo<'a, T> {
3030
was_dropped: &'a mut bool,
31+
// #[pin]
3132
field: T,
3233
}
3334

@@ -109,19 +110,17 @@ impl<T> ::pin_project::__private::PinnedDrop for Foo<'_, T> {
109110
// for details.
110111
#[allow(non_snake_case)]
111112
fn __unpin_scope_Foo() {
112-
struct AlwaysUnpinFoo<T: ?Sized> {
113-
val: ::core::marker::PhantomData<T>,
114-
}
115-
impl<T: ?Sized> ::core::marker::Unpin for AlwaysUnpinFoo<T> {}
116113
#[allow(dead_code)]
117114
#[doc(hidden)]
118-
pub struct __UnpinStructFoo<'a, T> {
119-
__pin_project_use_generics: AlwaysUnpinFoo<(T)>,
115+
pub struct __UnpinStructFoo<'_pin, 'a, T> {
116+
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'_pin, (T)>,
120117
__field0: T,
121118
__lifetime0: &'a (),
122119
}
123-
impl<'a, T> ::core::marker::Unpin for Foo<'a, T> where __UnpinStructFoo<'a, T>: ::core::marker::Unpin
124-
{}
120+
impl<'_pin, 'a, T> ::core::marker::Unpin for Foo<'a, T> where
121+
__UnpinStructFoo<'_pin, 'a, T>: ::core::marker::Unpin
122+
{
123+
}
125124
}
126125

127126
// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.

‎examples/struct-default-expanded.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use pin_project::pin_project;
2121

2222
struct Struct<T, U> {
23+
// #[pin]
2324
pinned: T,
2425
unpinned: U,
2526
}
@@ -86,18 +87,14 @@ impl<T, U> Struct<T, U> {
8687
// See also https://github.com/taiki-e/pin-project/pull/53.
8788
#[allow(non_snake_case)]
8889
fn __unpin_scope_Struct() {
89-
struct AlwaysUnpinStruct<T: ?Sized> {
90-
val: ::core::marker::PhantomData<T>,
91-
}
92-
impl<T: ?Sized> ::core::marker::Unpin for AlwaysUnpinStruct<T> {}
9390
#[allow(dead_code)]
9491
#[doc(hidden)]
95-
struct __UnpinStructStruct<T, U> {
96-
__pin_project_use_generics: AlwaysUnpinStruct<(T, U)>,
92+
struct __UnpinStructStruct<'_pin, T, U> {
93+
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'_pin, (T, U)>,
9794
__field0: T,
9895
}
99-
impl<T, U> ::core::marker::Unpin for Struct<T, U> where
100-
__UnpinStructStruct<T, U>: ::core::marker::Unpin
96+
impl<'_pin, T, U> ::core::marker::Unpin for Struct<T, U> where
97+
__UnpinStructStruct<'_pin, T, U>: ::core::marker::Unpin
10198
{
10299
}
103100
}

‎examples/unsafe_unpin-expanded.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use pin_project::{pin_project, UnsafeUnpin};
2323

2424
pub struct Foo<T, U> {
25+
// #[pin]
2526
pinned: T,
2627
unpinned: U,
2728
}

‎pin-project-internal/src/pin_project/derive.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use proc_macro2::TokenStream;
1+
use proc_macro2::{Span, TokenStream};
22
use quote::{format_ident, quote};
33
use syn::{parse::Nothing, *};
44

5-
use crate::utils::{Variants, VecExt};
5+
use crate::utils::{self, proj_lifetime_name, Variants, VecExt, DEFAULT_LIFETIME_NAME};
66

77
use super::PIN;
88

@@ -34,13 +34,27 @@ struct DeriveContext {
3434
/// Generics of the original type.
3535
generics: Generics,
3636

37+
/// Lifetime on the generated projected type.
38+
lifetime: Lifetime,
39+
3740
/// Types of the pinned fields.
3841
pinned_fields: Vec<Type>,
3942
}
4043

4144
impl DeriveContext {
4245
fn new(ident: Ident, vis: Visibility, generics: Generics) -> Self {
43-
Self { ident, vis, generics, pinned_fields: Vec::new() }
46+
let mut lifetime_name = String::from(DEFAULT_LIFETIME_NAME);
47+
proj_lifetime_name(&mut lifetime_name, &generics.params);
48+
let lifetime = Lifetime::new(&lifetime_name, Span::call_site());
49+
50+
Self { ident, vis, generics, lifetime, pinned_fields: Vec::new() }
51+
}
52+
53+
/// Creates the generics of projected type.
54+
fn proj_generics(&self) -> Generics {
55+
let mut generics = self.generics.clone();
56+
utils::proj_generics(&mut generics, self.lifetime.clone());
57+
generics
4458
}
4559

4660
fn visit_variants(&mut self, variants: &Variants) {
@@ -68,8 +82,6 @@ impl DeriveContext {
6882
fn make_unpin_impl(&mut self) -> TokenStream {
6983
let where_clause = self.generics.make_where_clause().clone();
7084
let orig_ident = &self.ident;
71-
let (impl_generics, ty_generics, _) = self.generics.split_for_impl();
72-
let type_params: Vec<_> = self.generics.type_params().map(|t| t.ident.clone()).collect();
7385

7486
let make_span = || {
7587
#[cfg(proc_macro_def_site)]
@@ -87,7 +99,6 @@ impl DeriveContext {
8799
} else {
88100
format_ident!("__UnpinStruct{}", orig_ident)
89101
};
90-
let always_unpin_ident = format_ident!("AlwaysUnpin{}", orig_ident, span = make_span());
91102

92103
// Generate a field in our new struct for every
93104
// pinned field in the original type.
@@ -138,25 +149,21 @@ impl DeriveContext {
138149

139150
let scope_ident = format_ident!("__unpin_scope_{}", orig_ident);
140151

141-
let vis = &self.vis;
142-
let full_generics = &self.generics;
152+
let Self { vis, lifetime, .. } = &self;
153+
let type_params: Vec<_> = self.generics.type_params().map(|t| t.ident.clone()).collect();
154+
let proj_generics = self.proj_generics();
155+
let (impl_generics, proj_ty_generics, _) = proj_generics.split_for_impl();
156+
let ty_generics = self.generics.split_for_impl().1;
143157
let mut full_where_clause = where_clause.clone();
144158

145159
let unpin_clause: WherePredicate = syn::parse_quote! {
146-
#struct_ident #ty_generics: ::core::marker::Unpin
160+
#struct_ident #proj_ty_generics: ::core::marker::Unpin
147161
};
148-
149162
full_where_clause.predicates.push(unpin_clause);
150163

151164
let attrs = if cfg!(proc_macro_def_site) { quote!() } else { quote!(#[doc(hidden)]) };
152165

153166
let inner_data = quote! {
154-
struct #always_unpin_ident <T: ?Sized> {
155-
val: ::core::marker::PhantomData<T>
156-
}
157-
158-
impl<T: ?Sized> ::core::marker::Unpin for #always_unpin_ident <T> {}
159-
160167
// This needs to have the same visibility as the original type,
161168
// due to the limitations of the 'public in private' error.
162169
//
@@ -171,8 +178,8 @@ impl DeriveContext {
171178
// See also https://github.com/taiki-e/pin-project/pull/53.
172179
#[allow(dead_code)]
173180
#attrs
174-
#vis struct #struct_ident #full_generics #where_clause {
175-
__pin_project_use_generics: #always_unpin_ident <(#(#type_params),*)>,
181+
#vis struct #struct_ident #proj_generics #where_clause {
182+
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<#lifetime, (#(#type_params),*)>,
176183

177184
#(#fields,)*
178185
#(#lifetime_fields,)*

‎src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,12 @@ pub mod __private {
199199

200200
#[allow(unsafe_code)]
201201
unsafe impl<T> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {}
202+
203+
// This is an internal helper struct used by `pin-project-internal`.
204+
//
205+
// See https://github.com/taiki-e/pin-project/pull/53 for more details.
206+
#[doc(hidden)]
207+
pub struct AlwaysUnpin<'a, T: ?Sized>(PhantomData<T>, PhantomData<&'a ()>);
208+
209+
impl<T: ?Sized> Unpin for AlwaysUnpin<'_, T> {}
202210
}

‎tests/pin_project.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![warn(rust_2018_idioms, single_use_lifetimes)]
44
#![allow(dead_code)]
55

6-
use core::pin::Pin;
6+
use core::{marker::PhantomPinned, pin::Pin};
77
use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
88

99
#[test]
@@ -348,3 +348,12 @@ fn visibility() {
348348
let y = x.project();
349349
let _: &mut u8 = y.b;
350350
}
351+
352+
#[test]
353+
fn trivial_bounds() {
354+
#[pin_project]
355+
pub struct NoGenerics {
356+
#[pin]
357+
field: PhantomPinned,
358+
}
359+
}

‎tests/ui/cfg/proper_unpin.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ struct Bar<T> {
2424
fn is_unpin<T: Unpin>() {}
2525

2626
fn baz<T, U>() {
27-
is_unpin::<Foo<PhantomPinned>>(); // Pass
27+
is_unpin::<Foo<PhantomPinned>>(); // Ok
28+
is_unpin::<Bar<()>>(); // Ok
2829
is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
2930
}
3031

‎tests/ui/cfg/proper_unpin.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `UnpinStructBar<std::marker::PhantomPinned>`
2-
--> $DIR/proper_unpin.rs:28:5
1+
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `UnpinStructBar<'_, std::marker::PhantomPinned>`
2+
--> $DIR/proper_unpin.rs:29:5
33
|
44
24 | fn is_unpin<T: Unpin>() {}
55
| -------- ----- required by this bound in `is_unpin`
66
...
7-
28 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructBar<std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
7+
29 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructBar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
99
|
1010
= help: the following implementations were found:
1111
<std::marker::PhantomPinned as std::marker::Unpin>
12-
= note: required because it appears within the type `UnpinStructBar<std::marker::PhantomPinned>`
12+
= note: required because it appears within the type `UnpinStructBar<'_, std::marker::PhantomPinned>`
1313
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
1414

1515
error: aborting due to previous error

‎tests/ui/pin_project/proper_unpin.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// compile-fail
22

33
use pin_project::pin_project;
4-
use std::pin::Pin;
4+
use std::marker::PhantomPinned;
55

66
struct Inner<T> {
77
val: T,
@@ -14,10 +14,29 @@ struct Foo<T, U> {
1414
other: U,
1515
}
1616

17+
#[pin_project]
18+
pub struct TrivialBounds {
19+
#[pin]
20+
field1: PhantomPinned,
21+
}
22+
23+
#[pin_project]
24+
struct Bar<'a, T, U> {
25+
#[pin]
26+
inner: &'a mut Inner<T>,
27+
other: U,
28+
}
29+
1730
fn is_unpin<T: Unpin>() {}
1831

19-
fn bar<T, U>() {
20-
is_unpin::<Foo<T, U>>(); //~ ERROR E0277
32+
fn assert_unpin() {
33+
is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
34+
is_unpin::<Foo<(), PhantomPinned>>(); // Ok
35+
is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
36+
37+
is_unpin::<TrivialBounds>(); //~ ERROR E0277
38+
39+
is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ Ok
2140
}
2241

2342
fn main() {}
+40-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,47 @@
1-
error[E0277]: the trait bound `T: std::marker::Unpin` is not satisfied in `UnpinStructFoo<T, U>`
2-
--> $DIR/proper_unpin.rs:20:5
1+
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `UnpinStructFoo<'_, std::marker::PhantomPinned, ()>`
2+
--> $DIR/proper_unpin.rs:33:5
33
|
4-
17 | fn is_unpin<T: Unpin>() {}
4+
30 | fn is_unpin<T: Unpin>() {}
55
| -------- ----- required by this bound in `is_unpin`
66
...
7-
20 | is_unpin::<Foo<T, U>>(); //~ ERROR E0277
8-
| ^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructFoo<T, U>`, the trait `std::marker::Unpin` is not implemented for `T`
7+
33 | is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructFoo<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
99
|
10-
= help: consider adding a `where T: std::marker::Unpin` bound
11-
= note: required because it appears within the type `Inner<T>`
12-
= note: required because it appears within the type `UnpinStructFoo<T, U>`
13-
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<T, U>`
10+
= help: the following implementations were found:
11+
<std::marker::PhantomPinned as std::marker::Unpin>
12+
= note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
13+
= note: required because it appears within the type `UnpinStructFoo<'_, std::marker::PhantomPinned, ()>`
14+
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, ()>`
1415

15-
error: aborting due to previous error
16+
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `UnpinStructFoo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
17+
--> $DIR/proper_unpin.rs:35:5
18+
|
19+
30 | fn is_unpin<T: Unpin>() {}
20+
| -------- ----- required by this bound in `is_unpin`
21+
...
22+
35 | is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructFoo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
24+
|
25+
= help: the following implementations were found:
26+
<std::marker::PhantomPinned as std::marker::Unpin>
27+
= note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
28+
= note: required because it appears within the type `UnpinStructFoo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
29+
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, std::marker::PhantomPinned>`
30+
31+
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `UnpinStructTrivialBounds<'_>`
32+
--> $DIR/proper_unpin.rs:37:5
33+
|
34+
30 | fn is_unpin<T: Unpin>() {}
35+
| -------- ----- required by this bound in `is_unpin`
36+
...
37+
37 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `UnpinStructTrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
39+
|
40+
= help: the following implementations were found:
41+
<std::marker::PhantomPinned as std::marker::Unpin>
42+
= note: required because it appears within the type `UnpinStructTrivialBounds<'_>`
43+
= note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
44+
45+
error: aborting due to 3 previous errors
1646

1747
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/unsafe_unpin/proper_unpin.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for OverlappingLifetimeNames<'_, T,
3535

3636
fn unsafe_unpin() {
3737
is_unpin::<Blah<PhantomPinned, ()>>(); //~ ERROR E0277
38+
is_unpin::<Blah<(), PhantomPinned>>(); // Ok
3839
is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
40+
3941
is_unpin::<NotImplementUnsafUnpin>(); //~ ERROR E0277
42+
4043
is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
4144
is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
4245
}

‎tests/ui/unsafe_unpin/proper_unpin.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` i
1414
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, ()>`
1515

1616
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied
17-
--> $DIR/proper_unpin.rs:38:5
17+
--> $DIR/proper_unpin.rs:39:5
1818
|
1919
6 | fn is_unpin<T: Unpin>() {}
2020
| -------- ----- required by this bound in `is_unpin`
2121
...
22-
38 | is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
22+
39 | is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
2424
|
2525
= help: the following implementations were found:
@@ -29,24 +29,24 @@ error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` i
2929
= note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>`
3030

3131
error[E0277]: the trait bound `NotImplementUnsafUnpin: pin_project::UnsafeUnpin` is not satisfied
32-
--> $DIR/proper_unpin.rs:39:16
32+
--> $DIR/proper_unpin.rs:41:16
3333
|
3434
6 | fn is_unpin<T: Unpin>() {}
3535
| -------- ----- required by this bound in `is_unpin`
3636
...
37-
39 | is_unpin::<NotImplementUnsafUnpin>(); //~ ERROR E0277
37+
41 | is_unpin::<NotImplementUnsafUnpin>(); //~ ERROR E0277
3838
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `pin_project::UnsafeUnpin` is not implemented for `NotImplementUnsafUnpin`
3939
|
4040
= note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, NotImplementUnsafUnpin>`
4141
= note: required because of the requirements on the impl of `std::marker::Unpin` for `NotImplementUnsafUnpin`
4242

4343
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied
44-
--> $DIR/proper_unpin.rs:40:5
44+
--> $DIR/proper_unpin.rs:43:5
4545
|
4646
6 | fn is_unpin<T: Unpin>() {}
4747
| -------- ----- required by this bound in `is_unpin`
4848
...
49-
40 | is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
49+
43 | is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
5050
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
5151
|
5252
= help: the following implementations were found:
@@ -56,12 +56,12 @@ error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` i
5656
= note: required because of the requirements on the impl of `std::marker::Unpin` for `OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>`
5757

5858
error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied
59-
--> $DIR/proper_unpin.rs:41:5
59+
--> $DIR/proper_unpin.rs:44:5
6060
|
6161
6 | fn is_unpin<T: Unpin>() {}
6262
| -------- ----- required by this bound in `is_unpin`
6363
...
64-
41 | is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
64+
44 | is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
6565
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
6666
|
6767
= help: the following implementations were found:
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-fail
1+
// run-pass
22

33
// NB: If you change this test, change 'trivial_bounds.rs' at the same time.
44

@@ -7,11 +7,10 @@ use std::marker::PhantomPinned;
77

88
struct Inner(PhantomPinned);
99

10-
// As a workaround, you need to use `UnsafeUnpin`.
11-
#[pin_project(UnsafeUnpin)] // Ok
10+
#[pin_project]
1211
struct Foo(#[pin] Inner);
1312

14-
#[pin_project] //~ ERROR E0277
13+
#[pin_project(UnsafeUnpin)]
1514
struct Bar(#[pin] Inner);
1615

1716
fn main() {}

‎tests/ui/unstable-features/trivial_bounds-feature-gate.stderr

-16
This file was deleted.

‎tests/ui/unstable-features/trivial_bounds.rs

+3
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ struct Inner(PhantomPinned);
1414
#[pin_project]
1515
struct Foo(#[pin] Inner);
1616

17+
#[pin_project(UnsafeUnpin)]
18+
struct Bar(#[pin] Inner);
19+
1720
fn main() {}

‎tests/unsafe_unpin.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ pub struct Blah<T, U> {
1717
#[allow(unsafe_code)]
1818
unsafe impl<T: Unpin, U> UnsafeUnpin for Blah<T, U> {}
1919

20-
#[pin_project(UnsafeUnpin)]
21-
pub struct NotImplementUnsafUnpin {
22-
#[pin]
23-
field1: PhantomPinned,
24-
}
25-
2620
#[pin_project(UnsafeUnpin)]
2721
pub struct OverlappingLifetimeNames<'_pin, T, U> {
2822
#[pin]
@@ -40,6 +34,15 @@ fn unsafe_unpin() {
4034
is_unpin::<OverlappingLifetimeNames<'_, (), ()>>();
4135
}
4236

37+
#[test]
38+
fn trivial_bounds() {
39+
#[pin_project(UnsafeUnpin)]
40+
pub struct NotImplementUnsafUnpin {
41+
#[pin]
42+
field: PhantomPinned,
43+
}
44+
}
45+
4346
#[test]
4447
fn test() {
4548
let mut x = OverlappingLifetimeNames { field1: 0, field2: 1, field3: &() };

0 commit comments

Comments
 (0)
Please sign in to comment.