rust-lang/rust-analyzer · error
Invalid name `{}`: cannot rename to `self`
Error message
Invalid name `{}`: cannot rename to `self` What it means
When renaming a non-lifetime definition, the name `self` classifies as `IdentifierKind::LowercaseSelf` and is explicitly rejected: `self` is a reserved keyword that cannot be used as an identifier for variables, functions, or other items. The error is raised in the `else` branch of `rename_reference` at crates/ide-db/src/rename.rs:387.
Source
Thrown at crates/ide-db/src/rename.rs:387
IdentifierKind::Ident => {
new_name = Name::new_lifetime(&format!("'{}", new_name.as_str()))
}
IdentifierKind::Lifetime => (),
IdentifierKind::LowercaseSelf => bail!(
"Invalid name `{}`: not a lifetime identifier",
new_name.display(sema.db, edition)
),
}
} else {
match ident_kind {
IdentifierKind::Lifetime => {
cov_mark::hit!(rename_not_an_ident_ref);
bail!("Invalid name `{}`: not an identifier", new_name.display(sema.db, edition));
}
IdentifierKind::Ident => cov_mark::hit!(rename_non_local),
IdentifierKind::Underscore => (),
IdentifierKind::LowercaseSelf => {
bail!(
"Invalid name `{}`: cannot rename to `self`",
new_name.display(sema.db, edition)
);
}
}
}
let def = convert_to_def_in_trait(sema.db, def);
let usages = def.usages(sema).all();
if !usages.is_empty() && ident_kind == IdentifierKind::Underscore {
cov_mark::hit!(rename_underscore_multiple);
bail!("Cannot rename reference to `_` as it is being referenced multiple times");
}
let mut source_change = SourceChange::default();
source_change.extend(usages.iter().map(|(file_id, references)| {
let edition = file_id.edition(sema.db);
(View on GitHub (pinned to e8f7e90aa3)
Solutions
- Pick a non-keyword identifier (e.g. `this`, `slf`, `my_self`).
- If the goal is to rename a method's `self`/`&self` receiver, that is not supported — rename parameters or the type instead.
- Client-side, block inputs matching Rust reserved keywords before calling rename.
Example fix
// before rename(local_def, "self")?; // Err: cannot rename to `self` // after rename(local_def, "this")?; // ok
Defensive patterns
Strategy: validation
Validate before calling
if new_name == "self" {
return Err(anyhow!("cannot rename to the reserved keyword `self`"));
} Type guard
fn is_keyword(s: &str) -> bool {
["self", "Self", "crate", "super", "fn", "let", "mut", "_"].contains(&s)
} Try / catch
match def.rename(sema, new_name, ...) {
Err(e) if e.to_string().contains("cannot rename to `self`") => eprintln!("choose a non-keyword name"),
other => other?,
} Prevention
- Blocklist all Rust keywords in the rename input field.
- Do not offer rename on the implicit `self` receiver parameter.
- Suggest `slf`/`this` style alternatives.
When it happens
Trigger: Renaming a local variable, parameter, function, or any non-lifetime definition with the new name `"self"`.
Common situations: User types `self` into the rename prompt for a variable inside a method, confusing the parameter `self` with a renamable name; the IDE refuses because `self` is contextual keyword syntax, not a plain binding.
Related errors
- Cannot rename builtin type
- Cannot rename a builtin attr.
- Cannot rename `Self`
- Invalid name `{0}`: cannot rename module to {0}
- Invalid name `{}`: not a lifetime identifier
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/da2bbd2c07c880d0.
Report an issue: GitHub.