Skip to content

add std::array overloads for constructors, to_array and get - #57

Open
0xull wants to merge 3 commits into
rustfoundation:mainfrom
0xull:array-overloads
Open

0xull wants to merge 3 commits into
rustfoundation:mainfrom
0xull:array-overloads

Conversation

@0xull

@0xull 0xull commented Oct 16, 2026 •

Copy link
Copy Markdown

this pr adds rust wrappers for std::array<int, 3> overloads covering three method names, the constructors, to_array and get.

std::array constructors are aggregate initialization with 0 to N initializers, in addition with the copy and move constructors. all of them are implemented for N = 3, so the constructor set is complete. unlike forward_list, none of its overloads clash because std::array has no count or value constructors.

c++ has two zero-argument forms (a; and a{};), but only one of them can be a rust overload, so i used value-initialization.

the constructors are the std::array overloads that differ by more than const or &/&&, so i chose to use two non-member functions as examples to show that rule:

  • to_array overloads on & and &mut built-in arrays, matching the c++ lvalue and rvalue versions.
  • get takes the element index as a template argument, and because the macro doesn't support const generics, each index gets its own overload through an Index<I> tag type. all three indices were done for &, but only index 0 was done for &mut and by-value, since every other index works the same way. but for the const&& overload it can't be represented, because rust types can't be const.

i implemented get to use &'static like forward_list::front, and its test leaks the arrays the same way the forward_list test does.

i skipped the other std::array overloads, with the Scope section in the module doc listing each one with the reason.

ai use: i used claude (web) to get explanation across different parts of the codebase, especially the overload! implementation and understanding of how overloads dispatch.

the code implementation are mine, written after studying forward_list implementation, and std::array specs from c++.

after studying forward_list and the use of &mut for c++ move, i was curious to ask if there have been any discussion about offering rust style move (by value)? i understand this would be a mismatch between both languages, but i'm curious for case when the moved-from c++ object itself needs not to be used after it is moved. because i initially implemented move to take ownership of the other object.

closes #34

  1. Write Rust wrappers for that C++ type, for 3-5 different overloaded method names:
    • Create a new file named after your type in overloading-macros/cpp-overload-test/src/stdcpp
    • Wrap constructors first, writing tests to make sure the correct constructor is called
    • Explain any potential compatibility issues in a Limitations doc section
    • Explain usability issues in an Ergonomics doc section
    • Check that you have implemented all the overloads for each method name, or documented why you can't
    • Push your changes and wait for a review
  2. Add a separate example with some failing overloads
    • Create a new file named after your type in overloading-macros/cpp-overload-test/examples
    • Wrap accessor/modifier methods
    • Explain how they fail in an Incompatibilities doc section
    • Explain how the overload failures could be resolved in a Workarounds doc section
    • Optional: If there's a C++ feature with no equivalent in Rust, explain that in an Inexpressible Overloads doc section
    • Push your changes and wait for a review
  3. Update the overload macro compatibility table Markdown doc
    • If you haven't checked some kinds of overloads, put a ?in those squares
    • Push your changes and wait for a review

Signed-off-by: Ikeh Chukwuka <mrikehchukwuka@gmail.com>
0xull added 2 commits October 18, 2026 07:20
Signed-off-by: Ikeh Chukwuka <mrikehchukwuka@gmail.com>
…ex<I>` tag type

Signed-off-by: Ikeh Chukwuka <mrikehchukwuka@gmail.com>
@0xull 0xull changed the title add std::array constructor overloads and tests add std::array overloads for constructors, to_array and get Oct 19, 2026
@0xull
0xull marked this pull request as ready for review October 19, 2026 05:55

@thunderseethe thunderseethe left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great start! Thanks for the submission.

after studying forward_list and the use of &mut for c++ move, i was curious to ask if there have been any discussion about offering rust style move (by value)? i understand this would be a mismatch between both languages, but i'm curious for case when the moved-from c++ object itself needs not to be used after it is moved. because i initially implemented move to take ownership of the other object.

I think this is definitely one of the more interesting questions about FFI between C++ and Rust. I would love to hear how you would tackle some of the problems for array. Especially around how to move items in and out of the array in both languages. Where Rust expects to be able to destructively move things out of an array that it owns, callers have to be careful not to leave an array element in an invalid state where Rust expects it won't be referenced again but C++ attemps to read it expecting the element to be left in a moved-from state.

I left one minor comment on section 1, but overall looks good. Can you show me an example of some failing overloads for array (per section 2)?

/// C++ also has a `const T&& get(const std::array&&)` overload but Rust types can't be `const`,
/// so a constant rvalue array has the same Rust type as a moved array. That overload
/// can't be represented separately from this one.
fn get(array: StdArray3, _index: Index<0>) -> T {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For methods that take an array "by value" like this, how can we uphold the lifetime guarentees here? This won't really matter for this case where T is an int but what if T was an object with a destructor. How can we ensure that when we return T by value that T won't get dropped when we drop the array initially holding it. If we can't, can we document the invariants required of our array when we call this method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

array

2 participants