rust-lang/rust-analyzer · error

Cannot rename `Self`

Error message

Cannot rename `Self`

What it means

`Definition::rename` refuses to rename `Definition::SelfType`. `Self` is a keyword-like alias for the implementing type, not a real name in scope; rewriting its occurrences would require changing the underlying type's name instead. The library bails rather than silently doing nothing or producing wrong edits.

Source

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

                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.
    pub fn range_for_rename(self, sema: &Semantics<'_, RootDatabase>) -> Option<FileRange> {
        let syn_ctx_is_root = |(range, ctx): (_, SyntaxContext)| ctx.is_root().then_some(range);

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Resolve the impl target type and rename that type definition instead of `Self`.
  2. Use find-references on `Self` to locate the impl, then rename the concrete type.
  3. Filter out `Definition::SelfType(_)` in the caller before dispatching to rename.

Example fix

// before
// rename `Self` directly -> error
// after: rename the implementing type
let ty = impl_self_ty(sema); // resolve SelfType to Foo
if let Some(adt_def) = ty.as_adt() {
    Definition::from(adt_def).rename(sema, "NewFoo", ...)?;
}
Defensive patterns

Strategy: validation

Validate before calling

if matches!(def, Definition::SelfType(_)) {
    return Err(anyhow!("rename the implementing type instead of `Self`"));
}

Type guard

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

Try / catch

match def.rename(sema, new_name, ...) {
    Err(e) if e.to_string().contains("Cannot rename `Self`") => redirect_to_impl_target_rename(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling `Definition::rename` (crates/ide-db/src/rename.rs:119) on a definition resolved to `SelfType`, e.g. placing the cursor on `Self` in `impl Foo { fn new() -> Self }` and renaming.

Common situations: Developer invokes rename on `Self` inside an impl block or trait definition and the IDE returns this error instead of a workspace edit.

Related errors


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