rust-lang/cargo · warning
returned early
Error message
returned early
What it means
This panic is in rename_table(), a helper used by cargo fix to rename deprecated manifest fields during edition migration (e.g., crate_type -> crate-type, proc_macro -> proc-macro). On line 552 it checks parent.key(old).cloned() and returns 0 early if None. On line 556 it calls parent.remove(old).expect("returned early") — since the key existed at line 552, remove should return the value.
Source
Thrown at src/ops/cargo_fix/mod.rs:556
{
fixes += rename_target_fields_2024(target);
}
fixes
}
fn rename_target_fields_2024(target: &mut dyn toml_edit::TableLike) -> usize {
let mut fixes = 0;
fixes += rename_table(target, "crate_type", "crate-type");
fixes += rename_table(target, "proc_macro", "proc-macro");
fixes
}
fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> usize {
let Some(old_key) = parent.key(old).cloned() else {
return 0;
};
let project = parent.remove(old).expect("returned early");
if !parent.contains_key(new) {
parent.insert(new, project);
let mut new_key = parent.key_mut(new).expect("just inserted");
*new_key.dotted_decor_mut() = old_key.dotted_decor().clone();
*new_key.leaf_decor_mut() = old_key.leaf_decor().clone();
}
1
}
fn check_resolver_change<'gctx>(
ws: &Workspace<'gctx>,
target_data: &mut RustcTargetData<'gctx>,
opts: &FixOptions,
) -> CargoResult<()> {
let root = ws.root_maybe();
match root {
MaybePackage::Package(root_pkg) => {
if root_pkg.manifest().resolve_behavior().is_some() {View on GitHub (pinned to 0e07a15537)
Solutions
- Manually rename the deprecated fields in Cargo.toml before running cargo fix (crate_type -> crate-type, proc_macro -> proc-macro).
- Re-run cargo fix — if it was a transient issue it won't recur.
- Update cargo to the latest version to get the newest edition-migration logic.
Example fix
# before (deprecated field name in Cargo.toml) [lib] crate_type = ["cdylib"] # after (rename to kebab-case) [lib] crate-type = ["cdylib"]
Defensive patterns
Strategy: validation
Validate before calling
// Before cargo fix --edition, rename deprecated fields manually
// Check for crate_type / proc_macro in Cargo.toml
let content = std::fs::read_to_string("Cargo.toml")?;
for deprecated in ["crate_type", "proc_macro"] {
if content.contains(deprecated) {
eprintln!("warning: found deprecated field `{}`; rename to `{}`", deprecated, deprecated.replace('_', "-"));
}
} Prevention
- Manually rename deprecated manifest fields before running cargo fix --edition.
- Always use kebab-case for Cargo.toml field names.
- Run cargo check on manifests before edition migration.
When it happens
Trigger: Migrating a Cargo.toml with deprecated field names (crate_type, proc_macro) where the key exists for the .key() check but is removed by the time .remove() is called. This requires concurrent mutation of the TOML document between the two calls — effectively impossible in single-threaded cargo fix execution.
Common situations: Running cargo fix --edition on a manifest with crate_type or proc_macro fields; essentially unreachable unless there is a re-entrant edit to the same toml_edit document or a bug in toml_edit's key/remove consistency.
Related errors
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/62bee8bc1630b241.json.
Report an issue: GitHub.