Skip to content
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
13 changes: 9 additions & 4 deletions src/substruct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,18 @@ impl<'a> Emitter<'a> {
let name = &substruct.ident;
let (impl_generics, ty_generics, where_clause) = substruct.generics.split_for_impl();

let mut attrs = Vec::<syn::Attribute>::new();
let method = syn::Ident::new(
&format!("into_{}", self.input.ident.to_string().to_snake_case()),
Span::call_site(),
);
let doc: syn::Attribute = syn::parse_quote!(
attrs.push(syn::parse_quote!(
#[doc = concat!("Convert `self` into a [`", stringify!(#original), "`].")]
);
));

let fields = match &self.input.data {
syn::Data::Enum(_) => panic!("Attempted to emit conversions for an enum"),
// Emitting conversions for an enum doesn't make sense
// Emitting conversions for a union doesn't make sense
syn::Data::Union(_) => return,
// Unit structs have no fields and so they have no conversions
syn::Data::Struct(data) if matches!(data.fields, syn::Fields::Unit) => return,
Expand Down Expand Up @@ -238,11 +239,15 @@ impl<'a> Emitter<'a> {
.collect();
let exc: Vec<_> = excluded.keys().collect();

if args.len() > 5 {
attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)]))
}

self.tokens.extend(quote::quote! {
impl #impl_generics #name #ty_generics
#where_clause
{
#doc
#( #attrs )*
pub fn #method(self, #( #args: #types, )*) -> #original #ty_generics {
#original {
#( #inc_dst: self.#inc_src, )*
Expand Down
4 changes: 4 additions & 0 deletions tests/trybuild.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#[test]
fn trybuild() {
// This still compiles the crate normally, it just means that we also get
// clippy warnings as well.
std::env::set_var("RUSTC_WORKSPACE_WRAPPER", "clippy-driver");

let t = trybuild::TestCases::new();
t.compile_fail("tests/ui/fail/*.rs");
t.pass("tests/ui/pass/*.rs");
Expand Down
10 changes: 6 additions & 4 deletions tests/ui/fail/union-invalid-field.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ error[E0609]: no field `y` on type `C`
|
help: a field with a similar name exists
|
15 | value.x = 1;
| ~
15 - value.y = 1;
15 + value.x = 1;
|

error[E0609]: no field `z` on type `C`
--> tests/ui/fail/union-invalid-field.rs:16:11
Expand All @@ -17,5 +18,6 @@ error[E0609]: no field `z` on type `C`
|
help: a field with a similar name exists
|
16 | value.x = 1;
| ~
16 - value.z = 1;
16 + value.x = 1;
|
29 changes: 29 additions & 0 deletions tests/ui/pass/large-struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#![deny(clippy::too_many_arguments)]
#![allow(dead_code)]

use substruct::substruct;

#[substruct(A, B)]
struct Large {
#[substruct(B)]
pub v0: u32,
#[substruct(B)]
pub v1: u32,
#[substruct(B)]
pub v2: u32,
#[substruct(B)]
pub v3: u32,
#[substruct(B)]
pub v4: u32,
#[substruct(B)]
pub v5: u32,
#[substruct(B)]
pub v6: u32,
#[substruct(B)]
pub v7: u32,
#[substruct(B)]
pub v8: u32,
pub v9: u32,
}

fn main() {}
Loading