{"record":{"id":"b96ea299a0478e8f","repo":"GraphiteEditor/Graphite","slug":"tried-to-derive-a-discriminant-for-non-enum","errorCode":null,"errorMessage":"Tried to derive a discriminant for non-enum","messagePattern":"Tried to derive a discriminant for non-enum","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/discriminant.rs","lineNumber":11,"sourceCode":"use crate::helpers::call_site_ident;\nuse proc_macro2::{Ident, Span, TokenStream};\nuse syn::spanned::Spanned;\nuse syn::{Attribute, Data, DeriveInput, Field, Fields, ItemEnum, MetaList};\n\npub fn derive_discriminant_impl(input_item: TokenStream) -> syn::Result<TokenStream> {\n\tlet input = syn::parse2::<DeriveInput>(input_item).unwrap();\n\n\tlet mut data = match input.data {\n\t\tData::Enum(data) => data,\n\t\t_ => return Err(syn::Error::new(Span::call_site(), \"Tried to derive a discriminant for non-enum\")),\n\t};\n\n\tlet mut is_sub_discriminant = vec![];\n\tlet mut attr_errs = vec![];\n\n\tfor var in &mut data.variants {\n\t\tif var.attrs.iter().any(|a| a.path().is_ident(\"sub_discriminant\")) {\n\t\t\tmatch var.fields.len() {\n\t\t\t\t1 => {\n\t\t\t\t\tlet Field { ty, .. } = var.fields.iter_mut().next().unwrap();\n\t\t\t\t\t*ty = syn::parse_quote! {\n\t\t\t\t\t\t<#ty as ToDiscriminant>::Discriminant\n\t\t\t\t\t};\n\t\t\t\t\tis_sub_discriminant.push(true);\n\t\t\t\t}\n\t\t\t\tn => unimplemented!(\"#[sub_discriminant] on variants with {n} fields is not supported (for now)\"),\n\t\t\t}\n\t\t} else {","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/discriminant.rs#L1-L29","documentation":"The Discriminant derive (proc-macros/src/discriminant.rs, generating ToDiscriminant impls with #[sub_discriminant] support) rejects any DeriveInput whose data is not Data::Enum. On a struct or union it returns this spanned compile-time error before generating anything.","triggerScenarios":"#[derive(Discriminant)] on a struct or union; routing the derive entry point at a non-enum item.","commonSituations":"Restructuring a discriminated enum into a struct during refactoring; applying the wrong derive from IDE completion to a struct type.","solutions":["Move the Discriminant derive onto an enum","Restructure the type as an enum (optionally with single-field #[sub_discriminant] variants)","Hand-implement ToDiscriminant if the struct must stay a struct"],"exampleFix":"// before\n#[derive(Discriminant)]\nstruct MyStruct;\n\n// after\n#[derive(Discriminant)]\nenum MyEnum {\n\tA,\n\tB,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Discriminant is enum-only — verify the item is an enum before deriving","When collapsing an enum into a struct, remove enum-only derives in the same change","Compile right after derive edits to catch misplacement early"],"tags":["proc-macro","rust","derive","compile-time"],"backgroundTag":"derive-on-non-enum","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}