Skip to content

Commit 3db3a3b

Browse files
committed
Add failing overloads
1 parent 8c17053 commit 3db3a3b

2 files changed

Lines changed: 169 additions & 10 deletions

File tree

‎cpp-overload-test/examples/stdcpp-forward-list.rs‎

Lines changed: 136 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,141 @@
22
//!
33
//! The `cpp!` macro doesn't work here, because of technical limitations it can only run one build
44
//! per crate. (Examples and binaries are built separately from `lib.rs`.)
5-
//! To add C++ code here, use /* ... */ code comment blocks.
5+
//! To add C++ code here, use /* ... */ code comment blocks, or just skip it.
6+
//!
7+
//! ### Potential Resolutions
8+
//!
9+
//! There isn't a clear equivalent of list initializers in Rust, so if we decided the initializer
10+
//! list overloads were inexpressible in Rust, all overloads would be compatible. (And initializer
11+
//! lists could be supported using the slice or iterator overloads.)
12+
13+
#![feature(splat, tuple_trait, c_size_t)]
14+
#![allow(incomplete_features)]
15+
#![allow(unused_braces)]
16+
17+
use splat_overload::overload;
18+
use std::ffi::c_size_t;
19+
20+
/// A wrapper struct to hold the returned C++ pointer, with the `T` fake generic type.
21+
/// We also fake the C++ list pointer with a Rust vector to help with type checking.
22+
#[expect(dead_code, reason = "Incompatible overloads can't be used")]
23+
struct StdForwardListT(Vec<T>);
24+
25+
/// Workaround for missing generic support in the `overload!` macro.
26+
type T = std::ffi::c_size_t;
627

7-
fn main() {
8-
const _: () = panic!("There are no failing overloads for C++ `std::forward_list` yet");
28+
// This overload set has overloads which are incompatible when `T` is `c_size_t`.
29+
overload! {
30+
impl StdForwardListT {
31+
/// Construct a list with `count` default-constructed items.
32+
fn new(_count: c_size_t) -> StdForwardListT {
33+
todo!()
34+
}
35+
36+
/// Construct a list filled with `count` instances of the given value.
37+
fn new(_value: T, _count: c_size_t) -> StdForwardListT {
38+
todo!()
39+
}
40+
41+
/// Construct a list from the supplied item.
42+
///
43+
/// ### Incompatibilities
44+
///
45+
/// This overload has the same types as `new(count)` when `T` is `c_size_t`, but different
46+
/// semantics:
47+
/// - `new(count)` fills the list with the default value of `T` repeated`count` times.
48+
/// - `new(value)` fills the list with one instance of `value`.
49+
fn new(_value: T) -> StdForwardListT {
50+
todo!()
51+
}
52+
53+
/// Construct a list from the supplied 2 items.
54+
///
55+
/// ### Incompatibilities
56+
///
57+
/// This overload has the same types as `new(value, count)` when `T` is `c_size_t`, but different
58+
/// semantics:
59+
/// - `new(value, count)` fills the list with `count` instances of `value`.
60+
/// - `new(a, b)` fills the list with two values: `a` and `b`.
61+
fn new(_a: T, _b: T) -> StdForwardListT {
62+
todo!()
63+
}
64+
}
965
}
66+
67+
/// A wrapper struct to hold the returned C++ pointer, with the `U` fake generic type.
68+
/// We also fake the C++ list pointer with a Rust vector to help with type checking.
69+
#[expect(dead_code, reason = "Incompatible overloads can't be used")]
70+
struct StdForwardListU(Vec<U>);
71+
72+
/// Workaround for missing generic support in the `overload!` macro.
73+
type U = StdForwardListU;
74+
75+
// This overload set has overloads which are compatible, but have poor ergonomics,
76+
// when `U` is `StdForwardListU` (which is possible with some boxed types).
77+
overload! {
78+
impl StdForwardListU {
79+
/// Clone list items into a new list from a shared list reference.
80+
fn newer(_other: &StdForwardListU) -> StdForwardListU where U: Clone {
81+
todo!()
82+
}
83+
84+
/// Move list items into a new list from a mutable list reference.
85+
fn newer(_other: &mut StdForwardListU) -> StdForwardListU {
86+
todo!()
87+
}
88+
89+
/// Construct a list from the supplied item.
90+
///
91+
/// ### Potential Overlap
92+
///
93+
/// This overload has similar types to `new(&/&mut other)` when `U` is `StdForwardListU`,
94+
/// but different semantics:
95+
/// - `new(&/&mut other)` clones or moves the list items into a new list.
96+
/// - `new(value)` fills the list with one instance of `value`.
97+
///
98+
/// Due to the references, this is technically compatible. But the ergonomics are likely
99+
/// to be poor, particularly when auto-ref and auto-deref are used.
100+
fn newer(_a: U) -> StdForwardListU {
101+
todo!()
102+
}
103+
}
104+
}
105+
106+
/// A wrapper struct to hold the returned C++ pointer, with the `V` fake generic type.
107+
/// We also fake the C++ list pointer with a Rust vector to help with type checking.
108+
#[expect(dead_code, reason = "Incompatible overloads can't be used")]
109+
struct StdForwardListV(Vec<V>);
110+
111+
/// Workaround for missing generic support in the `overload!` macro.
112+
/// Currently this type alias fails compilation very early due to cycle checking, but with
113+
/// generics the *possibility* of an identical impl existing is enough to make compilation fail,
114+
/// even if it can't be implemented in practice.
115+
//type V<'v> = &'v mut dyn Iterator<Item = V<'v>>;
116+
type V = Box<dyn Iterator<Item = VCycleBreaker>>;
117+
type VCycleBreaker = ();
118+
119+
// This overload set has overloads which are incompatible when `V` is
120+
// `&mut dyn Iterator<Item = V>`. This is a contrived example, but trait solving would fail anyway.
121+
overload! {
122+
impl StdForwardListV {
123+
/// Construct a list from an iterator.
124+
fn newest(_iter: &mut dyn Iterator<Item = V>) -> StdForwardListV {
125+
todo!()
126+
}
127+
128+
/// Construct a list from the supplied items.
129+
///
130+
/// ### Incompatibilities
131+
///
132+
/// This overload has the same type as `new(iter)` when `V` is
133+
/// `&mut dyn Iterator<Item = V>`, but different semantics:
134+
/// - `new(iter)` constructs a list from the items in the iterator.
135+
/// - `new(a)` constructs a list from a single item (where the item is an iterator).
136+
fn newest(_a: V) -> StdForwardListV {
137+
todo!()
138+
}
139+
}
140+
}
141+
142+
pub fn main() {}
Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
1-
error[E0080]: evaluation panicked: There are no failing overloads for C++ `std::forward_list` yet
2-
--> cpp-overload-test/examples/stdcpp-forward-list.rs:8:19
3-
|
4-
8 | const _: () = panic!("There are no failing overloads for C++ `std::forward_list` yet");
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `main::_` failed here
1+
error[E0119]: conflicting implementations of trait `NewArgs<StdForwardListT>` for type `(usize,)`
2+
--> cpp-overload-test/examples/stdcpp-forward-list.rs:29:1
3+
|
4+
29 | / overload! {
5+
30 | | impl StdForwardListT {
6+
31 | | /// Construct a list with `count` default-constructed items.
7+
32 | | fn new(_count: c_size_t) -> StdForwardListT {
8+
... |
9+
65 | | }
10+
| | ^
11+
| | |
12+
| |_first implementation here
13+
| conflicting implementation for `(usize,)`
14+
|
15+
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)
616

7-
For more information about this error, try `rustc --explain E0080`.
8-
error: could not compile `cpp-overload-test` (example "stdcpp-forward-list") due to 1 previous error
17+
error[E0119]: conflicting implementations of trait `NewArgs<StdForwardListT>` for type `(usize, usize)`
18+
--> cpp-overload-test/examples/stdcpp-forward-list.rs:29:1
19+
|
20+
29 | / overload! {
21+
30 | | impl StdForwardListT {
22+
31 | | /// Construct a list with `count` default-constructed items.
23+
32 | | fn new(_count: c_size_t) -> StdForwardListT {
24+
... |
25+
65 | | }
26+
| | ^
27+
| | |
28+
| |_first implementation here
29+
| conflicting implementation for `(usize, usize)`
30+
|
31+
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)
32+
33+
For more information about this error, try `rustc --explain E0119`.
34+
error: could not compile `cpp-overload-test` (example "stdcpp-forward-list") due to 2 previous errors

0 commit comments

Comments
 (0)