-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Stabilize Vec::new
and String::new
as const fn
s
#64028
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,13 +113,38 @@ impl<T, A: Alloc> RawVec<T, A> { | |
} | ||
|
||
impl<T> RawVec<T, Global> { | ||
/// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform | ||
/// to `min_const_fn` and so they cannot be called in `min_const_fn`s either. | ||
/// | ||
/// If you change `RawVec<T>::new` or dependencies, please take care to not | ||
/// introduce anything that would truly violate `min_const_fn`. | ||
/// | ||
/// NOTE: We could avoid this hack and check conformance with some | ||
/// `#[rustc_force_min_const_fn]` attribute which requires conformance | ||
/// with `min_const_fn` but does not necessarily allow calling it in | ||
/// `stable(...) const fn` / user code not enabling `foo` when | ||
/// `#[rustc_const_unstable(feature = "foo", ..)]` is present. | ||
pub const NEW: Self = Self::new(); | ||
|
||
/// Creates the biggest possible `RawVec` (on the system heap) | ||
/// without allocating. If `T` has positive size, then this makes a | ||
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a | ||
/// `RawVec` with capacity `usize::MAX`. Useful for implementing | ||
/// delayed allocation. | ||
pub const fn new() -> Self { | ||
Self::new_in(Global) | ||
// FIXME(Centril): Reintegrate this with `fn new_in` when we can. | ||
|
||
// `!0` is `usize::MAX`. This branch should be stripped at compile time. | ||
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`: | ||
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 }; | ||
|
||
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation". | ||
RawVec { | ||
ptr: Unique::empty(), | ||
// FIXME(mark-i-m): use `cap` when ifs are allowed in const | ||
cap: [0, !0][(mem::size_of::<T>() == 0) as usize], | ||
a: Global, | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ecstatic-morse @oli-obk are you keeping a list somewhere for all the awful hacks we have in libstd to work around const qualif limitations? This would be another one (there's also #63786). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should have a special string for "const related awful hack"? We can make an issue also... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also just tag PRs like this as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're going with a label, I'd make it a bit more general: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Presumably there could be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ecstatic-morse I was wondering if we couldn't use one label for all of them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't care so much. I thought it would be easier to go back and remove the labels if we know exactly which limitation is being worked around, but the absence of conditionals is probably the only thing that can be circumvented with these kinds of hacks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a todo entry for reviewing all const fns after we get loops and conditions, I'm certain we'll miss some by whitelisting what to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
/// Creates a `RawVec` (on the system heap) with exactly the | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,11 @@ | ||
// run-pass | ||
// check-pass | ||
|
||
#![allow(dead_code)] | ||
// Test several functions can be used for constants | ||
// 1. Vec::new() | ||
// 2. String::new() | ||
|
||
#![feature(const_vec_new)] | ||
#![feature(const_string_new)] | ||
|
||
const MY_VEC: Vec<usize> = Vec::new(); | ||
|
||
const MY_STRING: String = String::new(); | ||
|
||
pub fn main() {} | ||
fn main() {} |
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.
I'm pretty unhappy about this hack since I think carries the risk that we might stabilize things we don't want in const eval inadvertently and I have WIP more principled solution in /~https://github.com/Centril/rust/commits/stabilize-vec-new-const which I think we should seriously consider instead (but which can change into after this PR if necessary).