From 745c3d6a487e45c78bdfbab038eccec9e7191556 Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 24 Sep 2026 10:34:28 +0200 Subject: [PATCH 1/2] Link success and failing code files to each other --- cpp-overload-test/examples/stdcpp-forward-list.rs | 8 +++++++- cpp-overload-test/src/stdcpp/forward_list.rs | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cpp-overload-test/examples/stdcpp-forward-list.rs b/cpp-overload-test/examples/stdcpp-forward-list.rs index 101352d..d3e407d 100644 --- a/cpp-overload-test/examples/stdcpp-forward-list.rs +++ b/cpp-overload-test/examples/stdcpp-forward-list.rs @@ -1,4 +1,10 @@ -//! Test C++ overloads that can't be represented in Rust, and record the macro diagnostics. +//! Test C++ [std::forward_list][forward_list] overloads that can't be represented in Rust, and record the macro diagnostics. +//! Error output is in [stdcpp-forward-list.stderr]. +//! Working overloads are in [forward_list.rs]. +//! +//! [forward_list]: https://en.cppreference.com/cpp/container/forward_list +//! [stdcpp-forward-list.stderr]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.stderr +//! [forward_list.rs]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/src/stdcpp/forward_list.rs //! //! The `cpp!` macro doesn't work here, because of technical limitations it can only run one build //! per crate. (Examples and binaries are built separately from `lib.rs`.) diff --git a/cpp-overload-test/src/stdcpp/forward_list.rs b/cpp-overload-test/src/stdcpp/forward_list.rs index 90bec92..228f7cb 100644 --- a/cpp-overload-test/src/stdcpp/forward_list.rs +++ b/cpp-overload-test/src/stdcpp/forward_list.rs @@ -1,4 +1,9 @@ -//! Test that C++ overloads for `std::forward_list` can be successfully represented in Rust. +//! Test that C++ overloads for [std::forward_list][forward_list] can be successfully represented in Rust. +//! Failing overloads are in [stdcpp-forward-list.rs], and error output is in [stdcpp-forward-list.stderr]. +//! +//! [forward_list]: https://en.cppreference.com/cpp/container/forward_list +//! [stdcpp-forward-list.rs]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.rs +//! [stdcpp-forward-list.stderr]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/examples/stdcpp-forward-list.stderr #![allow(unused_braces)] From 356e61d0a2f2685c58f23b5fa687afcba34da5b9 Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 24 Sep 2026 10:34:55 +0200 Subject: [PATCH 2/2] Early draft C++ overload compat table --- README.md | 6 +++ cpp-overloads-in-rust.md | 103 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 cpp-overloads-in-rust.md diff --git a/README.md b/README.md index 0546f13..1424692 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,12 @@ Technical details for the current stage of the experiment can be found [on the I Most of this code requires a recent nightly Rust compiler. +## Experimental Outcomes + +Some outcomes of this experiment are summarised in the [C++ overloads in Rust](https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overloads-in-rust.md) document & compatibility table. + +These outcomes are based on the current state of the experimental compiler feature and overloading macro: they are not Rust language design decisions. + ## Macro Setup Install a recent version of the nightly Rust compiler, and use it to build your project. diff --git a/cpp-overloads-in-rust.md b/cpp-overloads-in-rust.md new file mode 100644 index 0000000..db97b9e --- /dev/null +++ b/cpp-overloads-in-rust.md @@ -0,0 +1,103 @@ + +# C++ Overloads in Rust: Experimental Outcomes + +***This document is an initial, partially reviewed draft*** + +This table shows how well C++ standard library overloads can be represented in Rust. + +These outcomes are based on the current state of the experimental `splat` compiler feature and +overloading macro: they are not Rust language design decisions. + +See the Limitations section below the table for more details. + +*Key:*
+⛔ Conflicting Overloads
+🦀 Rust Compiler Limitations
+⚙️ Overload Macro Limitations
+🌗 Partial Support or Poor Ergonomics
+✅ Works in Rust
+? Needs Analysis
+*blank* No C++ Overloads
+ +| C++ Standard Library Class | Constructors | Accessors | Modifiers | Transforms | +| :------------------------- | :----------- | :-------- | :-------- | :--------- | +| *Free Functions* | Constructors | Accessors | Modifiers | Transforms | +| TODO | | ? | ? | ? | +| *Non-Template Classes* | Constructors | Accessors | Modifiers | Transforms | +| TODO | ? | ? | ? | ? | +| *Template Classes* | Constructors | Accessors | Modifiers | Transforms | +| [forward_list] | ✅ | 🌗⚙️ | ? | ?[^1] | +| TODO | ? | ? | ? | ? | + +Constructors: Create an instance of the class, called as `Class::Class(...)`
+Accessors: Get information about the class, called as `instance->get(...)`
+Modifiers: Add or change the items in a list class, called as `instance->put(...)`
+Transforms: Rearrange the items in a list class, called as `instance->sort(...)`
+ +[forward_list]: https://github.com/rustfoundation/overloading-macros/blob/main/cpp-overload-test/src/stdcpp/forward_list.rs + +[^1]: TODO: are [C++ predicate functions](https://en.cppreference.com/cpp/container/forward_list/unique) with const refs ABI-compatible with Rust? + +## Limitations + +This section summarises common issues discovered during the analysis, and documents less +interesting overloads that were skipped. + +### Typical Overload Conflicts + +Overload macro missing functionality: + +- methods that only differ by `self` type, for example `get(&self) -> &T` and + `get(&mut self) -> &mut T` + - this can be worked around using associated functions, but the ergonomics suffer +- Generic types: + - this makes representing C++ templated types with generic Rust types impossible + - doesn't support `impl Iterator` or `where I: Iterator` as arguments, but supports + `&dyn Iterator` (which is less ergonomic) +- Lifetimes: + - generic lifetimes aren't supported + - when the input method has elided lifetimes, the generated code doesn't add lifetimes where + needed + +### Ergonomics + +Some overloads are confusing or hard to use, so we might not want to represent them in Rust: + +- `get(&self) -> &T` and `get(&mut self) -> &mut T` is a subtle difference, typical Rust APIs use + `get` and `get_mut` instead +- in generic list overloads, `new(count: usize)` and `new(item: T)` are easily confused if `T` is + an integer (and they conflict if `T` is `usize`, which means it can't be fully generic) + - this can be resolved by skipping overloads for initializer lists +- `&dyn Iterator` overloads require a type cast + - this could be resolved with improvements to the macro, or with an iterator adapter type + +Type inference doesn't work on some overloads: this is likely a macro or compiler experiment limitation. + +Some C++ overloads [use a tag argument][cpp-tag-arg] for [overload disambiguation][cpp-tag-type], +a strategy which could be adopted in Rust APIs. But in some cases, the Rust overload +[might not need disambiguation][rust-no-disambig]. + +[cpp-tag-arg]: https://en.cppreference.com/cpp/container/forward_list/forward_list +[cpp-tag-type]: https://en.cppreference.com/cpp/ranges/from_range +[rust-no-disambig]: https://github.com/rustfoundation/overloading-macros/blob/52c3f3aa5e4e6f11d71d2d832fce733f00d0b087/cpp-overload-test/src/stdcpp/forward_list.rs#L89 + +### Scope + +Some overloads have been ignored or minimised in this analysis. + +These overloads are less interesting: + +- overloaded operators: already available in stable Rust +- overloads with an allocator argument, or that only differ by noexcept: not an interesting + difference +- overloads that only differ by `const`/non-`const`, `&`/`&&` (lvalue/rvalue) in C++, or + `&`/`&mut` in Rust + +These overloads have no equivalent in Rust: + +- assignment functions, assignment operators, and `swap`: there is no "type move method" in Rust + (it uses `memcpy` for assignment/swaps) +- legacy iterator pointer-like methods for various positions + (`before_begin`/`begin`/`end`/`after_end`) +- initializer list methods: these are also a common source of overload conflicts for C++ templated + lists