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

type_name and type_case are mutually exclusive

Error message

type_name and type_case are mutually exclusive

What it means

`type_name` (an explicit identifier for the generated type alias) and `type_case` (which naming convention/case to apply to the function name) are two ways to determine the alias's name and are mutually exclusive; specifying both is ambiguous, so auto_type_impl returns this compile error from the attribute-option match arm.

Solutions

  1. Keep only `type_name` if you want a fixed alias name (apply casing yourself).
  2. Keep only `type_case` if you want the alias derived from the function name in that case.
  3. Remove both to use the default naming.

Example fix

// before
#[auto_type(type_alias, type_name = "MyOut", type_case = "PascalCase")]
fn f() -> _ { 1 }
// after
#[auto_type(type_alias, type_name = "MyOut")]
fn f() -> _ { 1 }
Defensive patterns

Strategy: validation

Validate before calling

let has_type_name = attr_contains("type_name");
let has_type_case = attr_contains("type_case");
assert!(!(has_type_name && has_type_case), "use type_name or type_case, not both");

Prevention

When it happens

Trigger: `#[auto_type(type_alias, type_name = "MyAlias", type_case = "PascalCase")]` — both Some(ident) and Some(case) reaching the (_, Some(_), Some(type_case)) arm.

Common situations: Users who set type_name for explicit control and later add type_case to adjust casing, not realizing type_case only applies when type_name is absent; also examples copy-pasted from older docs.

Related errors


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

Appendix: source

Thrown at dsl_auto_type/src/auto_type/mod.rs:96

        settings_input.type_case,
    ) {
        (false, None, None) => None,
        (true, None, None) => {
            // By default be consistent with call expressions, for when other will refer
            // this query fragment in another auto_type function
            Some(
                inferrer_settings
                    .function_types_case
                    .ident_with_case(function_name),
            )
        }
        (_, Some(ident), None) => Some(ident),
        (_, None, Some(case)) => {
            let case = Case::from_str(case.as_str(), case.span())?;
            Some(case.ident_with_case(function_name))
        }
        (_, Some(_), Some(type_case)) => {
            return Err(syn::Error::new(
                type_case.span(),
                "type_name and type_case are mutually exclusive",
            )
            .into());
        }
    };

    let last_statement = input_function.block.stmts.last().ok_or_else(|| {
        syn::Error::new(
            input_function.span(),
            "function body should not be empty for auto_type",
        )
    })?;
    let mut errors = Vec::new();
    let return_type = match input_function.sig.output {
        syn::ReturnType::Type(_, return_type) => {
            let return_expression = match last_statement {
                syn::Stmt::Expr(expr, None) => expr,

View on GitHub (pinned to 6fa6ed01b2)