From 77489c3107abe6780e2ce6551d4f00ccbbd36959 Mon Sep 17 00:00:00 2001 From: Amar Singh Date: Wed, 25 Aug 2021 21:32:25 -0400 Subject: [PATCH] Improve errors for `generate_solution_type` macro (#9553) * add more errors for check attributes in npos elections solution type * revert local env * return Ok false if there are no attributes * fmt * Update primitives/npos-elections/solution-type/src/lib.rs Co-authored-by: Squirrel * Update primitives/npos-elections/solution-type/src/lib.rs Co-authored-by: Guillaume Thiolliere * Update primitives/npos-elections/solution-type/src/lib.rs Co-authored-by: Guillaume Thiolliere * Update primitives/npos-elections/solution-type/src/lib.rs * improve span by giving extra attribute, nightly fmt * fix test to test new error msg Co-authored-by: Squirrel Co-authored-by: Guillaume Thiolliere --- .../npos-elections/solution-type/src/lib.rs | 27 +++++++------ .../{wrong_page.rs => wrong_attribute.rs} | 0 .../tests/ui/fail/wrong_attribute.stderr | 5 +++ .../tests/ui/fail/wrong_page.stderr | 38 ------------------- 4 files changed, 20 insertions(+), 50 deletions(-) rename substrate/primitives/npos-elections/solution-type/tests/ui/fail/{wrong_page.rs => wrong_attribute.rs} (100%) create mode 100644 substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.stderr delete mode 100644 substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.stderr diff --git a/substrate/primitives/npos-elections/solution-type/src/lib.rs b/substrate/primitives/npos-elections/solution-type/src/lib.rs index 16b4e8e047..9b0ec56fc7 100644 --- a/substrate/primitives/npos-elections/solution-type/src/lib.rs +++ b/substrate/primitives/npos-elections/solution-type/src/lib.rs @@ -134,20 +134,23 @@ struct SolutionDef { } fn check_attributes(input: ParseStream) -> syn::Result { - let attrs = input.call(syn::Attribute::parse_outer).unwrap_or_default(); + let mut attrs = input.call(syn::Attribute::parse_outer).unwrap_or_default(); if attrs.len() > 1 { - return Err(syn_err("compact solution can accept only #[compact]")) + let extra_attr = attrs.pop().expect("attributes vec with len > 1 can be popped"); + return Err(syn::Error::new_spanned( + extra_attr.clone(), + "compact solution can accept only #[compact]", + )) + } + if attrs.is_empty() { + return Ok(false) + } + let attr = attrs.pop().expect("attributes vec with len 1 can be popped."); + if attr.path.is_ident("compact") { + Ok(true) + } else { + Err(syn::Error::new_spanned(attr.clone(), "compact solution can accept only #[compact]")) } - - Ok(attrs.iter().any(|attr| { - if attr.path.segments.len() == 1 { - let segment = attr.path.segments.first().expect("Vec with len 1 can be popped."); - if segment.ident == Ident::new("compact", Span::call_site()) { - return true - } - } - false - })) } impl Parse for SolutionDef { diff --git a/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.rs b/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.rs similarity index 100% rename from substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.rs rename to substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.rs diff --git a/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.stderr b/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.stderr new file mode 100644 index 0000000000..ab700a3f2a --- /dev/null +++ b/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_attribute.stderr @@ -0,0 +1,5 @@ +error: compact solution can accept only #[compact] + --> $DIR/wrong_attribute.rs:4:2 + | +4 | #[pages(1)] pub struct TestSolution::< + | ^^^^^^^^^^^ diff --git a/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.stderr b/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.stderr deleted file mode 100644 index 7104305a9e..0000000000 --- a/substrate/primitives/npos-elections/solution-type/tests/ui/fail/wrong_page.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error[E0412]: cannot find type `Perbill` in this scope - --> $DIR/wrong_page.rs:7:14 - | -7 | Accuracy = Perbill, - | ^^^^^^^ not found in this scope - | -help: consider importing this struct - | -1 | use sp_arithmetic::Perbill; - | - -error[E0433]: failed to resolve: use of undeclared type `Perbill` - --> $DIR/wrong_page.rs:7:14 - | -7 | Accuracy = Perbill, - | ^^^^^^^ not found in this scope - | -help: consider importing this struct - | -1 | use sp_arithmetic::Perbill; - | - -error[E0119]: conflicting implementations of trait `std::convert::TryFrom<&[_npos::IndexAssignment]>` for type `TestSolution` - --> $DIR/wrong_page.rs:3:1 - | -3 | / generate_solution_type!( -4 | | #[pages(1)] pub struct TestSolution::< -5 | | VoterIndex = u8, -6 | | TargetIndex = u16, -7 | | Accuracy = Perbill, -8 | | >(8) -9 | | ); - | |__^ - | - = note: conflicting implementation in crate `core`: - - impl TryFrom for T - where U: Into; - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)