Improve error message on remote derive duplicate generics
This commit is contained in:
parent
c4f67e679f
commit
50354c2d0b
@ -24,7 +24,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = "1.0.90"
|
syn = "1.0.104"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0", path = "../serde" }
|
serde = { version = "1.0", path = "../serde" }
|
||||||
|
@ -6,6 +6,7 @@ use syn::{Member, Type};
|
|||||||
/// Cross-cutting checks that require looking at more than a single attrs
|
/// Cross-cutting checks that require looking at more than a single attrs
|
||||||
/// object. Simpler checks should happen when parsing and building the attrs.
|
/// object. Simpler checks should happen when parsing and building the attrs.
|
||||||
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||||
|
check_remote_generic(cx, cont);
|
||||||
check_getter(cx, cont);
|
check_getter(cx, cont);
|
||||||
check_flatten(cx, cont);
|
check_flatten(cx, cont);
|
||||||
check_identifier(cx, cont);
|
check_identifier(cx, cont);
|
||||||
@ -16,6 +17,28 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
|||||||
check_from_and_try_from(cx, cont);
|
check_from_and_try_from(cx, cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remote derive definition type must have either all of the generics of the
|
||||||
|
/// remote type:
|
||||||
|
///
|
||||||
|
/// #[serde(remote = "Generic")]
|
||||||
|
/// struct Generic<T> {…}
|
||||||
|
///
|
||||||
|
/// or none of them, i.e. defining impls for one concrete instantiation of the
|
||||||
|
/// remote type only:
|
||||||
|
///
|
||||||
|
/// #[serde(remote = "Generic<T>")]
|
||||||
|
/// struct ConcreteDef {…}
|
||||||
|
///
|
||||||
|
fn check_remote_generic(cx: &Ctxt, cont: &Container) {
|
||||||
|
if let Some(remote) = cont.attrs.remote() {
|
||||||
|
let local_has_generic = !cont.generics.params.is_empty();
|
||||||
|
let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none();
|
||||||
|
if local_has_generic && remote_has_generic {
|
||||||
|
cx.error_spanned_by(remote, "remove generic parameters from this path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Getters are only allowed inside structs (not enums) with the `remote`
|
/// Getters are only allowed inside structs (not enums) with the `remote`
|
||||||
/// attribute.
|
/// attribute.
|
||||||
fn check_getter(cx: &Ctxt, cont: &Container) {
|
fn check_getter(cx: &Ctxt, cont: &Container) {
|
||||||
|
@ -17,7 +17,7 @@ path = "lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.90", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
syn = { version = "1.0.104", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
@ -1,52 +1,5 @@
|
|||||||
error: expected one of `:`, `@`, or `|`, found `>`
|
error: remove generic parameters from this path
|
||||||
--> tests/ui/remote/double_generic.rs:12:19
|
|
||||||
|
|
|
||||||
12 | struct StructDef<U> {
|
|
||||||
| ^ expected one of `:`, `@`, or `|`
|
|
||||||
|
|
||||||
error: expected one of `!`, `)`, `,`, or `::`, found `<`
|
|
||||||
--> tests/ui/remote/double_generic.rs:12:17
|
|
||||||
|
|
|
||||||
11 | #[serde(remote = "remote::StructGeneric<u8>")]
|
|
||||||
| -
|
|
||||||
| |
|
|
||||||
| expected one of `!`, `)`, `,`, or `::`
|
|
||||||
| help: missing `,`
|
|
||||||
12 | struct StructDef<U> {
|
|
||||||
| ^ unexpected token
|
|
||||||
|
|
||||||
error: proc-macro derive produced unparseable tokens
|
|
||||||
--> tests/ui/remote/double_generic.rs:10:10
|
|
||||||
|
|
|
||||||
10 | #[derive(Serialize, Deserialize)]
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: expected one of `!`, `+`, `,`, `::`, or `>`, found `<`
|
|
||||||
--> tests/ui/remote/double_generic.rs:12:17
|
|
||||||
|
|
|
||||||
10 | #[derive(Serialize, Deserialize)]
|
|
||||||
| -----------
|
|
||||||
| |
|
|
||||||
| while parsing this item list starting here
|
|
||||||
| the item list ends here
|
|
||||||
11 | #[serde(remote = "remote::StructGeneric<u8>")]
|
|
||||||
| - expected one of `!`, `+`, `,`, `::`, or `>`
|
|
||||||
12 | struct StructDef<U> {
|
|
||||||
| ^ unexpected token
|
|
||||||
|
|
|
||||||
help: you might have meant to end the type parameters here
|
|
||||||
|
|
|
||||||
11 | #[serde(remote = "remote::StructGeneric<u8>">)]
|
|
||||||
| +
|
|
||||||
|
|
||||||
error: proc-macro derive produced unparseable tokens
|
|
||||||
--> tests/ui/remote/double_generic.rs:10:21
|
|
||||||
|
|
|
||||||
10 | #[derive(Serialize, Deserialize)]
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0412]: cannot find type `StructGeneric` in module `remote`
|
|
||||||
--> tests/ui/remote/double_generic.rs:11:18
|
--> tests/ui/remote/double_generic.rs:11:18
|
||||||
|
|
|
|
||||||
11 | #[serde(remote = "remote::StructGeneric<u8>")]
|
11 | #[serde(remote = "remote::StructGeneric<u8>")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in `remote`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Loading…
Reference in New Issue
Block a user