Repository: rust
Issue: Tracking Issue for the experimental `crabi` ABI
Labels: T-lang,C-tracking-issue,A-ABI

This is a tracking issue for the experimental `crabi` ABI; see https://github.com/rust-lang/rust/pull/105586 and https://github.com/rust-lang/compiler-team/issues/631.
The feature gate for the issue is `#![feature(crabi)]`.

### About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

### Steps
<!--
Include each step required to complete the feature. Typically this is a PR
implementing a feature, followed by a PR that stabilises the feature. However
for larger features an implementation could be broken up into multiple PRs.
-->

- [ ] Implement the experimental feature
- [ ] Write an RFC precisely specifying the ABI
- [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide])
- [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide])

[stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr
[doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs

### Unresolved Questions

- Niches: should we support cases like `Option<bool>` without a separate
  discriminant, or should we (for simplicity) always pass a separate
  discriminant? Likely the latter. However, what about things like `Option<&T>`
  and `Option<NonZeroU32>`, for which Rust guarantees the representation of
  `None`? Those work with the C ABI, and they have to work with crABI, but can
  we make them work with crABI *using the same encoding of `None`*?
- What subset of lifetimes can, and should, we support? We can't enforce them
  cross-language, but they may be useful as an advisory/documentation
  mechanism. Or we could leave them out entirely.
- To what extent should crABI make *any* attempt to specify things that can't
  be enforced, rather than ignoring semantics entirely and *only* specifying
  how types get passed?
- How can we make it easy to support data structures without having to do
  translation from `repr(Rust)` to `repr(crabi)` and have parallel structures?
  Can we make that less painful to express, and ideally mostly free at runtime?
  - Related: how can we handle tuples? Do we need a way to express
    `repr(crabi)` tuples? How can we do that conveniently?
- Should we provide support for extensible enums, such that we don't assume the
  discriminant matches one of the known variants? Would doing so make using
  enums less ergonomic? Could we address that with language changes?
- For handling objects, could we avoid having to pass in-memory function
  pointers via a vtable, and instead reference specific symbols? This wouldn't
  work for generics, though. Can we do any better than a vtable?
- For ranges, should we provide a concrete range type or types, or should we
  defer that and handle ranges as opaque objects or traits?
- Do we get any value out of supporting `()`, other than completeness? Passing
  `()` by value should just be ignored as if it weren't specified. Do we want
  people using pointers to `()`, and do those have any advantage over pointers
  to void?
- Should we do anything special about `i128` and `u128`, or should we just push
  for getting those supported correctly in `extern "C"`?
- For generics, such as `Option<u64>` or `Result<u32, ConcreteError>` or
  `[u8; 16]`, does the rule "all generic parameters must be bound to concrete
  types in the function signature" suffice, or do we need a more complex rule
  than that?
- Unwinding: The default `extern "crabi"` should not support unwind, and most
  languages don't tend to have support for unwinding through C-ABI functions,
  but should we have a `crabi-unwind` variant? Would doing so provide value?

### Implementation history

<!--
Include a list of all the PRs that were involved in implementing the feature.
-->

- Feature gate: https://github.com/rust-lang/rust/pull/105586