Clarify the guarantees of Vec::as_ptr and Vec::as_mut_ptr when there's no allocation
Currently the documentation says they return a pointer to the vector's buffer, which has the implied precondition that the vector allocated some memory. However `Vec`'s documentation also specifies that it won't always allocate, so it's unclear whether the pointer returned is valid in that case. Of course you won't be able to read/write actual bytes to/from it since the capacity is 0, but there's an exception: zero sized read/writes. They are still valid as long as the pointer is not null and the memory it points to wasn't deallocated, but `Vec::as_ptr` and `Vec::as_mut_ptr` don't specify that's not the case. This PR thus specifies they are actually valid for zero sized reads since `Vec` is implemented to hold a dangling pointer in those cases, which is neither null nor was deallocated.
Add unicode fast path to `is_printable`
Before, it would enter the full expensive check even for normal ascii characters. Now, it skips the check for the ascii characters in `32..127`. This range was checked manually from the current behavior.
I ran the `tracing` test suite in miri, and it was really slow. I looked at a profile, and miri spent most of the time in `core::char::methods::escape_debug_ext`, where half of that was dominated by `core::unicode::printable::is_printable`. So I optimized it here.
The tracing profile:
![The tracing profile](https://user-images.githubusercontent.com/48135649/170883650-23876e7b-3fd1-4e8b-9001-47672e06d914.svg)
Before, it would enter the full expensive check even for normal ascii
characters. Now, it skips the check for the ascii characters in
`32..127`. This range was checked manually from the current behavior.
Rollup of 6 pull requests
Successful merges:
- #97089 (Improve settings theme display)
- #97229 (Document the current aliasing rules for `Box<T>`.)
- #97371 (Suggest adding a semicolon to a closure without block)
- #97455 (Stabilize `toowned_clone_into`)
- #97565 (Add doc alias `memset` to `write_bytes`)
- #97569 (Remove `memset` alias from `fill_with`.)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Add doc alias `memset` to `write_bytes`
I were looking for `memset` in rust, but the docs only pointed me to `slice::fill`.
With only the old aliases, one might write code like this, which is incorrect if the memory is uninitialized.
``` Rust
core::slice::from_raw_parts(ptr, len).fill(0)
```
Document the current aliasing rules for `Box<T>`.
Currently, `Box<T>` gets `noalias`, meaning it has the same rules as `&mut T`. This is sparsely documented, even though it can have quite a big impact on unsafe code using box. Therefore, these rules are documented here, with a big warning that they are not normative and subject to change, since we have not yet committed to an aliasing model and the state of `Box<T>` is especially uncertain.
If you have any suggestions and improvements, make sure to leave them here. This is mostly intended to inform people about what is currently going on (to prevent misunderstandings such as [Jon Gjengset's Box aliasing](https://www.youtube.com/watch?v=EY7Wi9fV5bk)).
This is supposed to _only document current UB_ and not add any new guarantees or rules.
Implement [OsStr]::join
Implements join for `OsStr` and `OsString` slices:
```Rust
let strings = [OsStr::new("hello"), OsStr::new("dear"), OsStr::new("world")];
assert_eq!("hello dear world", strings.join(OsStr::new(" ")));
````
This saves one from converting to strings and back, or from implementing it manually.
This PR has been re-filed after #96744 was first accidentally merged and then reverted.
The change is instantly stable and thus:
r? rust-lang/libs-api `@rustbot` label +T-libs-api -T-libs
cc `@thomcc` `@m-ou-se` `@faptc`
refactor: VecDeques Iter fields to private
Made the fields of VecDeque's Iter private by creating a Iter::new(...) function to create a new instance of Iter and migrating usage to use Iter::new(...).
improve format impl for literals
The basic idea of this change can be seen here https://godbolt.org/z/MT37cWoe1.
Updates the format impl to have a fast path for string literals and the default path for regular format args.
This change will allow `format!("string literal")` to be used interchangably with `"string literal".to_owned()`.
This would be relevant in the case of `f!"string literal"` being legal (https://github.com/rust-lang/rfcs/pull/3267) in which case it would be the easiest way to create owned strings from literals, while also being just as efficient as any other impl
Remove "sys isn't exported yet" phrase
The oldest occurence is from 9e224c2bf1,
which is from the pre-1.0 days. In the years since then, std::sys still
hasn't been exported, and the last attempt was met with strong criticism:
https://github.com/rust-lang/rust/pull/97151
Thus, removing the "yet" part makes a lot of sense.
Use Box::new() instead of box syntax in library tests
The tests inside `library/*` have no reason to use `box` syntax as they have 0 performance relevance. Therefore, we can safely remove them (instead of having to use alternatives like the one in #97293).
The oldest occurence is from 9e224c2bf1,
which is from the pre-1.0 days. In the years since then, std::sys still
hasn't been exported, and the last attempt was met with strong criticism:
https://github.com/rust-lang/rust/pull/97151
Thus, removing the "yet" part makes a lot of sense.
Replace `#[default_method_body_is_const]` with `#[const_trait]`
pulled out of #96077
related issues: #67792 and #92158
cc `@fee1-dead`
This is groundwork to only allowing `impl const Trait` for traits that are marked with `#[const_trait]`. This is necessary to prevent adding a new default method from becoming a breaking change (as it could be a non-const fn).
Finish bumping stage0
It looks like the last time had left some remaining cfg's -- which made me think
that the stage0 bump was actually successful. This brings us to a released 1.62
beta though.
This now brings us to cfg-clean, with the exception of check-cfg-features in bootstrap;
I'd prefer to leave that for a separate PR at this time since it's likely to be more tricky.
cc https://github.com/rust-lang/rust/pull/97147#issuecomment-1132845061
r? `@pietroalbini`
ptr::invalid is not equivalent to a int2ptr cast
I just realized I forgot to update these docs when adding `from_exposed_addr`.
Right now the docs say `invalid` and `from_exposed_addr` are both equivalent to a cast, and that is clearly not what we want.
Cc ``@Gankra``
update libbacktrace
It seems like previously we were on a tag of the backtrace repo; not sure if there is a policy that it should always be a tag?
Cc https://github.com/rust-lang/backtrace-rs/pull/462 `@alexcrichton` `@DrMeepster`
proc_macro: don't pass a client-side function pointer through the server.
Before this PR, `proc_macro::bridge::Client<F>` contained both:
* the C ABI entry-point `run`, that the server can call to start the client
* some "payload" `f: F` passed to that entry-point
* in practice, this was always a (client-side Rust ABI) `fn` pointer to the actual function the proc macro author wrote, i.e. `#[proc_macro] fn foo(input: TokenStream) -> TokenStream`
In other words, the client was passing one of its (Rust) `fn` pointers to the server, which was passing it back to the client, for the client to call (see later below for why that was ever needed).
I was inspired by `@nnethercote's` attempt to remove the `get_handle_counters` field from `Client` (see https://github.com/rust-lang/rust/pull/97004#issuecomment-1139273301), which combined with removing the `f` ("payload") field, could theoretically allow for a `#[repr(transparent)]` `Client` that mostly just newtypes the C ABI entry-point `fn` pointer <sub>(and in the context of e.g. wasm isolation, that's *all* you want, since you can reason about it from outside the wasm VM, as just a 32-bit "function table index", that you can pass to the wasm VM to call that function)</sub>.
<hr/>
So this PR removes that "payload". But it's not a simple refactor: the reason the field existed in the first place is because monomorphizing over a function type doesn't let you call the function without having a value of that type, because function types don't implement anything like `Default`, i.e.:
```rust
extern "C" fn ffi_wrapper<A, R, F: Fn(A) -> R>(arg: A) -> R {
let f: F = ???; // no way to get a value of `F`
f(arg)
}
```
That could be solved with something like this, if it was allowed:
```rust
extern "C" fn ffi_wrapper<
A, R,
F: Fn(A) -> R,
const f: F // not allowed because the type is a generic param
>(arg: A) -> R {
f(arg)
}
```
Instead, this PR contains a workaround in `proc_macro::bridge::selfless_reify` (see its module-level comment for more details) that can provide something similar to the `ffi_wrapper` example above, but limited to `F` being `Copy` and ZST (and requiring an `F` value to prove the caller actually can create values of `F` and it's not uninhabited or some other unsound situation).
<hr/>
Hopefully this time we don't have a performance regression, and this has a chance to land.
cc `@mystor` `@bjorn3`
Partially stabilize `(const_)slice_ptr_len` feature by stabilizing `NonNull::len`
This PR partially stabilizes features `const_slice_ptr_len` and `slice_ptr_len` by only stabilizing `NonNull::len`. This partial stabilization is tracked under features `slice_ptr_len_nonnull` and `const_slice_ptr_len_nonnull`, for which this PR can serve as the tracking issue.
To summarize the discussion from #71146 leading up to this partial stabilization request:
It's currently a bit footgunny to obtain the length of a raw slice pointer, stabilization of `NonNull:len` will help with removing these footguns. Some example footguns are:
```rust
/// # Safety
/// The caller must ensure that `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. is within the bounds of a single allocated object;
/// 3. does not to point to a slice for which the length exceeds `isize::MAX` bytes;
/// 4. points to a properly aligned address;
/// 5. does not point to uninitialized memory;
/// 6. does not point to a mutably borrowed memory location.
pub unsafe fn ptr_len<T>(ptr: core::ptr::NonNull<[T]>) -> usize {
(&*ptr.as_ptr()).len()
}
```
A slightly less complicated version (but still more complicated than it needs to be):
```rust
/// # Safety
/// The caller must ensure that the start of `ptr`:
/// 1. does not point to memory that was previously allocated but is now deallocated;
/// 2. must be within the bounds of a single allocated object.
pub unsafe fn ptr_len<T>(ptr: NonNull<[T]>) -> usize {
(&*(ptr.as_ptr() as *const [()])).len()
}
```
This PR does not stabilize `<*const [T]>::len` and `<*mut [T]>::len` because the tracking issue #71146 list a potential blocker for these methods, but this blocker [does not apply](https://github.com/rust-lang/rust/issues/71146#issuecomment-808735714) to `NonNull::len`.
We should probably also ping the [Constant Evaluation WG](https://github.com/rust-lang/const-eval) since this PR includes a `#[rustc_allow_const_fn_unstable(const_slice_ptr_len)]`. My instinct here is that this will probably be okay because the pointer is not actually dereferenced and `len()` does not touch the address component of the pointer, but would be best to double check :)
One potential down-side was raised that stabilizing `NonNull::len` could lead to encouragement of coding patterns like:
```
pub fn ptr_len<T>(ptr: *mut [T]) -> usize {
NonNull::new(ptr).unwrap().len()
}
```
which unnecessarily assert non-nullness. However, these are much less of a footgun than the above examples and this should be resolved when `slice_ptr_len` fully stabilizes eventually.
Remove impossible panic note from `Vec::append`
Neither the number of elements in a vector can overflow a `usize`, nor
can the amount of elements in two vectors.
It looks like the last time had left some remaining cfg's -- which made me think
that the stage0 bump was actually successful. This brings us to a released 1.62
beta though.