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

  1. Manually rename the deprecated fields in Cargo.toml before running cargo fix (crate_type -> crate-type, proc_macro -> proc-macro).
  2. Re-run cargo fix — if it was a transient issue it won't recur.
  3. 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

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.