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
- Resolve the impl target type and rename that type definition instead of `Self`.
- Use find-references on `Self` to locate the impl, then rename the concrete type.
- 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
- Resolve `Self` to the impl's self type and rename that definition instead.
- Disable rename UI on the `Self` token in editors.
- Teach users that `Self` is an alias, not a name.
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
- Cannot rename builtin type
- Cannot rename a builtin attr.
- Invalid name `{0}`: cannot rename module to {0}
- Invalid name `{}`: not a lifetime identifier
- Invalid name `{}`: not an identifier
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/3a596eccaf755242.
Report an issue: GitHub.