rust-lang/rust-analyzer · error

Cannot rename reference to `_` as it is being referenced mul

Error message

Cannot rename reference to `_` as it is being referenced multiple times

What it means

`rename_reference` refuses a rename to `_` when the definition has existing usages: `_` bindings drop values immediately, so renaming a multiply-referenced binding to `_` would change semantics (each use would move/drop differently). rust_analyzer bails with "Cannot rename reference to `_` as it is being referenced multiple times" and marks the path with `cov_mark::hit!(rename_underscore_multiple)`.

Source

Thrown at crates/ide-db/src/rename.rs:400

                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);
        (
            file_id.file_id(sema.db),
            source_edit_from_references(sema.db, references, def, &new_name, edition),
        )
    }));

    if let Definition::Field(field) = def {
        rename_field_constructors(sema, field, &new_name, &mut source_change, config);
    }

    if rename_definition == RenameDefinition::Yes {
        // This needs to come after the references edits, because we change the annotation of existing edits
        // if a conflict is detected.
        let (file_id, edit) =

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Prefix the name with an underscore instead (e.g. `_x`) — this silences unused warnings while keeping the binding usable.
  2. Remove the usages first if the variable is genuinely no longer needed, then rename to `_`.
  3. Refactor the code so the value is consumed exactly once if `_` is truly desired.

Example fix

// before
rename(local_def, "_")?; // Err: referenced multiple times
// after
rename(local_def, "_x")?; // ok: underscore-prefixed keeps the binding
Defensive patterns

Strategy: validation

Validate before calling

if new_name == "_" && !def.usages(sema).all().is_empty() {
    return Err(anyhow!("rename to `_` requires a definition with no other usages; use `_name` instead"));
}

Type guard

fn can_rename_to_underscore(def: &Definition, sema: &Semantics<'_, RootDatabase>) -> bool {
    def.usages(sema).all().is_empty()
}

Try / catch

match def.rename(sema, "_", ...) {
    Err(e) if e.to_string().contains("referenced multiple times") => suggest_underscore_prefix(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling rename with new name `"_"` (classified `IdentifierKind::Underscore`) on a definition where `def.usages(sema).all()` is non-empty, i.e. the name is referenced at least once elsewhere, at crates/ide-db/src/rename.rs:400.

Common situations: User tries to silence an unused-variable warning by renaming a still-used variable to `_`; the IDE blocks it because `_` cannot hold multiple references meaningfully.

Related errors


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