Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak ui tests and error messages #61

Merged
merged 1 commit into from
Sep 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions pin-project-internal/src/pin_project/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,25 @@ use super::{Context, PIN};

pub(super) fn parse(cx: &mut Context, mut item: ItemEnum) -> Result<TokenStream> {
if item.variants.is_empty() {
return Err(error!(item, "cannot be implemented for enums without variants"));
return Err(error!(
item,
"#[pin_project] attribute may not be used on enums without variants"
));
}
let has_field = item.variants.iter().try_fold(false, |has_field, v| {
if let Some((_, e)) = &v.discriminant {
Err(error!(e, "cannot be implemented for enums with discriminants"))
Err(error!(e, "#[pin_project] attribute may not be used on enums with discriminants"))
} else if let Fields::Unit = v.fields {
Ok(has_field)
} else {
Ok(true)
}
})?;
if !has_field {
return Err(error!(item.variants, "cannot be implemented for enums that have no field"));
return Err(error!(
item.variants,
"#[pin_project] attribute may not be used on enums that have no field"
));
}

let (proj_variants, proj_arms) = variants(cx, &mut item)?;
Expand Down
11 changes: 8 additions & 3 deletions pin-project-internal/src/pin_project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ impl Parse for Args {
match &*i.to_string() {
"PinnedDrop" => pinned_drop = Some(i.span()),
"UnsafeUnpin" => unsafe_unpin = Some(i.span()),
_ => return Err(error!(i, "an invalid argument was passed")),
_ => {
return Err(error!(
i,
"an invalid argument was passed to #[pin_project] attribute"
))
}
}

if !input.is_empty() {
Expand Down Expand Up @@ -363,7 +368,7 @@ fn parse(args: TokenStream, input: TokenStream) -> Result<TokenStream> {
res.extend(cx.make_proj_trait());
Ok(res)
}
item => Err(error!(item, "may only be used on structs or enums")),
item => Err(error!(item, "#[pin_project] attribute may only be used on structs or enums")),
}
}

Expand All @@ -376,7 +381,7 @@ fn ensure_not_packed(item: &ItemStruct) -> Result<TokenStream> {
if p.is_ident("packed") {
return Err(error!(
p,
"pin_project may not be used on #[repr(packed)] types"
"#[pin_project] attribute may not be used on #[repr(packed)] types"
));
}
}
Expand Down
12 changes: 10 additions & 2 deletions pin-project-internal/src/pin_project/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,17 @@ pub(super) fn parse(cx: &mut Context, mut item: ItemStruct) -> Result<TokenStrea
| Fields::Unnamed(FieldsUnnamed { unnamed: fields, .. })
if fields.is_empty() =>
{
return Err(error!(item.fields, "cannot be implemented for structs with zero fields"))
return Err(error!(
item.fields,
"#[pin_project] attribute may not be used on structs with zero fields"
))
}
Fields::Unit => {
return Err(error!(
item,
"#[pin_project] attribute may not be used on structs with units"
))
}
Fields::Unit => return Err(error!(item, "cannot be implemented for structs with units")),

Fields::Named(fields) => named(cx, fields)?,
Fields::Unnamed(fields) => unnamed(cx, fields)?,
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/pin_project/drop_conflict.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::{pin_project, pinned_drop};
use std::pin::Pin;

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/pin_project/drop_conflict.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
error[E0119]: conflicting implementations of trait `FooMustNotImplDrop` for type `Foo<_, _>`:
--> $DIR/drop_conflict.rs:8:1
--> $DIR/drop_conflict.rs:6:1
|
8 | #[pin_project] //~ ERROR E0119
6 | #[pin_project] //~ ERROR E0119
| ^^^^^^^^^^^^^^
| |
| first implementation here
| conflicting implementation for `Foo<_, _>`

error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `Bar<_, _>`:
--> $DIR/drop_conflict.rs:19:1
--> $DIR/drop_conflict.rs:17:1
|
19 | #[pin_project(PinnedDrop)] //~ ERROR E0119
17 | #[pin_project(PinnedDrop)] //~ ERROR E0119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
...
29 | impl<T, U> Drop for Bar<T, U> {
27 | impl<T, U> Drop for Bar<T, U> {
| ----------------------------- first implementation here

error: aborting due to 2 previous errors
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/pin_project/forget-unsafe-unpin.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// run-pass

#![deny(warnings, unsafe_code)]

use pin_project::pin_project;

// FIXME
Expand Down
Empty file.
4 changes: 1 addition & 3 deletions tests/ui/pin_project/invalid.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::pin_project;

#[pin_project]
Expand All @@ -26,7 +24,7 @@ enum D<T> {
},
}

#[pin_project(UnsafeUnpin,,)] //~ ERROR unexpected token
#[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
struct E<T> {
#[pin]
future: T,
Expand Down
20 changes: 10 additions & 10 deletions tests/ui/pin_project/invalid.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
error: unexpected token
--> $DIR/invalid.rs:9:10
--> $DIR/invalid.rs:7:10
|
9 | #[pin()] //~ ERROR unexpected token
7 | #[pin()] //~ ERROR unexpected token
| ^

error: unexpected token
--> $DIR/invalid.rs:14:18
--> $DIR/invalid.rs:12:18
|
14 | struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
12 | struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
| ^

error: unexpected token
--> $DIR/invalid.rs:18:12
--> $DIR/invalid.rs:16:12
|
18 | A(#[pin(foo)] T), //~ ERROR unexpected token
16 | A(#[pin(foo)] T), //~ ERROR unexpected token
| ^

error: unexpected token
--> $DIR/invalid.rs:24:14
--> $DIR/invalid.rs:22:14
|
24 | #[pin(foo)] //~ ERROR unexpected token
22 | #[pin(foo)] //~ ERROR unexpected token
| ^

error: expected identifier
--> $DIR/invalid.rs:29:27
--> $DIR/invalid.rs:27:27
|
29 | #[pin_project(UnsafeUnpin,,)] //~ ERROR unexpected token
27 | #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
| ^

error: aborting due to 5 previous errors
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/pin_project/packed.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::pin_project;

#[pin_project]
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/pin_project/packed.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error: pin_project may not be used on #[repr(packed)] types
--> $DIR/packed.rs:8:8
error: #[pin_project] attribute may not be used on #[repr(packed)] types
--> $DIR/packed.rs:6:8
|
8 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] type
6 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] type
| ^^^^^^

error: pin_project may not be used on #[repr(packed)] types
--> $DIR/packed.rs:15:8
error: #[pin_project] attribute may not be used on #[repr(packed)] types
--> $DIR/packed.rs:13:8
|
15 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] type
13 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] type
| ^^^^^^

error: aborting due to 2 previous errors
Expand Down
6 changes: 2 additions & 4 deletions tests/ui/pin_project/proper_unpin.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::{pin_project, pinned_drop};
use std::pin::Pin;

struct Inner<T> {
val: T
val: T,
}

#[pin_project]
struct Foo<T, U> {
#[pin]
inner: Inner<T>,
other: U
other: U,
}

fn is_unpin<T: Unpin>() {}
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/pin_project/proper_unpin.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error[E0277]: the trait bound `T: std::marker::Unpin` is not satisfied in `__UnpinStructFoo<T, U>`
--> $DIR/proper_unpin.rs:22:5
--> $DIR/proper_unpin.rs:20:5
|
19 | fn is_unpin<T: Unpin>() {}
17 | fn is_unpin<T: Unpin>() {}
| ----------------------- required by `is_unpin`
...
22 | is_unpin::<Foo<T, U>>(); //~ ERROR E0277
20 | is_unpin::<Foo<T, U>>(); //~ ERROR E0277
| ^^^^^^^^^^^^^^^^^^^^^ within `__UnpinStructFoo<T, U>`, the trait `std::marker::Unpin` is not implemented for `T`
|
= help: consider adding a `where T: std::marker::Unpin` bound
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/pin_project/unpin_conflict.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::pin_project;
use std::pin::Pin;

Expand Down
18 changes: 9 additions & 9 deletions tests/ui/pin_project/unpin_conflict.stderr
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
--> $DIR/unpin_conflict.rs:10:1
--> $DIR/unpin_conflict.rs:8:1
|
10 | #[pin_project] //~ ERROR E0119
8 | #[pin_project] //~ ERROR E0119
| ^^^^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
...
18 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl
16 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl
| --------------------------------------------- first implementation here

error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
--> $DIR/unpin_conflict.rs:22:1
--> $DIR/unpin_conflict.rs:20:1
|
22 | #[pin_project] //~ ERROR E0119
20 | #[pin_project] //~ ERROR E0119
| ^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
...
30 | impl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl
28 | impl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl
| ------------------------------ first implementation here

error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
--> $DIR/unpin_conflict.rs:32:1
--> $DIR/unpin_conflict.rs:30:1
|
32 | #[pin_project] //~ ERROR E0119
30 | #[pin_project] //~ ERROR E0119
| ^^^^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
...
40 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl
38 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl
| -------------------------------------------- first implementation here

error: aborting due to 3 previous errors
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/pin_project/unpin_sneaky.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// compile-fail

use pin_project::pin_project;

#[pin_project]
struct Foo {
#[pin]
inner: u8
inner: u8,
}

impl Unpin for __UnpinStructFoo {}
impl Unpin for __UnpinStructFoo {} //~ ERROR E0412,E0321

fn main() {}
22 changes: 11 additions & 11 deletions tests/ui/pin_project/unpin_sneaky.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
error[E0412]: cannot find type `__UnpinStructFoo` in this scope
--> $DIR/unpin_sneaky.rs:9:16
|
9 | impl Unpin for __UnpinStructFoo {}
| ^^^^^^^^^^^^^^^^ not found in this scope
--> $DIR/unpin_sneaky.rs:11:16
|
11 | impl Unpin for __UnpinStructFoo {} //~ ERROR E0412,E0321
| ^^^^^^^^^^^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
1 | use crate::__UnpinStructFoo;
|
|
3 | use crate::__UnpinStructFoo;
|

error[E0321]: cross-crate traits with a default impl, like `std::marker::Unpin`, can only be implemented for a struct/enum type, not `[type error]`
--> $DIR/unpin_sneaky.rs:9:1
|
9 | impl Unpin for __UnpinStructFoo {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
--> $DIR/unpin_sneaky.rs:11:1
|
11 | impl Unpin for __UnpinStructFoo {} //~ ERROR E0412,E0321
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type

error: aborting due to 2 previous errors

Expand Down
14 changes: 6 additions & 8 deletions tests/ui/pin_project/unsupported.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
// compile-fail

#![deny(warnings, unsafe_code)]

use pin_project::pin_project;

#[pin_project]
struct Struct1 {} //~ ERROR cannot be implemented for structs with zero fields
struct Struct1 {} //~ ERROR may not be used on structs with zero fields

#[pin_project]
struct Struct2(); //~ ERROR cannot be implemented for structs with zero fields
struct Struct2(); //~ ERROR may not be used on structs with zero fields

#[pin_project]
struct Struct3; //~ ERROR cannot be implemented for structs with units
struct Struct3; //~ ERROR may not be used on structs with units

#[pin_project]
enum Enum1 {} //~ ERROR cannot be implemented for enums without variants
enum Enum1 {} //~ ERROR may not be used on enums without variants

#[pin_project]
enum Enum2 {
A = 2, //~ ERROR cannot be implemented for enums with discriminants
A = 2, //~ ERROR may not be used on enums with discriminants
}

#[pin_project]
enum Enum1 {
A, //~ ERROR cannot be implemented for enums that have no field
A, //~ ERROR may not be used on enums that have no field
B,
}

Expand Down
Loading