{"record":{"id":"8758e1b1c0e525fc","repo":"tracel-ai/burn","slug":"generic-type-ident-should-not-be-used-on-both","errorCode":null,"errorMessage":"Generic type `{ident}` should not be used on both a module field and a skipped field. Consider removing `#[module(skip)]` or using a different type for one of the fields.","messagePattern":"Generic type `(.+?)` should not be used on both a module field and a skipped field\\. Consider removing `#\\[module\\(skip\\)\\]` or using a different type for one of the fields\\.","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/burn-derive/src/module/codegen_struct.rs","lineNumber":349,"sourceCode":"                let field_type = parse_module_field_type(field, generics)?;\n                if field_type.is_module {\n                    module_generics.extend(field_type.generic_idents.iter().cloned());\n                } else if matches!(field_type.attr, Some(ModuleFieldAttribute::Skip)) {\n                    skip_generics.extend(field_type.generic_idents.iter().cloned());\n                }\n                fields.push(ModuleField::new(field.clone(), field_type));\n            }\n        }\n        syn::Data::Enum(_) => panic!(\"Only struct can be derived\"),\n        syn::Data::Union(_) => panic!(\"Only struct can be derived\"),\n    };\n\n    for ident in module_generics.intersection(&skip_generics) {\n        if let Some(param) = ast.generics.params.iter().find_map(|p| match p {\n            syn::GenericParam::Type(tp) if tp.ident == *ident => Some(tp),\n            _ => None,\n        }) {\n            return Err(syn::Error::new(\n                param.ident.span(),\n                format!(\n                    \"Generic type `{ident}` should not be used on both a module field and a skipped field. \\\n                     Consider removing `#[module(skip)]` or using a different type for one of the fields.\",\n                ),\n            ));\n        }\n    }\n\n    Ok(fields)\n}\n\npub(crate) fn parse_module_field_type(\n    field: &Field,\n    generics: &mut ModuleGenerics,\n) -> syn::Result<ModuleFieldType> {\n    let mut field_type = ModuleFieldType::default();\n","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-derive/src/module/codegen_struct.rs#L331-L367","documentation":"burn-derive's #[Module] macro rejects a struct whose generics are used both on a module field (a field that generates module code) and on a field marked #[module(skip)]. Skipped fields are excluded from codegen, so if the same generic type parameter appears in both, the generated code would be inconsistent (the generic would be required for the skipped field but not tracked as a module parameter), so the proc macro fails at compile time pointing at the generic parameter.","triggerScenarios":"Compiling a #[derive(Module)] struct where one type generic parameter appears on a regular module field (e.g. `inner: Linear<B>`) and also on a `#[module(skip)]` field (e.g. `#[module(skip)] extra: Option<T>`) with the same ident.","commonSituations":"Reusing a backend generic `B` or model generic `T` on both a real submodule and a skipped metadata/config field; copy-pasting fields and adding #[module(skip)] to one without renaming its generic; migrating structs to skip serialization of some fields.","solutions":["Remove `#[module(skip)]` from the offending field so it participates in module codegen like the other field using the generic.","Change the skipped field to a different (concrete or distinct generic) type so the two fields do not share the same generic parameter.","Make the skipped field generic over a different type parameter (add a new generic) or hardcode its type.","Store the skipped data outside the Module struct (e.g. in a wrapper struct holding the Module plus the extra field)."],"exampleFix":"// before\n#[derive(Module)]\nstruct Net<B: Backend> {\n    inner: Linear<B>,\n    #[module(skip)]\n    aux: Aux<B>, // same generic on skipped field: compile error\n}\n// after\n#[derive(Module)]\nstruct Net<B: Backend> {\n    inner: Linear<B>,\n    #[module(skip)]\n    aux: Aux<f32>, // or drop #[module(skip)] from aux\n}","handlingStrategy":"validation","validationCode":"// Compile-time: audit #[derive(Module)] structs so no generic ident appears\n// both on a normal module field and on a #[module(skip)] field.\n// e.g. `cargo check` fails at the generic param span; fix before building.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never reuse the same generic parameter on a #[module(skip)] field and a module field.","Give skipped metadata/config fields concrete types (e.g. usize, String) instead of the backend/model generic.","When adding #[module(skip)], rename the field's generic or remove the attribute.","Run `cargo check` early after editing Module derives; this error is reported at compile time with the offending generic named."],"tags":["rust","proc-macro","burn-derive","compile-error"],"backgroundTag":"conflicting-generic-parameter","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}