Repository navigation
Add std::vector constructor overloads and tests #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ayuse
wants to merge
9
commits into
rustfoundation:main
Choose a base branch
from
Ayuse:codex/vector-constructors
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
fd7e67c
Add C++ vector constructor overload experiment
Ayuse 70adf50
Document vector constructor coverage and deferred overloads
Ayuse 3cdb954
Move vector documentation beside relevant constructors
Ayuse ffe330e
Shorten vector constructor coverage comments
Ayuse 218e13f
Expand vector overload coverage and ownership tests
Ayuse b675ce1
Add vector overload incompatibility examples
Ayuse a518e82
Document vector overload compatibility results
Ayuse 9934cc9
Address vector documentation and diagnostic review feedback
Ayuse d27de34
Merge main and resolve vector integration conflicts
Ayuse File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| //! Demonstrate incompatible Rust translations of C++ `std::vector` overloads. | ||
| //! Expected compiler output is in `stdcpp-vector.stderr`; working overloads are in | ||
| //! `src/stdcpp/vector.rs`. This example uses Rust-only stand-ins because the crate's | ||
| //! `cpp!` build scans the library, not separately compiled examples. | ||
| //! | ||
| //! ### Incompatibilities | ||
| //! | ||
| //! Setting the element alias `T` to `c_size_t` makes the one-element initializer-list | ||
| //! signature identical to the count constructor, and the two-element signature | ||
| //! identical to the fill constructor. The generated argument-trait implementations | ||
| //! overlap. Explicit argument casts cannot distinguish identical types. | ||
| //! This collision comes from translating initializer lists into separate arguments: | ||
| //! C++ has a distinct `initializer_list<T>` parameter and braced-initialization syntax. | ||
| //! | ||
| //! The macro also rejects `front(&self)` and `front(&mut self)` in one overload set. | ||
| //! Its single dispatch method must have one receiver kind, so it cannot directly | ||
| //! represent the const and non-const C++ accessor pair. | ||
| //! | ||
| //! ### Macro ergonomics | ||
| //! | ||
| //! FIXME: The `(usize, usize)` conflict diagnostic points at the overload block | ||
| //! and displays the one-argument constructor instead of the conflicting two-argument | ||
| //! constructors. Improve the macro's generated spans so the error identifies the | ||
| //! count-and-value and two-element initializer-list overloads. | ||
| //! | ||
| //! ### Workarounds | ||
| //! | ||
| //! Give initializer-list input a distinct wrapper type, or use separate constructor | ||
| //! names for element lists and counts. Accepting slices instead is another API option, | ||
| //! but the existing slice bridge invokes the iterator-pair constructor and would not | ||
| //! demonstrate the initializer-list constructor. | ||
| //! | ||
| //! Use separate `front` and `front_mut` methods for the accessor pair. An alternative | ||
| //! worth testing is associated-function overloads with explicit `&Vector` and | ||
| //! `&mut Vector` arguments instead of receivers. A working borrowed accessor must | ||
| //! tie the returned reference's lifetime to the vector and prevent invalidating | ||
| //! mutations while that reference is borrowed. | ||
| //! | ||
| //! C++ signatures: <https://eel.is/c++draft/vector.overview>. | ||
|
|
||
| #![feature(splat, tuple_trait, c_size_t)] | ||
| #![allow(incomplete_features)] | ||
| #![allow(unused_braces)] | ||
|
|
||
| use splat_overload::overload; | ||
| use std::ffi::c_size_t; | ||
|
|
||
| type T = c_size_t; | ||
|
|
||
| #[expect(dead_code, reason = "Incompatible overloads cannot be called")] | ||
| struct StdVectorT(Vec<T>); | ||
|
|
||
| overload! { | ||
| impl StdVectorT { | ||
| fn new(_count: c_size_t) -> StdVectorT { | ||
| todo!() | ||
| } | ||
|
|
||
| fn new(_count: c_size_t, _value: T) -> StdVectorT { | ||
| todo!() | ||
| } | ||
|
|
||
| fn new(_value: T) -> StdVectorT { | ||
| todo!() | ||
| } | ||
|
|
||
| fn new(_a: T, _b: T) -> StdVectorT { | ||
| todo!() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[expect(dead_code, reason = "Incompatible overloads cannot be called")] | ||
| struct StdVectorFront(Vec<std::ffi::c_int>); | ||
|
|
||
| overload! { | ||
| impl StdVectorFront { | ||
| fn front(&self) -> Option<&std::ffi::c_int> { | ||
| self.0.first() | ||
| } | ||
|
|
||
| fn front(&mut self) -> Option<&mut std::ffi::c_int> { | ||
| self.0.first_mut() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn main() {} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| error: proc macro panicked | ||
| --> cpp-overload-test/examples/stdcpp-vector.rs:76:1 | ||
| | | ||
| 76 | / overload! { | ||
| 77 | | impl StdVectorFront { | ||
| 78 | | fn front(&self) -> Option<&std::ffi::c_int> { | ||
| 79 | | self.0.first() | ||
| ... | | ||
| 86 | | } | ||
| | |_^ | ||
| | | ||
| = help: message: all overloads must have the same receiver kind (&self, &mut self, self, or no receiver), got front: &self and front: &mut self | ||
|
|
||
| error[E0119]: conflicting implementations of trait `NewArgs<StdVectorT>` for type `(usize,)` | ||
| --> cpp-overload-test/examples/stdcpp-vector.rs:53:1 | ||
| | | ||
| 53 | / overload! { | ||
| 54 | | impl StdVectorT { | ||
| 55 | | fn new(_count: c_size_t) -> StdVectorT { | ||
| 56 | | todo!() | ||
| ... | | ||
| 71 | | } | ||
| | | ^ | ||
| | | | | ||
| | |_first implementation here | ||
| | conflicting implementation for `(usize,)` | ||
| | | ||
| = note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
|
||
| error[E0119]: conflicting implementations of trait `NewArgs<StdVectorT>` for type `(usize, usize)` | ||
| --> cpp-overload-test/examples/stdcpp-vector.rs:53:1 | ||
| | | ||
| 53 | / overload! { | ||
| 54 | | impl StdVectorT { | ||
| 55 | | fn new(_count: c_size_t) -> StdVectorT { | ||
| 56 | | todo!() | ||
| ... | | ||
| 71 | | } | ||
| | | ^ | ||
| | | | | ||
| | |_first implementation here | ||
| | conflicting implementation for `(usize, usize)` | ||
| | | ||
| = note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
|
||
| For more information about this error, try `rustc --explain E0119`. | ||
| error: could not compile `cpp-overload-test` (example "stdcpp-vector") due to 3 previous errors |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there might have been a version control snafu? Is it expected that these are
todo!()?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The examples are test files that show that overloads conflict in Rust (or can't be implemented in C++). So
todo!()is ok here, there's not much point filling in the C++ code when the Rust code will never work.See the example code here where the overloads conflict when T is size_t:
overloading-macros/cpp-overload-test/examples/stdcpp-forward-list.rs
Lines 34 to 40 in 2389011
Think of them like a cheap version of Rust compiler UI tests, they also come with a stderr output file.
Also, this is step 2 of the PR, this is @thunderseethe's decision. If he thinks that the step 1 work is complete, he can move on to reviewing step 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these were intentional placeholders in the compile-fail example, not a version-control mistake. The test checks conflicting signatures, so the bodies never run.