RFC 2070 part 1: PanicInfo and Location API changes
This implements part of https://rust-lang.github.io/rfcs/2070-panic-implementation.html
Tracking issue: https://github.com/rust-lang/rust/issues/44489
* Move `std::panic::PanicInfo` and `std::panic::Location` to a new `core::panic` module. The two types and the `std` module were already `#[stable]` and stay that way, the new `core` module is `#[unstable]`.
* Add a new `PanicInfo::message(&self) -> Option<&fmt::Arguments>` method, which is `#[unstable]`.
* Implement `Display` for `PanicInfo` and `Location`
Remove "empty buffer" doc in read_until
This appears copied from fill_buf, but the above paragraph already indicates that a lack of delimiter at the end is EOF.
Primitive docs relevant
This fixes the documentation to show the right types in the examples for many integer methods.
I need to check if the result is correct before we merge.
This is the ideal FileType on Windows. You may not like it, but this is what peak performance looks like.
Theoretically this would fix https://github.com/rust-lang/rust/issues/46484
The current iteration of this PR should not cause existing code to break, but instead merely improves handling around reparse points. Specifically...
* Reparse points are considered to be symbolic links if they have the name surrogate bit set. Name surrogates are reparse points that effectively act like symbolic links, redirecting you to a different directory/file. By checking for this bit instead of specific tags, we become much more general in our handling of reparse points, including those added by third parties.
* If something is a reparse point but does not have the name surrogate bit set, then we ignore the fact that it is a reparse point because it is actually a file or directory directly there, despite having additional handling by drivers due to the reparse point.
* For everything which is not a symbolic link (including non-surrogate reparse points) we report whether it is a directory or a file based on the presence of the directory attribute bit.
* Notably this still preserves invariant that when `is_symlink` returns `true`, both `is_dir` and `is_file` will return `false`. The potential for breakage was far too high.
* Adds an unstable `FileTypeExt` to allow users to determine whether a symbolic link is a directory or a file, since `FileType` by design is incapable of reporting this information.
Early exit for empty HashMap (issue #38880)
Addresses issue #38880 by checking if the HashMap is empty before computing the value of the hash.
Before (integer keys)
```
running 4 tests
test empty_once ... bench: 13 ns/iter (+/- 0)
test empty_100 ... bench: 1,367 ns/iter (+/- 35)
test exist_once ... bench: 14 ns/iter (+/- 0)
test exist_100 ... bench: 1,518 ns/iter (+/- 40)
```
After
```
running 4 tests
test empty_once ... bench: 2 ns/iter (+/- 0)
test empty_100 ... bench: 221 ns/iter (+/- 0)
test exist_once ... bench: 15 ns/iter (+/- 0)
test exist_100 ... bench: 1,515 ns/iter (+/- 92)
```
When the HashMap is not empty, the performance remains the same, and when it is empty the performance is significantly improved.
Correct a few stability attributes
* `core_float_bits`, `duration_core`, `path_component_asref`, and `repr_align` were stabalized in 1.25.0 not 1.24.0.
* Impls for `NonNull` involving unstable things should remain unstable.
* `Duration` should remain stable since 1.3.0 so it appears correctly in the `std` docs.
* `cursor_mut_vec` is an impl on only stable things so should be marked stable.
Document std::os::raw.
This adds a brief explanation to each type and its definition according to C. This also helps clarify that the definitions of the types, as described by rustdoc, are not necessarily the same from platform to platform.
Use a range to identify SIGSEGV in stack guards
Previously, the `guard::init()` and `guard::current()` functions were
returning a `usize` address representing the top of the stack guard,
respectively for the main thread and for spawned threads. The `SIGSEGV`
handler on `unix` targets checked if a fault was within one page below that
address, if so reporting it as a stack overflow.
Now `unix` targets report a `Range<usize>` representing the guard memory,
so it can cover arbitrary guard sizes. Non-`unix` targets which always
return `None` for guards now do so with `Option<!>`, so they don't pay any
overhead.
For `linux-gnu` in particular, the previous guard upper-bound was
`stackaddr + guardsize`, as the protected memory was *inside* the stack.
This was a glibc bug, and starting from 2.27 they are moving the guard
*past* the end of the stack. However, there's no simple way for us to know
where the guard page actually lies, so now we declare it as the whole range
of `stackaddr ± guardsize`, and any fault therein will be called a stack
overflow. This fixes#47863.
Implement extensible syscall interface for wasm
Currently it's possible to run tests with the native wasm target, but it's not possible to tell whether they pass or to capture the output, because libstd throws away stdout, stderr and the exit code. While advanced libstd features should probably require more specific targets (eg. wasm-unknown-web) I think even the unknown target should at least support basic I/O.
Any solution is constrained by these factors:
- It must not be javascript specific
- There must not be too strong coupling between libstd and the host environment (because it's an "unknown" target)
- WebAssembly does not allow "optional" imports - all imports *must* be resolved.
- WebAssembly does not support calling the host environment through any channel *other* than imports.
The best solution I could find to these constraints was to give libstd a single required import, and implement a syscall-style interface through that import. Each syscall is designed such that a no-op implementation gives the most reasonable fallback behaviour. This means that the following import table would be perfectly valid:
```javascript
imports.env = { rust_wasm_syscall: function(index, data) {} }
```
Currently I have implemented these system calls:
- Read from stdin
- Write to stdout/stderr
- Set the exit code
- Get command line arguments
- Get environment variable
- Set environment variable
- Get time
It need not be extended beyond this set if being able to run tests for this target is the only goal.
edit:
As part of this PR I had to make a further change. Previously, the rust entry point would be automatically called when the webassembly module was instantiated. This was problematic because from the javascript side it was impossible to call exported functions, access program memory or get a reference to the instance.
To solve this, ~I changed the default behaviour to not automatically call the entry point, and added a crate-level attribute to regain the old behaviour. (`#![wasm_auto_run]`)~ I disabled this behaviour when building tests.