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)