Short answer
As of 2026, Carbon's C++ interoperability is an experimental design goal, not a finished feature. There is no confirmed general mechanism for resolving a C++ template instantiation that exceeds the current mapping capabilities — the design direction is that un-mappable types either fail at compile time or are exposed only through a restricted, opaque view, not silently coerced into a Carbon type. And on the safety question: Carbon's memory-safety invariants stop at the interop boundary. C++ code is treated as unsafe, full stop.
Type mismatches: likely explanation vs. confirmed facts
Confirmed: Carbon's interop approach imports C++ declarations through Clang-based parsing and gives them Carbon-facing views. It does not re-implement C++ semantics. The supported subset of C++ declarations is explicitly limited and evolving.
Likely, not confirmed: For a template relying on non-standard compiler extensions or ABI-specific behavior, the expected outcome is a compile-time interop error — Carbon's design philosophy favors explicit failure over silent misinterpretation. Whether a given un-mappable type degrades to an opaque handle today depends on the current toolchain state and must be verified, not assumed. Do not design a migration around an automatic opaque-type fallback existing.
Memory safety at the boundary
Carbon cannot retroactively apply its safety model to C++ objects. The boundary is a trust boundary:
- Safety checks are enforced on the Carbon side only.
- Any pointer or reference arriving from C++ must be treated as unvalidated — lifetime, ownership, and nullability are the caller's responsibility.
- The practical pattern is a thin wrapper layer: validate pointers and lifetimes at the boundary, and never let raw C++ objects flow into otherwise-safe Carbon code paths.
Treating C++ objects as if they satisfy Carbon invariants reintroduces exactly the memory bugs the migration was meant to eliminate.
How to verify for your codebase
- Build the current toolchain from the carbon-language repository and attempt to import a representative instantiation of your problem template. Observe whether the compiler errors, imports it, or restricts it.
- Check the project's current interop design documents and open issues for the supported C++ declaration subset.
- Write a minimal boundary test: pass a C++-allocated object into Carbon and see what the compiler requires at the call site.
- Confirm which Clang/LLVM version the toolchain targets — ABI and template behavior are version-sensitive and not portable across C++ compilers.
Uncertainty
Both answers depend on an experimental toolchain that changes frequently. Any claim here about specific fallback behavior or inserted checks should be re-verified against the toolchain revision you actually build; this answer reflects design intent, not shipped guarantees.