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

type_alias and no_type_alias are mutually exclusive

Error message

type_alias and no_type_alias are mutually exclusive

What it means

The #[auto_type] attribute accepts both `type_alias` and `no_type_alias` flags to force the generated type alias on or off. Specifying both is contradictory — the macro cannot honor both — so auto_type_impl fails expansion at the settings-resolution match arm.

Solutions

  1. Remove one of the two conflicting flags, keeping only `type_alias` or `no_type_alias`.
  2. If relying on the default, remove both flags entirely.
  3. If a wrapper macro injects one flag, stop passing the other manually.

Example fix

// before
#[auto_type(type_alias, no_type_alias)]
fn f() -> _ { 1 }
// after
#[auto_type(type_alias)]
fn f() -> _ { 1 }
Defensive patterns

Strategy: validation

Validate before calling

// Attribute sanity check before applying:
let opts = ["type_alias", "no_type_alias"];
let chosen: Vec<_> = opts.iter().filter(|o| attr_contains(o)).collect();
assert!(chosen.len() <= 1, "pick only one alias flag");

Prevention

When it happens

Trigger: `#[auto_type(type_alias, no_type_alias)]` on a function, typically by stacking conflicting helper attributes or copy-pasting attribute options.

Common situations: Users migrating between macro versions where the default changed and they add the opposite flag 'just in case'; or combining wrapper macros that each inject one of the flags.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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

Appendix: source

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

    let inferrer_settings = InferrerSettings {
        dsl_path: settings_input
            .dsl_path
            .unwrap_or(derive_settings.default_dsl_path),
        method_types_case: derive_settings.default_method_type_case,
        function_types_case: derive_settings.default_function_type_case,
    };

    let function_name = &input_function.sig.ident;
    let type_alias = match (
        settings_input.type_alias.is_present(),
        settings_input.no_type_alias.is_present(),
        derive_settings.default_generate_type_alias,
    ) {
        (false, false, b) => b,
        (true, false, _) => true,
        (false, true, _) => false,
        (true, true, _) => {
            return Err(syn::Error::new(
                Span::mixed_site(),
                "type_alias and no_type_alias are mutually exclusive",
            )
            .into());
        }
    };
    let type_alias: Option<syn::Ident> = match (
        type_alias,
        settings_input.type_name,
        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

View on GitHub (pinned to 6fa6ed01b2)