Skip to content

Commit

Permalink
Prepare for removal of safe_packed_borrows lint
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Mar 2, 2021
1 parent 30a0948 commit c4dcbad
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 12 deletions.
15 changes: 10 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,18 +590,23 @@ macro_rules! __pin_project_internal {

// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
//
// Taking a reference to a packed field is unsafe, amd appplying
// #[forbid(safe_packed_borrows)] makes sure that doing this without
// an 'unsafe' block (which we deliberately do not generate)
// is a hard error.
// 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(safe_packed_borrows)]
//
// Note:
// - Lint-based tricks aren't perfect, but they're much better than nothing:
// https://github.com/taiki-e/pin-project-lite/issues/26
// - Enable both unaligned_references and safe_packed_borrows lints
// because unaligned_references lint does not exist in older compilers:
// https://github.com/taiki-e/pin-project-lite/pull/55
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
$(where
$($where_clause)*)?
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/default/struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/multifields/struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned1;
let _ = &this.pinned2;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/naming/struct-all.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/naming/struct-mut.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/naming/struct-none.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/naming/struct-ref.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
2 changes: 1 addition & 1 deletion tests/expand/pub/struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const _: () = {
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
impl<T, U> MustNotImplDrop for Struct<T, U> {}
#[forbid(safe_packed_borrows)]
#[forbid(unaligned_references, safe_packed_borrows)]
fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
let _ = &this.pinned;
let _ = &this.unpinned;
Expand Down
52 changes: 52 additions & 0 deletions tests/ui/pin_project/packed.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
error: reference to packed field is unaligned
--> $DIR/packed.rs:3:1
|
3 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
4 | | #[repr(packed, C)]
5 | | struct A {
6 | | #[pin]
7 | | field: u16,
8 | | }
9 | | }
| |_^
|
note: the lint level is defined here
--> $DIR/packed.rs:3:1
|
3 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
4 | | #[repr(packed, C)]
5 | | struct A {
6 | | #[pin]
7 | | field: u16,
8 | | }
9 | | }
| |_^
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: reference to packed field is unaligned
--> $DIR/packed.rs:11:1
|
11 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
12 | | #[repr(packed(2))]
13 | | struct C {
14 | | #[pin]
15 | | field: u32,
16 | | }
17 | | }
| |_^
|
note: the lint level is defined here
--> $DIR/packed.rs:11:1
|
11 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
12 | | #[repr(packed(2))]
13 | | struct C {
14 | | #[pin]
15 | | field: u32,
16 | | }
17 | | }
| |_^
= note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/packed.rs:3:1
|
Expand Down

0 comments on commit c4dcbad

Please sign in to comment.