Add experimental fallible::FallibleVec - #157394
ChrisDenton wants to merge 1 commit into
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
Ooph, that's unfortunate. Simplest thing is to rename this type. But I do wonder if that could be fixed. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
fallible::Vecfallible::FallibleVec
|
Let me know if this is actually waiting on a review -- for now since CI is failing I'll move it back to waiting on author. |
b0e0675 to
39ac2e9
Compare
|
Any special-casing of Miri in the standard library requires review. cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
39ac2e9 to
30086ce
Compare
This comment has been minimized.
This comment has been minimized.
b98f62a to
ed80ad2
Compare
This comment has been minimized.
This comment has been minimized.
ed80ad2 to
12f773c
Compare
This comment has been minimized.
This comment has been minimized.
12f773c to
93c0c8d
Compare
This comment has been minimized.
This comment has been minimized.
93c0c8d to
ec3627b
Compare
|
@Mark-Simulacrum sorry about the wait, I have more time to move this forward now. As a reminder to myself as much as you the naming "FallibleVec" is pretty much like "yeet", it's probably not what we end up with but it can act as a placeholder until we figure out that particular bikeshed. Also diagnostics need some work, but I'm told this isn't trivial so I'd rather that not be a blocker atm. As noted in the OP, this is intended to be a MVP. It's likely everything about this API will be argued over but I think we should start with something rather than wait until we've fully designed everything. @rustbot ready |
ec3627b to
1801eb3
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
I removed the Allocator API stuff. When I originally made this PR it had been more or less unchanged for ages but now it's had a lot of work done and is nearing stabilization so I want to avoid stepping on any toes. It's easy to add back the Allocator methods in a follow up PR once Allocator is properly stable and things have settled a bit. |
This comment has been minimized.
This comment has been minimized.
1801eb3 to
4d4aad0
Compare
| #[unstable(feature = "fallible_vec", issue = "157392")] | ||
| #[derive(Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] | ||
| pub struct FallibleVec<T> { | ||
| buf: InfallibleVec<T>, |
There was a problem hiding this comment.
Hm, do you think the code is more readable with this called InfallibleVec vs. just Vec?
| /// All allocating methods will return [`AllocError`][super::AllocError] if allocation fails. | ||
| /// Otherwise are the same as their infallible `Vec` counterparts. | ||
| /// | ||
| /// Both `fallible::Vec` and `Vec` are fully ABI compatible, which means you can freely cast between with no cost. |
There was a problem hiding this comment.
| /// Both `fallible::Vec` and `Vec` are fully ABI compatible, which means you can freely cast between with no cost. | |
| /// Both `fallible::Vec<T>` and `Vec<T>` are fully layout and ABI compatible, which means you can freely cast between the two. |
| /// # Safety | ||
| /// | ||
| /// This is highly unsafe, due to the number of invariants that aren't | ||
| /// checked: |
There was a problem hiding this comment.
I think it would be nice to find a way to not duplicate all of the safety requirements, code examples, etc. -- maybe it makes sense to just forward to main Vec docs here and in other methods?
I think at least right now most users should understand this type as being "equivalent to" Vec, modulo some specific details, and having all the docs duplicated makes it harder to find those differences.
There was a problem hiding this comment.
I see you noted this in the PR description -- ultimately happy to defer this but I think it'll continue being a painpoint until/after stabilization of this API surface area since we'll keep forgetting to update both places (or need to review duplicate diffs).
| #[rustc_const_unstable(feature = "fallible_vec", issue = "157392")] | ||
| pub const fn to_fallible(self) -> FallibleVec<T> { | ||
| FallibleVec { buf: self } | ||
| } |
There was a problem hiding this comment.
Should we provide conversions over &mut self and &self? I think we can transmute those references too, right?
| /// ``` | ||
| #[inline] | ||
| pub fn leak<'a>(self) -> &'a mut [T] | ||
| where { |
| /// vector's elements to a larger allocation. This expensive operation is | ||
| /// offset by the *capacity* *O*(1) insertions it allows. | ||
| #[inline] | ||
| #[must_use = "if you don't need a reference to the value, use `Vec::push` instead"] |
There was a problem hiding this comment.
nit: InfallibleVec::push
| /// As of Rust 1.57, this method does not reallocate or shrink the `FallibleVec`, | ||
| /// so the leaked allocation may include unused capacity that is not part | ||
| /// of the returned slice. |
There was a problem hiding this comment.
nit: FallibleVec would nead to make this decision prior to stabilization, since the return type would be different.
|
|
||
| #[inline] | ||
| fn deref(&self) -> &[T] { | ||
| self.as_slice() |
There was a problem hiding this comment.
I suspect the structure of this method is going to end up invalidating pointers that Vec wouldn't have? Or do we get away with it in practice? (Haven't thought too deeply about this and doesn't really block landing this, but probably worth adding to tracking issue until we have an answer)
(Specifically any guarantees or happens-to-work around e.g. spare capacity not getting invalidated when calling len())
| } | ||
|
|
||
| /// A specialized version of `self.reserve(len, 1)` which requires the | ||
| /// caller to ensure `len == self.capacity()`. |
There was a problem hiding this comment.
Hm, this wording suggests unsafe fn is warranted, but I guess it's pre-existing either way?
View all comments
Tracking issue: #157392
There are a few things to be aware of here:
VecVecis a pretty crucial part of rust's standard library. We have to be extremely careful touching its code. We might regress performance or make debugging worse.With that in mind, this PR does the minimum necessary for an MVP
fallible::FallibleVec. The only actually new thing it adds is falliblepushandpush_mutmethods. The rest just forwards toVecequivalents. Further APIs can be added (carefully) afterwards.I apologise for the number of lines changed in the PR but they are mostly copy/pasted docs (I wanted them for the testable examples mostly). We should probably find a better way of duplicating them but I think this works for a minimally intrusive experiment.