{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreicjqt3xe4ezdoznwz5fottidfb3pgq5u7rdhwvh7hqhkypnigs5xq",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mjljlt4yi7z2"
  },
  "path": "/t/code-bloat-caused-by-lack-of-nounwind-attr-on-drop-in-place/24173#post_6",
  "publishedAt": "2026-04-16T02:32:03.000Z",
  "site": "https://internals.rust-lang.org",
  "textContent": "I think it's because rustc emits `invoke` in the IR, which implies unwinding. LLVM's pass for adding nounwind uses:\n\n\n    /// Helper for NoUnwind inference predicate InstrBreaksAttribute.\n    static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {\n      if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))\n        return false;\n      if (const auto *CI = dyn_cast<CallInst>(&I)) {\n        if (Function *Callee = CI->getCalledFunction()) {\n          // I is a may-throw call to a function inside our SCC. This doesn't\n          // invalidate our current working assumption that the SCC is no-throw; we\n          // just have to scan that other function.\n          if (SCCNodes.contains(Callee))\n            return false;\n        }\n      }\n      return true;\n    }\n\n\nwhich only allows `call` (`CallInst`).\n\nThis check is relevant for recursive functions. I happen to have `Arc` that is a recursive type, so `Arc::drop_slow` calls `drop_in_place` which may call `Arc::drop_slow` again. In this case `rustc` assuming that `drop_slow` may unwind makes it emit unwind-requiring `invoke` instruction when called recursively, which then cements its status as an unwinding function.\n\nI don't know if LLVM checking for `CallInst` is intentional, or was it meant to be `CallBase` (which would include `InstInvoke`)",
  "title": "Code bloat caused by lack of nounwind attr on `drop_in_place`"
}