embassy-rs/embassy · error

could not parse mul/div. enum=

Error message

could not parse mul/div. enum={} variant={}

What it means

When generating RCC mul/div code, build.rs parses each clock enum variant name as a number (mul/div factor, e.g. DIV2, MUL4) with `parse_num`. If a variant name can't be interpreted as a number, the script panics naming the enum and variant. It means chip metadata contains a multiplier/divider enum variant outside the expected naming convention.

Solutions

  1. Check the named enum/variant in embassy-stm32's metadata and rename/normalize it to the expected numeric convention (e.g. DIV4, MUL8).
  2. Extend build.rs's `parse_num` to handle the new naming pattern.
  3. Regenerate metadata from the upstream source expected by this embassy-stm32 version.

Example fix

// metadata enum variant "DIV_2_POW_4" -> unparsable
// before: variant named DIV_2_POW_4
// after: rename metadata variant to DIV16 so parse_num succeeds
Defensive patterns

Strategy: fallback

Try / catch

// build-time only; extend parse_num to cover new naming
fn parse_num(name: &str) -> Result<Num, ()> { /* handle DIVx/MULx and new forms */ }

Prevention

When it happens

Trigger: Processing a clock enum whose variants aren't numeric-style names (e.g. an RCC PLL divider enum with symbolic variant names) while generating mul/div lookup tables.

Common situations: New STM32 families with unusual prescaler naming; metadata regenerated from different SVDs introducing nonstandard variant names.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/865f73e79995a590. Report an issue: GitHub.

Appendix: source

Thrown at embassy-stm32/build.rs:2429

                        };
                        return Ok(f.simplify());
                    }
                }
                if n.contains("Disabled") {
                    return Ok(Frac { num: 1, denom: 0 });
                }
                Err(())
            }

            if (kind == "rcc" && is_rcc_name(e.name)) || ((kind == "adccommon" || kind == "adc") && is_adc_name(e.name))
            {
                let kind = format_ident!("{}", kind);
                let enum_name = format_ident!("{}", e.name);
                let mut nums = Vec::new();
                let mut denoms = Vec::new();
                for v in e.variants {
                    let Ok(val) = parse_num(v.name) else {
                        panic!("could not parse mul/div. enum={} variant={}", e.name, v.name)
                    };
                    let variant_name = format_ident!("{}", v.name);
                    let variant = quote!(crate::pac::#kind::vals::#enum_name::#variant_name);
                    let num = val.num;
                    let denom = val.denom;
                    nums.push(quote!(#variant => #num,));
                    denoms.push(quote!(#variant => #denom,));
                }

                g.extend(quote! {
                    impl crate::time::Prescaler for crate::pac::#kind::vals::#enum_name {
                        fn num(&self) -> u32 {
                            match *self {
                                #(#nums)*
                                #[allow(unreachable_patterns)]
                                _ => unreachable!(),
                            }
                        }

View on GitHub (pinned to 463a07b963)