Skip to content

Commit

Permalink
Merge #56
Browse files Browse the repository at this point in the history
56: 0.1: Prepare for removal of safe_packed_borrows lint r=taiki-e a=taiki-e

This is the backport of #55

Co-authored-by: Taiki Endo <[email protected]>
  • Loading branch information
bors[bot] and taiki-e authored Mar 2, 2021
2 parents f6de05d + ffed3c4 commit b2fba2e
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 19 deletions.
17 changes: 12 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,18 +301,25 @@ 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
// https://github.com/rust-lang/rust/pull/82525
#[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/tests/expand/default-struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,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/tests/expand/pub-struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,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
8 changes: 4 additions & 4 deletions tests/ui/packed.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use pin_project_lite::pin_project;

pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
pin_project! { //~ ERROR reference to packed field is unaligned
#[repr(packed, C)]
struct A {
struct Packed {
#[pin]
field: u16,
}
}

pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
pin_project! { //~ ERROR reference to packed field is unaligned
#[repr(packed(2))]
struct C {
struct PackedN {
#[pin]
field: u32,
}
Expand Down
68 changes: 60 additions & 8 deletions tests/ui/packed.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,61 @@
error: reference to packed field is unaligned
--> $DIR/packed.rs:3:1
|
3 | / pin_project! { //~ ERROR reference to packed field is unaligned
4 | | #[repr(packed, C)]
5 | | struct Packed {
6 | | #[pin]
7 | | field: u16,
8 | | }
9 | | }
| |_^
|
note: the lint level is defined here
--> $DIR/packed.rs:3:1
|
3 | / pin_project! { //~ ERROR reference to packed field is unaligned
4 | | #[repr(packed, C)]
5 | | struct Packed {
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 reference to packed field is unaligned
12 | | #[repr(packed(2))]
13 | | struct PackedN {
14 | | #[pin]
15 | | field: u32,
16 | | }
17 | | }
| |_^
|
note: the lint level is defined here
--> $DIR/packed.rs:11:1
|
11 | / pin_project! { //~ ERROR reference to packed field is unaligned
12 | | #[repr(packed(2))]
13 | | struct PackedN {
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
|
3 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
3 | / pin_project! { //~ ERROR reference to packed field is unaligned
4 | | #[repr(packed, C)]
5 | | struct A {
5 | | struct Packed {
6 | | #[pin]
7 | | field: u16,
8 | | }
Expand All @@ -13,9 +65,9 @@ error: borrow of packed field is unsafe and requires unsafe function or block (e
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
3 | / pin_project! { //~ ERROR reference to packed field is unaligned
4 | | #[repr(packed, C)]
5 | | struct A {
5 | | struct Packed {
6 | | #[pin]
7 | | field: u16,
8 | | }
Expand All @@ -29,9 +81,9 @@ note: the lint level is defined here
error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
--> $DIR/packed.rs:11:1
|
11 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
11 | / pin_project! { //~ ERROR reference to packed field is unaligned
12 | | #[repr(packed(2))]
13 | | struct C {
13 | | struct PackedN {
14 | | #[pin]
15 | | field: u32,
16 | | }
Expand All @@ -41,9 +93,9 @@ error: borrow of packed field is unsafe and requires unsafe function or block (e
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
11 | / pin_project! { //~ ERROR reference to packed field is unaligned
12 | | #[repr(packed(2))]
13 | | struct C {
13 | | struct PackedN {
14 | | #[pin]
15 | | field: u32,
16 | | }
Expand Down

0 comments on commit b2fba2e

Please sign in to comment.