-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
collections: Stabilize Vec #17029
collections: Stabilize Vec #17029
Conversation
oops, wrong title! |
I don't understand the rationale for moving Why go out of the way to make Why only do it for static methods? It's just inconsistent and needlessly verbose. The names will collide In a module with more than one collection type (map + set), which is another reason why static methods are useful. AFAIK, it never went through the RFC process (at least not anything I saw) and goes against the previous consensus that led to converting these from free functions into methods in many modules. |
@thestinger When was there consensus that these should be methods? I thought they became methods purely because of the move to |
@alexcrichton If |
@kballard: How do you propose dealing with modules with more than one container type then? Why should static methods be in a module but not any of the other methods? They became methods because we made the decision to purge the free functions and a lot of work went into migrating everything. The Referring to |
What's the motivation for removing Similarly, |
Also, when you're deprecating |
( |
@thestinger You can't put instance methods in a module, unless you want to provide a single-implementation trait for them. And actually, using a single-implementation trait that needs to be explicitly |
@kballard: Making |
What's the motivation for removing the And the suggested replacement for if vec.len() < 4 {
vec.grow(4 - vec.len(), 0u);
vec.push(42u);
} else {
*vec.get_mut(5) = 42u; // will be vec[5] = 42u
} I'm willing to believe that |
@thestinger It's not about verbosity, it's about simplifying the API. |
@kballard: How is adding a module or adding a trait simplifying the API? Please just add a filter for |
@thestinger Note that I am not saying we should actually move instance methods into traits in the I also disagree that moving static methods into the |
It's a terrible idea because it doesn't work for modules with more than one type like the key-value data structures so it cannot be used consistently. You've avoided addressing that point. No one has given an explanation for the reasoning behind moving the static methods but not the instance methods. I think your point about a clean view of the safe methods was good, but I think it would be fully addressed by adding a filter to rustdoc.
That's not true. It's an extra namespace combined with an extra use statement for anything not in the prelude. There will be a
That's a misrepresentation of the current state of affairs. The vast majority of these
Not all static |
I fully agree with @thestinger. |
@thestinger, the convention for "raw" operations is a convention under development. The current mention in the guidelines isn't as specific as it could be, and I now that @aturon is working on fleshing it out to make it more concrete. This PR represents our current understanding of how "raw" operations should work, and you bring up some good points that need to be taken into consideration when developing the guideline around operations such as these. Our thinking was something like:
Due to a concrete guideline not currently existing, I may leave these methods in the submodule as
Right now we have a number of "push some elements onto this vector" functions, all of which are pretty inconsistent:
Some example inconsistencies:
We ended up deciding that there are so many convention questions here that the best thing to do would be to deprecate all of them and start from scratch. I believe that using iterators can be more ergonomic than it is today, and I agree that the current method of "pushing all by clone" is a little un-ergonomic. To maintain consistence across all collections we need to make sure they all provide similar interfaces (wherever possible). The sugar of "push all by clone" only exists for vectors, and we'd also like to extend that option to containers like set, maps, etc. So, all in all, we would like to deprecate the functions for now and start afresh. Does that make sense?
This was indeed considered when deciding what to do about these functions. We figured that these functions are not being removed, and will likely not for awhile, so the performance is not lost for now. If we are unable to come up with a suitable alternative when these functions are slated for deletion, it is likely that some may remain for this concern.
I've placed the Does that makes sense?
This was a bit of a toss up. The other method in question was We couldn't really think of a super-compelling argument in either direction, so we just made a decision.
Thanks for pointing that out! I'll change it. |
That's the problem with making all the decision making behind closed doors. There are many good points (not just from me) that are being missed and then the language has to go through many iterations of breaking changes. The problem with making stability decisions in the dark is that there's no going back after a mistake. There should at least be a cool off period of a week after the last API change before something can be marked
That's what There are incredibly simple ways to shoot yourself in the foot like
If it's useful, it shouldn't be deprecated. Just make it
One person's personal style guidelines isn't the same thing as consensus-based decisions. Writing them up and then proposing them via the RFC process is great, but it currently doesn't really hold any weight. Even though the RFC decisions are made by a small group of people, it's done after people have a venue to give input and criticize. The decision might not be something that most people in the community agree with, but at least it's a very well informed decision.
It's not the community's understanding of how |
This is not appropriate. As @thestinger says, deprecation means "this is going away" and is a very strong encouragement for people to stop using the APIs immediately. The only alternatives are a) live with compiler warnings (which sucks, and we definitely don't want to encourage this), or b) disable the warnings (which also sucks, we don't want people to disable deprecation warnings). Starting from scratch and building a more consistent API is fine. But In the meantime, the functions that are candidates for being replaced but do not yet have a replacement should be |
@thestinger Thinking about it some more, the precedent of |
It's still a more complex API (another module to look through), noisier to use, inconsistent (everything else is a method) and is an incomplete solution (what do you do with multiple types in a module?). To add another issue, what about |
@alexcrichton Yes, I'd recommend keeping the As to We were on the fence as to whether to mark these methods as deprecated or experimental. Since our plan is to remove them, deprecation seemed to send the clearest signal, but marking experimental may indeed be the better choice in cases like this (i.e. when the migration is not yet clear.) As @alexcrichton explained, As a general point, during stabilization we are trying to reduce API surface area where we can, both to minimize the promises we're making and to simplify APIs. For the case of convenience methods, this is sometimes a matter of taste and/or conventions. We also want to avoid leaving too much around as |
@alexcrichton I'm not sure where to find it anymore but somewhere there's a suggestion that the syntax fn with<T>(val: T, f: |&mut T|) -> T {
let mut val = val;
f(&mut val);
val
} and then call it like let x = with(make_vec(), Vec::push(_, 42u)); Not as nice or straightforward as Note: the |
To be clear, the guidelines that @alexcrichton cited are not personal -- they are official. In particular, new guidelines for things like
We've been trying to strike a balance between going through the RFC process for conventions issues and making more local API decisions in meetings. The RFC process is lengthy and heavy weight, and we have to balance it against the need to get APIs stabilized leading up to 1.0. Please understand that this is not about a power trip, but rather the simple fact that decisions need to be made in a timely fashion and the resulting process is not always perfect. That said, I think the process can certainly be improved and allow for more community input prior to final decisions. (For example, I'm currently writing a large RFC for more general API design around And thanks @kballard and @thestinger both for your feedback. |
If all type constructors that take raw pointers are done as functions in a I get what you're saying here, but I'm not sure it's really that important to require that all static type constructors be static methods of the type. Note here that we're actually removing
Use your best judgement? I'd actually be in favor of extending associated items to allow modules as well, so you can say It occurs to me that we actually could simulate the embedded module thing with the current proposed associated items, by having an associated item that is a static value of a zero-sized type that provides the constructors as methods. The only difference is you'd use impl<T> Vec<T> {
pub static raw: VecRawConstructor<T> = VecRawConstructor;
// ...
}
struct VecRawConstructor<T>;
impl<T> VecRawConstructor<T> {
pub fn from_parts(&self, length: uint, capacity: uint, ptr: *mut T) -> Vec<T> { ... }
}
fn example_usage() {
let (len, cap, ptr) = ...;
let v = unsafe { Vec::raw.from_parts(len, cap, ptr) };
// ...
} |
@aturon I am quite sympathetic to the idea that we should make it easier to user iterators for things like In any case, while the actual design of these APIs are being hammered out, I think it's really important that we don't use Perhaps we need another stability level, something that means "this is a candidate for deprecation, but we don't have a replacement yet". This way we can still mark these APIs appropriately without triggering the deprecation warnings. But I personally think |
@aturon: I don't think it's a power trip. I think the chosen development process is flawed. Major overhauls of existing library APIs or conventions should be going through an RFC so the community has a chance to give input. A steering committee should make the final call after hearing all of the facts / opinions, not micro-manage the whole design. |
Oh what I thinking, the associated items RFC includes associated types, that can be used instead of an associated static: impl<T> Vec<T> {
pub type raw = VecRawConstructor<T>;
// ...
}
pub struct VecRawConstructor<T>;
impl<T> VecRawConstructor<T> {
pub fn from_parts(&self, length: uint, capacity: uint, ptr: *mut T) -> Vec<T> { ... }
}
fn example_usage() {
let (len, cap, ptr) = ...;
let v = unsafe { Vec::raw::from_parts(len, cap, ptr) };
// ...
} |
It seems to be a simple tooling issue -- fix it in rustdoc. You wouldn't put "hard to use" but safe methods in a separate submodule, so why here. |
60d3d81
to
347500a
Compare
347500a
to
13341ae
Compare
13341ae
to
28b0485
Compare
28b0485
to
6e7cf52
Compare
6e7cf52
to
ef4c913
Compare
ef4c913
to
56bf2e2
Compare
The following methods, types, and names have become stable: * Vec * Vec::as_mut_slice * Vec::as_slice * Vec::capacity * Vec::clear * Vec::default * Vec::grow * Vec::insert * Vec::len * Vec::new * Vec::pop * Vec::push * Vec::remove * Vec::set_len * Vec::shrink_to_fit * Vec::truncate * Vec::with_capacity The following have become unstable: * Vec::dedup // naming * Vec::from_fn // naming and unboxed closures * Vec::get_mut // will be removed for IndexMut * Vec::grow_fn // unboxed closures and naming * Vec::retain // unboxed closures * Vec::swap_remove // uncertain naming * Vec::from_elem // uncertain semantics * vec::unzip // should be generic for all collections The following have been deprecated * Vec::append - call .extend() * Vec::append_one - call .push() * Vec::from_slice - call .to_vec() * Vec::grow_set - call .grow() and then .push() * Vec::into_vec - move the vector instead * Vec::move_iter - renamed to iter_move() * Vec::to_vec - call .clone() The following methods remain experimental pending conventions * vec::raw * vec::raw::from_buf * Vec:from_raw_parts * Vec::push_all This is a breaking change in terms of the signature of the `Vec::grow` function. The argument used to be taken by reference, but it is now taken by value. Code must update by removing a leading `&` sigil or by calling `.clone()` to create a value. [breaking-change]
56bf2e2
to
0169218
Compare
The following methods, types, and names have become stable: * Vec * Vec::as_mut_slice * Vec::as_slice * Vec::capacity * Vec::clear * Vec::default * Vec::grow * Vec::insert * Vec::len * Vec::new * Vec::pop * Vec::push * Vec::remove * Vec::set_len * Vec::shrink_to_fit * Vec::truncate * Vec::with_capacity * vec::raw * vec::raw::from_buf * vec::raw::from_raw_parts The following have become unstable: * Vec::dedup // naming * Vec::from_fn // naming and unboxed closures * Vec::get_mut // will be removed for IndexMut * Vec::grow_fn // unboxed closures and naming * Vec::retain // unboxed closures * Vec::swap_remove // uncertain naming * Vec::from_elem // uncertain semantics * vec::unzip // should be generic for all collections The following have been deprecated * Vec::append - call .extend() * Vec::append_one - call .push() * Vec::from_slice - call .to_vec() * Vec::grow_set - call .grow() and then .push() * Vec::into_vec - move the vector instead * Vec::move_iter - renamed to iter_move() * Vec::push_all - call .extend() * Vec::to_vec - call .clone() * Vec:from_raw_parts - moved to raw::from_raw_parts This is a breaking change in terms of the signature of the `Vec::grow` function. The argument used to be taken by reference, but it is now taken by value. Code must update by removing a leading `&` sigil or by calling `.clone()` to create a value. [breaking-change]
Revert "Use jemalloc for releases" This reverts commit 692c41e: https://github.com/rust-lang/rust-analyzer/actions/runs/8592641551/job/23542950551.
Revert "Use jemalloc for releases" This reverts commit 692c41e: https://github.com/rust-lang/rust-analyzer/actions/runs/8592641551/job/23542950551.
The following methods, types, and names have become stable:
The following have become unstable:
The following have been deprecated
This is a breaking change in terms of the signature of the
Vec::grow
function.The argument used to be taken by reference, but it is now taken by value. Code
must update by removing a leading
&
sigil or by calling.clone()
to create avalue.
[breaking-change]