{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigmdgdcfj2qnbxeo5lnp7vetykff7jgospzevz7qztnqzrn6f2ogu",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mgxrle5in7v2"
  },
  "path": "/t/could-borrow-checking-with-origins-unblock-sound-specialization/24079#post_3",
  "publishedAt": "2026-03-13T19:14:32.000Z",
  "site": "https://internals.rust-lang.org",
  "textContent": "You're right, I assumed that that having this infromation in codegen would unlock more optimizations. The idea was to use origin information at concrete call sites for lifetimes specialization. At a concrete call site like `(&s, &s).merge()`, the solver would use origin information to determine that both references share the same origin and pick the specialized impl. This is a type-checking time decision, before codegen runs.\n\nIn general one could imagine simpler case when codegen doesn't have knowledge of origins:\n\n  1. Solver sees `(&s, &s).merge()` at a concrete call site\n  2. Solver determines the origins are the same\n  3. Solver picks the specialized impl\n  4. Solver writes into MIR: \"call this specific function\" (the specialized one)\n  5. Lifetimes get erased\n  6. Codegen sees a direct function call and compiles it\n\n\n\nEach call site gets its own resolution. So `(&s, &s).merge()` and `(&a, &b).merge()` become two different resolved function calls in MIR. By the time codegen runs, the decision is already made.\n\nFor specialization that depends on lifetime properties (`'static`, same-origin, outlives), anything that goes through a generic function can only be resolved if the relevant bounds are explicitly declared in the function signature. Without explicit bounds, the solver falls back to the default impl. For method-only specialization (where the return type doesn't change), monomorphization can pick the specialized code path for type-based properties like `T: Copy`, and for `T: 'static` on owned types where `'static` is determinable from the type structure alone (e.g. `u32`, `String`). But for reference types like `&str`, the monomorphizer can't tell if it was `&'static str` or `&'a str` after lifetime erasure, so it falls back to the default.\n\nIf origin/lifetime information were preserved into codegen, it would unlock additional optimizations beyond what the solver can prove statically. Method-only specialization could be resolved at monomorphization time for cases like same-origin dispatch through generic functions, or `'static` dispatch for reference types. But even without that, the proposal still stands. We'd just miss those optimizations, falling back to the default (slower) code path. The soundness story doesn't depend on codegen having origin information, only the optimization story does.\n\nSo in a way, we get proper full specialization for \"concrete\" types, but when lifetime shenanigans are involved, it becomes specialization only at the call-site level, or through explicitly declared bounds.",
  "title": "Could borrow checking with origins unblock sound specialization"
}