diesel-rs/diesel · error · syn::Error

auto_type: unexpected double type ascription

Error message

auto_type: unexpected double type ascription

What it means

dsl_auto_type walks each let-pattern to collect variable/type mappings. A pattern like `let x: T: U` (or a type-ascribed pattern that itself contains another type-ascribed subpattern) yields two type ascriptions for the same binding; since the macro can only pick one, it fails compilation with this error.

Solutions

  1. Remove the redundant inner type ascription, keeping only one per binding.
  2. Keep only the outer tuple-level ascription: `let (a, b): (i32, String) = ...;` instead of annotating elements again.
  3. If this comes from a generated macro, fix the generator to emit a single ascription at one level.

Example fix

// before
let (a: i32): (i32,) = (1,);
// after
let (a,): (i32,) = (1,);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure each binding has at most one type ascription level:
// pattern_writes_type(pat) == false || outer_ascription.is_none()

Prevention

When it happens

Trigger: Writing a let statement whose pattern applies type ascription twice, e.g. `let (a: i32): (i32,) = ...` or nested `x: T` patterns under an already-ascribed tuple pattern while processing `Pat::Type` recursively with an existing ascription.

Common situations: Rare hand-written double annotations, often from mechanically editing `let x: T = ...` into a tuple pattern or from macros generating nested ascribed patterns; also from refactoring tuple destructuring where the outer tuple and inner element are both annotated.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07). Data as JSON: /api/errors/e8054b74d32b4291. Report an issue: GitHub.

Appendix: source

Thrown at dsl_auto_type/src/auto_type/local_variables_map.rs:48

}

impl<'a> LocalVariablesMap<'a, '_> {
    pub(crate) fn process_pat(
        &mut self,
        pat: &'a syn::Pat,
        type_ascription: Option<&'a Type>,
        local_init_expression: Option<&'a syn::Expr>,
    ) -> Result<(), syn::Error> {
        // Either the let statement hints the type or we have to infer it
        // Either the let statement is a simple assignment or a destructuring assignment
        match pat {
            syn::Pat::Type(pat_type) => {
                self.process_pat(
                    &pat_type.pat,
                    Some(match type_ascription {
                        None => &pat_type.ty,
                        Some(type_ascription) => {
                            return Err(syn::Error::new(
                                type_ascription.span(),
                                "auto_type: unexpected double type ascription",
                            ));
                        }
                    }),
                    local_init_expression,
                )?;
            }
            syn::Pat::Ident(pat_ident) => {
                self.inner.map.insert(
                    &pat_ident.ident,
                    match (type_ascription, local_init_expression) {
                        (opt_type_ascription, Some(expr)) => {
                            let inferrer = self.inferrer();
                            LetStatementInferredType {
                                type_: inferrer.infer_expression_type(expr, opt_type_ascription),
                                errors: inferrer.into_errors(),
                            }

View on GitHub (pinned to 6fa6ed01b2)