{"record":{"id":"bad8b9538fe43440","repo":"rust-lang/rust-analyzer","slug":"invalid-name-cannot-rename-to-a-keyword","errorCode":null,"errorMessage":"Invalid name `{}`: cannot rename to a keyword","messagePattern":"Invalid name `(.+?)`: cannot rename to a keyword","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ide-db/src/rename.rs","lineNumber":829,"sourceCode":"    Underscore,\n    LowercaseSelf,\n}\n\nimpl IdentifierKind {\n    pub fn classify(edition: Edition, new_name: &str) -> Result<(Name, IdentifierKind)> {\n        match parser::LexedStr::single_token(edition, new_name) {\n            Some(res) => match res {\n                (SyntaxKind::IDENT, _) => Ok((Name::new_root(new_name), IdentifierKind::Ident)),\n                (T![_], _) => {\n                    Ok((Name::new_symbol_root(sym::underscore), IdentifierKind::Underscore))\n                }\n                (SyntaxKind::LIFETIME_IDENT, _) if new_name != \"'static\" && new_name != \"'_\" => {\n                    Ok((Name::new_lifetime(new_name), IdentifierKind::Lifetime))\n                }\n                _ if SyntaxKind::from_keyword(new_name, edition).is_some() => match new_name {\n                    \"self\" => Ok((Name::new_root(new_name), IdentifierKind::LowercaseSelf)),\n                    \"crate\" | \"super\" | \"Self\" => {\n                        bail!(\"Invalid name `{}`: cannot rename to a keyword\", new_name)\n                    }\n                    _ => Ok((Name::new_root(new_name), IdentifierKind::Ident)),\n                },\n                (_, Some(syntax_error)) => bail!(\"Invalid name `{}`: {}\", new_name, syntax_error),\n                (_, None) => bail!(\"Invalid name `{}`: not an identifier\", new_name),\n            },\n            None => bail!(\"Invalid name `{}`: not an identifier\", new_name),\n        }\n    }\n}\n","sourceCodeStart":811,"sourceCodeEnd":840,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/ide-db/src/rename.rs#L811-L840","documentation":"`IdentifierKind::classify` (crates/ide-db/src/rename.rs:829) validates a proposed new name by lexing it as a single Rust token. If the name lexes to a keyword, only a small set is permitted: `self` (LowercaseSelf) and path keywords that become valid idents via raw-name representation (`_ => Ok(...Ident)`). The reserved path keywords `crate`, `super`, and `Self` can never be binding names, so the method bails with 'cannot rename to a keyword'.","triggerScenarios":"Calling rename (textDocument/rename) with newName equal to `crate`, `super`, or `Self` on any item; the name passes the single-token check, matches `SyntaxKind::from_keyword`, and hits the explicit bail arm at rename.rs:829.","commonSituations":"User (or an LLM/refactoring script driving the LSP) types `Self` intending a struct-like alias, or `super`/`crate` intending a path segment rename — none of which are legal identifier positions in Rust.","solutions":["Choose a legal identifier that is not one of `crate`, `super`, or `Self` (e.g. `self_param` instead of `self`-like keywords).","If you wanted path-component semantics, rename the module/item to a normal name and update `use` paths instead.","For a type alias intent, keep the original name and add `type SelfAlias = ...;` rather than renaming."],"exampleFix":"// before: LSP rename request\n{ \"newName\": \"Self\" }\n\n// after\n{ \"newName\": \"SelfType\" }","handlingStrategy":"validation","validationCode":"const RESERVED: [&str; 3] = [\"crate\", \"super\", \"Self\"];\nfn validate_rename_name(new_name: &str) -> Result<(), String> {\n    if RESERVED.contains(&new_name) {\n        return Err(format!(\"cannot rename to keyword `{new_name}`\"));\n    }\n    Ok(())\n}","typeGuard":"fn is_legal_rust_ident(s: &str) -> bool {\n    let mut cs = s.chars();\n    matches!(cs.next(), Some(c) if c.is_alphabetic() || c == '_')\n        && cs.all(|c| c.is_alphanumeric() || c == '_')\n        && !matches!(s, \"crate\" | \"super\" | \"Self\")\n}","tryCatchPattern":null,"preventionTips":["Validate candidate names against the reserved list crate/super/Self before sending rename.","Remember `self` and raw keywords (r#fn) are allowed but crate/super/Self never are.","Use rustc's own keyword list when generating names programmatically.","Show the error message text to users in editor UIs; it names the offending keyword."],"tags":["rust-analyzer","rename","keyword","validation"],"backgroundTag":"invalid-identifier-name","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}