Fix calling convention for CRT startup
My PR #81478 used the wrong calling convention for a set of
functions that are called by the CRT. These functions need to use
`extern "C"`.
This would only affect x86, which is the only target (that I know of)
that has multiple calling conventions.
```@bors``` r? ```@m-ou-se```
Let io::copy reuse BufWriter buffers
This optimization will allow users to implicitly set the buffer size for io::copy by wrapping the writer into a `BufWriter` if the default block size is insufficient, which should fix#49921
Due to min_specialization limitations this approach only works with `BufWriter` but not for `BufReader<R>` since `R` is unconstrained and thus the necessary specialization on `R: Read` is not always applicable. Once specialization becomes more powerful this optimization could be extended to look at the reader and writer side and use whichever buffer is larger.
Implement Rust 2021 panic
This implements the Rust 2021 versions of `panic!()`. See https://github.com/rust-lang/rust/issues/80162 and https://github.com/rust-lang/rfcs/pull/3007.
It does so by replacing `{std, core}::panic!()` by a bulitin macro that expands to either `$crate::panic::panic_2015!(..)` or `$crate::panic::panic_2021!(..)` depending on the edition of the caller.
This does not yet make std's panic an alias for core's panic on Rust 2021 as the RFC proposes. That will be a separate change: c5273bdfb2 That change is blocked on figuring out what to do with https://github.com/rust-lang/rust/issues/80846 first.
My PR #81478 used the wrong calling convention for a set of
functions that are called by the CRT. These functions need to use
`extern "C"`.
This would only affect x86, which is the only target (that I know of)
that has multiple calling conventions.
Resolve DLL imports at CRT startup, not on demand
On Windows, libstd uses GetProcAddress to locate some DLL imports, so
that libstd can run on older versions of Windows. If a given DLL import
is not present, then libstd uses other behavior (such as fallback
implementations).
This commit uses a feature of the Windows CRT to do these DLL imports
during module initialization, before main() (or DllMain()) is called.
This is the ideal time to resolve imports, because the module is
effectively single-threaded at that point; no other threads can
touch the data or code of the module that is being initialized.
This avoids several problems. First, it makes the cost of performing
the DLL import lookups deterministic. Right now, the DLL imports are
done on demand, which means that application threads _might_ have to
do the DLL import during some time-sensitive operation. This is a
small source of unpredictability. Since threads can race, it's even
possible to have more than one thread running the same redundant
DLL lookup.
This commit also removes using the heap to allocate strings, during
the DLL lookups.
Stabilize raw ref macros
This stabilizes `raw_ref_macros` (https://github.com/rust-lang/rust/issues/73394), which is possible now that https://github.com/rust-lang/rust/issues/74355 is fixed.
However, as I already said in https://github.com/rust-lang/rust/issues/73394#issuecomment-751342185, I am not particularly happy with the current names of the macros. So I propose we also change them, which means I am proposing to stabilize the following in `core::ptr`:
```rust
pub macro const_addr_of($e:expr) {
&raw const $e
}
pub macro mut_addr_of($e:expr) {
&raw mut $e
}
```
The macro name change means we need another round of FCP. Cc `````@rust-lang/libs`````
Fixes#73394
Add `core::stream::Stream`
[[Tracking issue: #79024](https://github.com/rust-lang/rust/issues/79024)]
This patch adds the `core::stream` submodule and implements `core::stream::Stream` in accordance with [RFC2996](https://github.com/rust-lang/rfcs/pull/2996). The RFC hasn't been merged yet, but as requested by the libs team in https://github.com/rust-lang/rfcs/pull/2996#issuecomment-725696389 I'm filing this PR to get the ball rolling.
## Documentatation
The docs in this PR have been adapted from [`std::iter`](https://doc.rust-lang.org/std/iter/index.html), [`async_std::stream`](https://docs.rs/async-std/1.7.0/async_std/stream/index.html), and [`futures::stream::Stream`](https://docs.rs/futures/0.3.8/futures/stream/trait.Stream.html). Once this PR lands my plan is to follow this up with PRs to add helper methods such as `stream::repeat` which can be used to document more of the concepts that are currently missing. That will allow us to cover concepts such as "infinite streams" and "laziness" in more depth.
## Feature gate
The feature gate for `Stream` is `stream_trait`. This matches the `#[lang = "future_trait"]` attribute name. The intention is that only the APIs defined in RFC2996 will use this feature gate, with future additions such as `stream::repeat` using their own feature gates. This is so we can ensure a smooth path towards stabilizing the `Stream` trait without needing to stabilize all the APIs in `core::stream` at once. But also don't start expanding the API until _after_ stabilization, as was the case with `std::future`.
__edit:__ the feature gate has been changed to `async_stream` to match the feature gate proposed in the RFC.
## Conclusion
This PR introduces `core::stream::{Stream, Next}` and re-exports it from `std` as `std::stream::{Stream, Next}`. Landing `Stream` in the stdlib has been a mult-year process; and it's incredibly exciting for this to finally happen!
---
r? `````@KodrAus`````
cc/ `````@rust-lang/wg-async-foundations````` `````@rust-lang/libs`````
On Windows, libstd uses GetProcAddress to locate some DLL imports, so
that libstd can run on older versions of Windows. If a given DLL import
is not present, then libstd uses other behavior (such as fallback
implementations).
This commit uses a feature of the Windows CRT to do these DLL imports
during module initialization, before main() (or DllMain()) is called.
This is the ideal time to resolve imports, because the module is
effectively single-threaded at that point; no other threads can
touch the data or code of the module that is being initialized.
This avoids several problems. First, it makes the cost of performing
the DLL import lookups deterministic. Right now, the DLL imports are
done on demand, which means that application threads _might_ have to
do the DLL import during some time-sensitive operation. This is a
small source of unpredictability. Since threads can race, it's even
possible to have more than one thread running the same redundant
DLL lookup.
This commit also removes using the heap to allocate strings, during
the DLL lookups.
Stabilize `Seek::stream_position` (feature `seek_convenience`)
Tracking issue: #59359
Unresolved questions from tracking issue:
- "Override `stream_len` for `File`?" → we can do that in the future, this does not block stabilization.
- "Rename to `len` and `position`?" → as noted in the tracking issue, both of these shorter names have problems (`len` is usually a cheap getter, `position` clashes with `Cursor`). I do think the current names are perfectly fine.
- "Rename `stream_position` to `tell`?" → as mentioned in [the comment bringing this up](https://github.com/rust-lang/rust/issues/59359#issuecomment-559541545), `stream_position` is more descriptive. I don't think `tell` would be a good name.
What remains to decide, is whether or not adding these methods is worth it.
Trying to shrink_to greater than capacity should be no-op
Per the discussion in https://github.com/rust-lang/rust/issues/56431, `shrink_to` shouldn't panic if you try to make a vector shrink to a capacity greater than its current capacity.
Make std::future a re-export of core::future
After 1a764a7ef5, there are no `std::future`-specific items (except for `cfg(bootstrap)` items removed in 93eed402ad). So, instead of defining `std` own module, we can re-export the `core::future` directly.
Implement Error for &(impl Error)
Opening this up just to see what it breaks. It's unfortunate that `&(impl Error)` doesn't actually implement `Error`. If this direct approach doesn't work out then I'll try something different, like an `Error::by_ref` method.
**EDIT:** This is a super low-priority experiment so feel free to cancel it for more important crater runs! 🙂
-----
# Stabilization Report
## Why?
We've been working for the last few years to try "fix" the `Error` trait, which is probably one of the most fundamental in the whole standard library. One of its issues is that we commonly expect you to work with abstract errors through `dyn Trait`, but references and smart pointers over `dyn Trait` don't actually implement the `Error` trait. If you have a `&dyn Error` or a `Box<dyn Error>` you simply can't pass it to a method that wants a `impl Error`.
## What does this do?
This stabilizes the following trait impl:
```rust
impl<'a, T: Error + ?Sized + 'static> Error for &'a T;
```
This means that `&dyn Error` will now satisfy a `impl Error` bound.
It doesn't do anything with `Box<dyn Error>` directly. We discussed how we could do `Box<dyn Error>` in the thread here (and elsewhere in the past), but it seems like we need something like lattice-based specialization or a sprinkling of snowflake compiler magic to make that work. Having said that, with this new impl you _can_ now get a `impl Error` from a `Box<dyn Error>` by dereferencing it.
## What breaks?
A crater run revealed a few crates broke with something like the following:
```rust
// where e: &'short &'long dyn Error
err.source()
```
previously we'd auto-deref that `&'short &'long dyn Error` to return a `Option<&'long dyn Error>` from `source`, but now will call directly on `&'short impl Error`, so will return a `Option<&'short dyn Error>`. The fix is to manually deref:
```rust
// where e: &'short &'long dyn Error
(*err).source()
```
In the recent Libs meeting we considered this acceptable breakage.
Remove delay-binding for Win XP and Vista
The minimum supported Windows version is now Windows 7. Windows XP
and Windows Vista are no longer supported; both are already broken, and
require extra steps to use.
This commit removes the delayed-binding support for Windows API
functions that are present on all supported Windows targets. This has
several benefits: Removes needless complexity. Removes a load and
dynamic call on hot paths in mutex acquire / release. This may have
performance benefits.
* "Drop official support for Windows XP"
https://github.com/rust-lang/compiler-team/issues/378
* "Firefox has ended support for Windows XP and Vista"
https://support.mozilla.org/en-US/kb/end-support-windows-xp-and-vista
Inline methods of Path and OsString
These methods are not generic, and therefore aren't candidates for cross-crate inlining without an `#[inline]` attribute.
Document why not use concat! in dbg! macro
Original title: Reduce code generated by `dbg!` macro
The expanded code before/after: <https://rust.godbolt.org/z/hE3j95>.
---
We cannot use `concat!` since `file!` could contains `{` or the expression is a block (`{ .. }`).
Using it will generated malformed format strings.
So let's document this reason why we don't use `concat!` macro at all.
The minimum supported Windows version is now Windows 7. Windows XP
and Windows Vista are no longer supported; both are already broken, and
require extra steps to use.
This commit removes the delayed-binding support for Windows API
functions that are present on all supported Windows targets. This has
several benefits: Removes needless complexity. Removes a load and
dynamic call on hot paths in mutex acquire / release. This may have
performance benefits.
* "Drop official support for Windows XP"
https://github.com/rust-lang/compiler-team/issues/378
* "Firefox has ended support for Windows XP and Vista"
https://support.mozilla.org/en-US/kb/end-support-windows-xp-and-vista
std: Update wasi-libc commit of the wasm32-wasi target
This brings in an implementation of `current_dir` and `set_current_dir`
(emulation in `wasi-libc`) as well as an updated version of finding
relative paths. This also additionally updates clang to the latest
release to build wasi-libc with.
BufWriter: Provide into_raw_parts
If something goes wrong, one might want to unpeel the layers of nested
Writers to perform recovery actions on the underlying writer, or reuse
its resources.
`into_inner` can be used for this when the inner writer is still
working. But when the inner writer is broken, and returning errors,
`into_inner` simply gives you the error from flush, and the same
`Bufwriter` back again.
Here I provide the necessary function, which I have chosen to call
`into_raw_parts`.
I had to do something with `panicked`. Returning it to the caller as
a boolean seemed rather bare. Throwing the buffered data away in this
situation also seems unfriendly: maybe the programmer knows something
about the underlying writer and can recover somehow.
So I went for a custom Error. This may be overkill, but it does have
the nice property that a caller who actually wants to look at the
buffered data, rather than simply extracting the inner writer, will be
told by the type system if they forget to handle the panicked case.
If a caller doesn't need the buffer, it can just be discarded. That
WriterPanicked is a newtype around Vec<u8> means that hopefully the
layouts of the Ok and Err variants can be very similar, with just a
boolean discriminant. So this custom error type should compile down
to nearly no code.
*If this general idea is felt appropriate, I will open a tracking issue, etc.*
Don't use posix_spawn_file_actions_addchdir_np on macOS.
There is a bug on macOS where using `posix_spawn_file_actions_addchdir_np` with a relative executable path will cause `posix_spawnp` to return ENOENT, even though it successfully spawned the process in the given directory.
`posix_spawn_file_actions_addchdir_np` was introduced in macOS 10.15 first released in Oct 2019. I have tested macOS 10.15.7 and 11.0.1.
Example offending program:
```rust
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::*;
fn main() {
fs::create_dir_all("bar").unwrap();
fs::create_dir_all("foo").unwrap();
fs::write("foo/foo.sh", "#!/bin/sh\necho hello ${PWD}\n").unwrap();
let perms = fs::Permissions::from_mode(0o755);
fs::set_permissions("foo/foo.sh", perms).unwrap();
let c = Command::new("../foo/foo.sh").current_dir("bar").spawn();
eprintln!("{:?}", c);
}
```
This prints:
```
Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })
hello /Users/eric/Temp/bar
```
I wanted to open this PR to get some feedback on possible solutions. Alternatives:
* Do nothing.
* Document the bug.
* Try to detect if the executable is a relative path on macOS, and avoid using `posix_spawn_file_actions_addchdir_np` only in that case.
I looked at the [XNU source code](https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/kern/kern_exec.c.auto.html), but I didn't see anything obvious that would explain the behavior. The actual chdir succeeds, it is something else further down that fails, but I couldn't see where.
EDIT: I forgot to mention, relative exe paths with `current_dir` in general are discouraged (see #37868). I don't know if #37868 is fixable, since normalizing it would change the semantics for some platforms. Another option is to convert the executable to an absolute path with something like joining the cwd with the new cwd and the executable, but I'm uncertain about that.
Clarify what the effects of a 'logic error' are
This clarifies what a 'logic error' is (which is a term used to describe what happens if you put things in a hash table or btree and then use something like a refcell to break the internal ordering). This tries to be as vague as possible, as we don't really want to promise what happens, except "bad things, but not UB". This was discussed in #80657