rust-lang/rust-analyzer · error

Cannot rename a builtin attr.

Error message

Cannot rename a builtin attr.

What it means

`Definition::rename` rejects renaming `Definition::BuiltinAttr` — attributes the compiler interprets natively (e.g. `#[derive]`, `#[test]`, `#[inline]`). These names are fixed by rustc; renaming them would break the code, so rust_analyzer bails early with this message.

Source

Thrown at crates/ide-db/src/rename.rs:117

            // Then bail if non-local
            if !krate.origin(sema.db).is_local() {
                bail!("Cannot rename a non-local definition")
            }
            krate.edition(sema.db)
        } else {
            Edition::LATEST
        };

        match *self {
            Definition::Module(module) => rename_mod(sema, module, new_name),
            Definition::ToolModule(_) => {
                bail!("Cannot rename a tool module")
            }
            Definition::BuiltinType(_) => {
                bail!("Cannot rename builtin type")
            }
            Definition::BuiltinAttr(_) => {
                bail!("Cannot rename a builtin attr.")
            }
            Definition::SelfType(_) => bail!("Cannot rename `Self`"),
            Definition::Macro(mac) => rename_reference(
                sema,
                Definition::Macro(mac),
                new_name,
                rename_definition,
                edition,
                config,
            ),
            def => rename_reference(sema, def, new_name, rename_definition, edition, config),
        }
    }

    /// Textual range of the identifier which will change when renaming this
    /// `Definition`. Note that builtin types can't be
    /// renamed and extern crate names will report its range, though a rename will introduce
    /// an alias instead.

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Do not rename builtin attributes; they are part of the language.
  2. If a custom attribute with the same name is wanted, define your own proc-macro attribute and rename that instead.
  3. Guard callers with a check for `Definition::BuiltinAttr(_)` before calling rename.
Defensive patterns

Strategy: validation

Validate before calling

if matches!(def, Definition::BuiltinAttr(_)) {
    return Err(anyhow!("builtin attributes like #[derive] cannot be renamed"));
}

Type guard

fn is_builtin_attr(def: &Definition) -> bool {
    matches!(def, Definition::BuiltinAttr(_))
}

Try / catch

match def.rename(sema, new_name, ...) {
    Err(e) if e.to_string().contains("builtin attr") => show_hint("built-in attributes are fixed by rustc"),
    other => other?,
}

Prevention

When it happens

Trigger: Invoking `Definition::rename` (crates/ide-db/src/rename.rs:117) when the resolved definition is a builtin attribute, typically from a rename request on the `derive` in `#[derive(Debug)]`.

Common situations: A user tries to rename `derive`, `test`, `inline`, or similar built-in attribute names in their editor and gets this error back as an LSP error response.

Related errors


AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03). Data as JSON: /api/errors/8a21b92f3331af8c. Report an issue: GitHub.