We used to write a temporary closure kind into the inference table, but
this could lead to obligations being incorrectled resolved before
inference had completed. This result could then be cached, leading to
further trouble. This patch avoids writing any closure kind until the
computation is complete.
Fixes#34349.
Added empty CloseDelim to tokens for future use.
Description says it all. I added a new DelimToken type, Empty, to indicate a Delimited tokenstream with no actual delimiters (which are variously useful for constructing macro output).
r? @nrc
The type equation in projection takes place under a binder and a snapshot, which
we can't easily take types out of. Instead, when encountering a projection error,
try to re-do the projection and find the type error then.
This fails to produce a sane type error when the failure was a "leak_check" failure.
I can't think of a sane way to show *these*, so I just left them use the old crappy
representation, and added a test to make sure we don't break them.
Refactor constant evaluation to use a single error reporting function
that reports a type-error-like message.
Also, unify all error codes with the "constant evaluation error" message
to just E0080, and similarly for a few other duplicate codes. The old
situation was a total mess, and now that we have *something* we can
further iterate on the UX.
Unfortunately, projection errors do not come with a nice set of
mismatched types. This is because the type equality check occurs
within a higher-ranked context. Therefore, only the type error
is reported. This is ugly but was always the situation.
I will introduce better errors for the lower-ranked case in
another commit.
Fixes the last known occurence of #31173
Add a method to the mpsc::Receiver for producing a non-blocking iterator
Currently, the `mpsc::Receiver` offers methods for receiving values in both blocking (`recv`) and non-blocking (`try_recv`) flavours. However only blocking iteration over values is supported. This PR adds a non-blocking iterator to complement the `try_recv` method, just as the blocking iterator complements the `recv` method.
Use-case
-------------
I predominantly use rust in my work on real-time systems and in particular real-time audio generation/processing. I use `mpsc::channel`s to communicate between threads in a purely non-blocking manner. I.e. I might send messages from the GUI thread to the audio thread to update the state of the dsp-graph, or from the audio thread to the GUI thread to display the RMS of each node. These are just a couple examples (I'm probably using 30+ channels across my various projects). I almost exclusively use the `mpsc::Receiver::try_recv` method to avoid blocking any of the real-time threads and causing unwanted glitching/stuttering. Now that I mention it, I can't think of a single time that I personally have used the `recv` method (though I can of course see why it would be useful, and perhaps the common case for many people).
As a result of this experience, I can't help but feel there is a large hole in the `Receiver` API.
| blocking | non-blocking |
|------------|--------------------|
| `recv` | `try_recv` |
| `iter` | 🙀 |
For the most part, I've been working around this using `while let Ok(v) = r.try_recv() { ... }`, however as nice as this is, it is clearly no match for the Iterator API.
As an example, in the majority of my channel use cases I only want to check for *n* number of messages before breaking from the loop so that I don't miss the audio IO callback or hog the GUI thread for too long when an unexpectedly large number of messages are sent. Currently, I have to write something like this:
```rust
let mut take = 100;
while let Ok(msg) = rx.try_recv() {
// Do stuff with msg
if take == 0 {
break;
}
take -= 1;
}
```
or wrap the `try_recv` call in a `Range<usize>`/`FilterMap` iterator combo.
On the other hand, this PR would allow for the following:
```rust
for msg in rx.try_iter().take(100) {
// Do stuff with msg
}
```
I imagine this might also be useful to game devs, embedded or anyone doing message passing across real-time threads.
Add MIR Optimization Tests
I've starting working on the infrastructure for testing MIR optimizations.
The plan now is to have a set of test cases (written in Rust), compile them with -Z dump-mir, and check the MIR before and after each pass.
feat: reinterpret `precision` field for strings
This commit changes the behavior of formatting string arguments with both width and precision fields set.
Documentation says that the `width` field is the "minimum width" that the format should take up. If the value's string does not fill up this many characters, then the padding specified by fill/alignment will be used to take up the required space.
This is true for all formatted types except string, which is truncated down to `precision` number of chars and then all of `fill`, `align` and `width` fields are completely ignored.
For example: `format!("{:/^10.8}", "1234567890);` emits "12345678". In the contrast Python version works as the expected:
```python
>>> '{:/^10.8}'.format('1234567890')
'/12345678/'
```
This commit gives back the `Python` behavior by changing the `precision` field meaning to the truncation and nothing more. The result string *will* be prepended/appended up to the `width` field with the proper `fill` char.
__However, this is the breaking change, I admit.__ Feel free to close it, but otherwise it should be mentioned in the `std::fmt` documentation somewhere near of `fill/align/width` fields description.
rustc: Remove soft-float from MIPS targets
Right now two MIPS targets in the compiler, `mips-unknown-linux-{gnu,musl}` both
generate object files using the soft-float ABI through LLVM by default. This is
also expressed as the `-C soft-float` codegen option and otherwise isn't used
for any other target in the compiler. This option was added quite some time ago
(back in #9617), and nowadays it's more appropriate to be done through a codegen
option.
This is motivated by #34743 which necessitated an upgrade in the CMake
installation on our bots which necessitated an upgrade in the Ubuntu version
which invalidated the MIPS compilers we were using. The new MIPS compilers
(coming from Debian I believe) all have hard float enabled by default and soft
float support not built in. This meant that we couldn't upgrade the bots
until #34841 landed because otherwise we would fail to compile C code as the
`-msoft-float` option wouldn't work.
Unfortunately, though, this means that once we upgrade the bots the C code we're
compiling will be compiled for hard float and the Rust code will be compiled
for soft float, a bad mismatch! This PR remedies the situation such that Rust
will compile with hard float as well.
If this lands it will likely produce broken nightlies for a day or two while we
get around to upgrading the bots because the current C toolchain only produces
soft-float binaries, and now rust will be hard-float. Hopefully, though, the
upgrade can go smoothly!
implement AddAssign for String
Currently `String` implements `Add` but not `AddAssign`. This PR fills in that gap.
I played around with having `AddAssign` (and `Add` and `push_str`) take `AsRef<str>` instead of `&str`, but it looks like that breaks arguments that implement `Deref<Target=str>` and not `AsRef<str>`. Comments in [`libcore/convert.rs`](https://github.com/rust-lang/rust/blob/master/src/libcore/convert.rs#L207-L213) make it sound like we could fix this with a blanket impl eventually. Does anyone know what's blocking that?
core: impl From<T> for Option<T>
First, the semantics of this `impl` seem spot on. If I have a value `T`, and I wish to make a `Option<T>`, then `Option::from(val)` should always give `Some(val)`.
Second, this allows improvement for several APIs that currently take `Option<T>` as arguments. Consider:
```rust
fn set_read_timeout(&mut self, timeout: Option<u32>) {
// ...
}
x.set_read_timeout(Some(30));
x.set_read_timeout(Some(10));
x.set_read_timeout(None);
```
With this `impl`:
```rust
fn set_read_timeout<T: Into<Option<u32>>>(&mut self, timeout: T) {
let timeout = timeout.into();
// ...
}
x.set_read_timeout(30);
x.set_read_timeout(10);
x.set_read_timeout(Some(10)); // backwards compatible
x.set_read_timeout(None);
```
The change to those methods aren't included, but could be modified later.
r? @sfackler