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

  1. Pick a non-keyword identifier (e.g. `this`, `slf`, `my_self`).
  2. If the goal is to rename a method's `self`/`&self` receiver, that is not supported — rename parameters or the type instead.
  3. 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

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


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