Skip to content

Add std::list overloads: constructors, insert, erase, splice, sort - #58

Open
rogerkorantenng wants to merge 1 commit into
rustfoundation:mainfrom
rogerkorantenng:std-list-overloads
Open

rogerkorantenng wants to merge 1 commit into
rustfoundation:mainfrom
rogerkorantenng:std-list-overloads

Conversation

@rogerkorantenng

Copy link
Copy Markdown

Outreachy Application: std::list overloads

Claimed in #38 (#38 (comment)), from the tracking issue #19.

This PR wraps 5 overloaded std::list method names in cpp-overload-test/src/stdcpp/list.rs: new (constructors), insert, erase, splice and sort. Every overload for each name is either wrapped or documented as skipped. The skipped ones are allocator variants and the &/&& duplicates.

Interesting findings

  • Iterator positions vs the borrow checker. insert, erase and splice take a position from the same list as &mut self. If StdListIter borrowed the list, you couldn't call list.insert(&pos, ...) while holding pos. So the iterator wraps a const_iterator and doesn't borrow the list. The cost is that Rust can't stop you using an iterator from the wrong list, or one that has been erased. C++ can't either. A cursor API would fix this, but then insert would be a cursor method instead of a list overload.
  • Constructor ambiguity is resolved only by literal type. new(3, 9) gives [3, 9] (initializer list), but new(3_usize, 9) gives [9, 9, 9]. Forget the suffix and you silently get the other overload. If T were c_size_t, these overloads would conflict (E0119).
  • Copy vs move is & vs &mut. new(&other) copies and new(&mut other) empties other. That's easy to mix up.
  • splice goes from 6 overloads to 3. list& and list&& both become &mut StdList. Splicing a list into itself is impossible, because it would need two &mut borrows. Moved elements' iterators now point into self, which Rust lifetimes can't express.
  • insert(pos, initializer_list) becomes a slice. The constructors' 1/2/3-item trick doesn't work here: insert(pos, a) has the same types as insert(pos, value).
  • sort(comp) needs an extern "C" fn. There are no generics in overload!, and C++ templates can't be instantiated for a Rust closure type, so closures can't be passed (capturing or not). A panicking predicate aborts the process. A C++ trampoline plus a closure pointer could fix this.
  • Return type inference. Callers need let list: StdList = StdList::new(...), even though every overload returns StdList (marked FIXME).

AI use

No, AI was used in writing the code, they were written and tested by myself with the help of the rust documentation(rustdoc)

Banned AI Usage

Do not use AI to write GitHub descriptions, GitHub comments, code comments, or Zulip chats. Write in your native language, or at your current English level. In your PR description, you must tell us how you used AI. You must review code yourself before you open a PR.

For the best learning experience, write the code yourself, without using AI. Using LLMs to generate code is heavily restricted, and generating large amounts of code is banned.

Applicants must follow the Rust Project AI/LLM policy.

Application Steps

Claim a C++ standard library type from the list in the tracking issue by clicking on that issue, then commenting on it. This is the C++ type you will be working on. Before you claim a ticket, make sure no-one else has commented before you.

After each step, push your work to your open PR, make sure CI passes, then wait for 2-4 days for a mentor to review it. If you need help, post a message in the #outreachy > Overloading Applicant Help Oct 2026 topic on Zulip.

This coding task focuses on Rust and C++ overloads. It is ok to skip drop/destructors (leak memory), use unsafe, and ignore some compiler warnings. Shortcuts and workarounds can be used to simplify non-overload code.

Checklist

  1. Write Rust wrappers for that C++ type, for 3-5 different overloaded method names:
    • Create a new file named after your type in 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 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: 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

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.

1 participant