rust-lang/rust · error

return depth from strip_n_refs should be smaller than the in

Error message

return depth from strip_n_refs should be smaller than the input

What it means

mutability_errors.rs:757: while suggesting `.insert()` for an index expression, the code computes (index_refs - key_refs).checked_sub(depth).expect("return depth from strip_n_refs should be smaller than the input"). depth is the number of refs strip_n_refs actually stripped; the invariant guarantees depth <= index_refs - key_refs, so the subtraction never underflows.

Source

Thrown at compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs:757

                        let (borrowed_prefix, borrowed_index);

                        // only suggest `insert` and `entry` if index is of type K or &{n}K or *{n}K (when there is a Borrow impl for this case).
                        // We use `peel_refs` because borrow lifetimes may differ in both index and
                        // key. I.e, if they are of the same base type:
                        if index_ty.peel_refs() == key_ty.peel_refs() {
                            let (index_refs, key_refs) =
                                (count_ty_refs(index_ty), count_ty_refs(key_ty));

                            let (deref_prefix, deref_index) = if index_refs >= key_refs {
                                // index is &{n}K
                                strip_n_refs(index, index_refs - key_refs)
                                    .map(|val| ("".to_string(), val))
                                    .unwrap_or_else(|(depth, val)| {
                                        (
                                            if key_refs == 0 {
                                                "*".repeat(
                                                    (index_refs-key_refs).checked_sub(depth).expect("return depth from strip_n_refs should be smaller than the input")
                                                )
                                            } else {
                                                String::new() //if key K is a ref, autoderef finish this for us.
                                            },
                                            val,
                                        )
                                    })
                            } else {
                                // in this case the minimal ref addition works for all subcases
                                ("&".repeat(key_refs - index_refs), index)
                            };

                            self.err.multipart_suggestion(
                                format!("use `.insert()` to insert a value into a `{}`", self.ty),
                                vec![
                                    // val.insert({deref_prefix}{deref_index}, rv);
                                    (
                                        val.span.shrink_to_hi().with_hi(deref_index.span.lo()),

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. File a rustc ICE with the minimized indexing expression and the surrounding map type.
  2. Simplify the index/key expressions (remove layers of & or *) so the suggestion heuristic takes a simpler path.
  3. Bisect with cargo bisect-rustc.
  4. Try the equivalent code on stable.
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: The index-suggestion heuristic runs on an index expression whose ref-counts make strip_n_refs return a depth larger than index_refs - key_refs, violating the arithmetic invariant.

Common situations: A borrowck diagnostic ICE for a HashMap/BTreeMap indexing suggestion involving mismatched reference layers; an internal heuristic bug.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/73d32cba176eadeb. Report an issue: GitHub.