rust-lang/rust-analyzer · error
Only the first parameter may be renamed to self
Error message
Only the first parameter may be renamed to self
What it means
Renaming to `self` is only allowed for the first parameter of the function. rename_to_self resolves the first parameter's local and, if it differs from the local under the cursor, bails with this error. Self parameters must occupy the first position in Rust's parameter list.
Source
Thrown at crates/ide/src/rename.rs:520
}
let fn_def = match local.parent(sema.db) {
hir::ExpressionStoreOwner::Body(hir::DefWithBody::Function(func)) => func,
_ => bail!("Cannot rename local to self outside of function"),
};
if fn_def.self_param(sema.db).is_some() {
bail!("Method already has a self parameter");
}
let params = fn_def.assoc_fn_params(sema.db);
let first_param = params
.first()
.ok_or_else(|| format_err!("Cannot rename local to self unless it is a parameter"))?;
match first_param.as_local(sema.db) {
Some(plocal) => {
if plocal != local {
bail!("Only the first parameter may be renamed to self");
}
}
None => bail!("rename_to_self invoked on destructuring parameter"),
}
let assoc_item = fn_def
.as_assoc_item(sema.db)
.ok_or_else(|| format_err!("Cannot rename parameter to self for free function"))?;
let impl_ = match assoc_item.container(sema.db) {
hir::AssocItemContainer::Trait(_) => {
bail!("Cannot rename parameter to self for trait functions");
}
hir::AssocItemContainer::Impl(impl_) => impl_,
};
let first_param_ty = first_param.ty();
let impl_ty = impl_.self_ty(sema.db);
let (ty, self_param) = if impl_ty.is_reference() {
// if the impl is a ref to the type we can just match the `&T` with self directlyView on GitHub (pinned to e8f7e90aa3)
Solutions
- Target the first parameter of the function when renaming to self.
- Reorder parameters manually so the desired one is first, then rename to self.
- Rename the local to another identifier and refactor to self manually.
Example fix
// before
fn f(a: i32, b: i32) {} // rename b -> self: error
// after
fn f(b: i32, a: i32) {} // rename first param b -> self
Defensive patterns
Strategy: validation
Validate before calling
// Only the first parameter may become self; verify the cursor's local
// is the first named parameter of the enclosing fn before renaming
fn is_first_param(cursor_param_index: usize) -> bool {
cursor_param_index == 0
} Try / catch
match rename(db, pos, "self", &config) {
Ok(change) => apply(change),
Err(e) if e.to_string().contains("Only the first parameter may be renamed to self") => {
prompt_user("Only the first parameter can become self");
}
Err(e) => report(e),
} Prevention
- Enable rename-to-self only when the cursor is on the first fn parameter
- Reorder parameters manually before converting one to self
- Offer a parameter-refactor assist instead of a raw rename for later params
When it happens
Trigger: Calling rename with new_name == "self" on any local/parameter that is not the function's first parameter (e.g. the second or third fn parameter).
Common situations: Users pressing F2 on a later parameter and typing `self`, expecting rust-analyzer to reorder parameters — which it refuses to do.
Related errors
- Cannot rename local to self outside of function
- Method already has a self parameter
- Invalid name `{}`: cannot rename to a keyword
- Invalid name `{}`: {}
- rename_to_self invoked on destructuring parameter
AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03).
Data as JSON: /api/errors/4931bc74340c85c9.
Report an issue: GitHub.