Rollup of 9 pull requests
Successful merges:
- #121201 (align_offset, align_to: no longer allow implementations to spuriously fail to align)
- #122076 (Tweak the way we protect in-place function arguments in interpreters)
- #122100 (Better comment for implicit captures in RPITIT)
- #122157 (Add the new description field to Target::to_json, and add descriptions for some MSVC targets)
- #122164 (Fix misaligned loads when loading UEFI arg pointers)
- #122171 (Add some new solver tests)
- #122172 (Don't ICE if we collect no RPITITs unless there are no unification errors)
- #122197 (inspect formatter: add braces)
- #122198 (Remove handling for previously dropped LLVM version)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't ICE if we collect no RPITITs unless there are no unification errors
Move an assertion in `collect_return_position_impl_trait_in_trait_tys` to after the `ObligationCtxt::eq` calls, so that we only assert and ICE if we have unification errors.
Fixes#121468
Fix misaligned loads when loading UEFI arg pointers
Currently, the two UEFI argument pointers are stored in an `alloca` of alignment 1, a pointer to which is then passed as `argv`. However, [the library code](9c3ad802d9/library/std/src/sys/pal/uefi/mod.rs (L60-L61)) treats `argv` as a pointer to an array of pointers and dereferences it as such, meaning that it presumes the `alloca` is aligned to at least the alignment of a pointer. This PR fixes this mismatch by aligning the `alloca` to the alignment of a pointer.
This PR also changed the `gep` to use the new `inbounds_ptradd` method.
Add the new description field to Target::to_json, and add descriptions for some MSVC targets
The original PR to add a `description` field to `Target` (<https://github.com/rust-lang/rust/pull/121905>) didn't add the field to `Target::to_json`, which meant that the `check_consistency` testwould fail if you tried to set a description as it wouldn't survive round-tripping via JSON: https://github.com/rust-lang/rust/actions/runs/8180997936/job/22370052535#step:27:4967
This change adds the field to `Target::to_json`, and sets some descriptions to verify that it works correctly.
Tweak the way we protect in-place function arguments in interpreters
Use `MPlaceTy` instead of `PlaceTy` in `FnArg` and ignore (copy) locals in an earlier step ("Locals that don't have their address taken are as protected as they can ever be").
This seems to be crucial for tail call support (as they can't refer to caller's locals which are killed when replacing the stack frame).
r? `@RalfJung`
cc `@oli-obk`
see https://github.com/rust-lang/rust/pull/121273#issuecomment-1980210690
align_offset, align_to: no longer allow implementations to spuriously fail to align
For a long time, we have allowed `align_offset` to fail to compute a properly aligned offset, and `align_to` to return a smaller-than-maximal "middle slice". This was done to cover the implementation of `align_offset` in const-eval and Miri. See https://github.com/rust-lang/rust/issues/62420 for more background. For about the same amount of time, this has caused confusion and surprise, where people didn't realize they have to write their code to be defensive against `align_offset` failures.
Another way to put this is: the specification is effectively non-deterministic, and non-determinism is hard to test for -- in particular if the implementation everyone uses to test always produces the same reliable result, and nobody expects it to be non-deterministic to begin with.
With https://github.com/rust-lang/rust/pull/117840, Miri has stopped making use of this liberty in the spec; it now always behaves like rustc. That only leaves const-eval as potential motivation for this behavior. I do not think this is sufficient motivation. Currently, none of the relevant functions are stably const: `align_offset` is unstably const, `align_to` is not const at all. I propose that if we ever want to make these const-stable, we just accept the fact that they can behave differently at compile-time vs at run-time. This is not the end of the world, and it seems to be much less surprising to programmers than unexpected non-determinism. (Related: https://github.com/rust-lang/rfcs/pull/3352.)
`@thomcc` has repeatedly made it clear that they strongly dislike the non-determinism in align_offset, so I expect they will support this. `@oli-obk,` what do you think? Also, whom else should we involve? The primary team responsible is clearly libs-api, so I will nominate this for them. However, allowing const-evaluated code to behave different from run-time code is t-lang territory. The thing is, this is not stabilizing anything t-lang-worthy immediately, but it still does make a decision we will be bound to: if we accept this change, then
- either `align_offset`/`align_to` can never be called in const fn,
- or we allow compile-time behavior to differ from run-time behavior.
So I will nominate for t-lang as well, with the question being: are you okay with accepting either of these outcomes (without committing to which one, just accepting that it has to be one of them)? This closes the door to "have `align_offset` and `align_to` at compile-time and also always have compile-time behavior match run-time behavior".
Closes https://github.com/rust-lang/rust/issues/62420
Merge `collect_mod_item_types` query into `check_well_formed`
follow-up to https://github.com/rust-lang/rust/pull/121154
this removes more potential parallel-compiler bottlenecks and moves diagnostics for the same items next to each other, instead of grouping diagnostics by analysis kind
Use `MPlaceTy` instead of `PlaceTy` in `FnArg` and ignore (copy) locals in an
earlier step ("Locals that don't have their address taken are as protected as
they can ever be").
This seems to be crucial for tail call support (as they can't refer to caller's
locals which are killed when replacing the stack frame).
Use `ControlFlow` in visitors.
Follow up to #121256
This does have a few small behaviour changes in some diagnostic output where the visitor will now find the first match rather than the last match. The change in `find_anon_types.rs` has the only affected test. I don't see this being an issue as the last occurrence isn't any better of a choice than the first.
Refactor pre-getopts command line argument handling
Rebased version of #111658. I've also fixed the Windows CI failure (although I don't have access to Windows to test it myself).
add known-bug tests for derive failure to detect packed repr
We only taint if it was a normal item. Modules and imports are untouched. Tainting them needs to be done differently, and it's unclear if that would be useful or desirable. If we just taint them into `Res::Err`, we end up losing some duplicate name messages *in the presence of other resolution errors*.
r? `@petrochenkov`
Make TAITs and ATPITs capture late-bound lifetimes in scope
This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.
r? `@oli-obk` cc `@aliemjay`
Fixes#122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
Add `#[inline]` to `BTreeMap::new` constructor
This PR add the `#[inline]` attribute to `BTreeMap::new` constructor as to make it eligible for inlining.
<details>
For some context: I was profiling `rustc --check-cfg` with callgrind and due to the way we currently setup all the targets and we end-up calling `BTreeMap::new` multiple times for (nearly) all the targets. Adding the `#[inline]` attribute reduced the number of instructions needed.
</details>
Fix quadratic behavior of repeated vectored writes
Some implementations of `Write::write_vectored` in the standard library (`BufWriter`, `LineWriter`, `Stdout`, `Stderr`) check all buffers to calculate the total length. This is O(n) over the number of buffers.
It's common that only a limited number of buffers is written at a time (e.g. 1024 for `writev(2)`). `write_vectored_all` will then call `write_vectored` repeatedly, leading to a runtime of O(n²) over the number of buffers.
This fix is to only calculate as much as needed if it's needed.
Here's a test program:
```rust
#![feature(write_all_vectored)]
use std::fs::File;
use std::io::{BufWriter, IoSlice, Write};
use std::time::Instant;
fn main() {
let buf = vec![b'\0'; 100_000_000];
let mut slices: Vec<IoSlice<'_>> = buf.chunks(100).map(IoSlice::new).collect();
let mut writer = BufWriter::new(File::create("/dev/null").unwrap());
let start = Instant::now();
write_smart(&slices, &mut writer);
println!("write_smart(): {:?}", start.elapsed());
let start = Instant::now();
writer.write_all_vectored(&mut slices).unwrap();
println!("write_all_vectored(): {:?}", start.elapsed());
}
fn write_smart(mut slices: &[IoSlice<'_>], writer: &mut impl Write) {
while !slices.is_empty() {
// Only try to write as many slices as can be written
let res = writer
.write_vectored(slices.get(..1024).unwrap_or(slices))
.unwrap();
slices = &slices[(res / 100)..];
}
}
```
Before this change:
```
write_smart(): 6.666952ms
write_all_vectored(): 498.437092ms
```
After this change:
```
write_smart(): 6.377158ms
write_all_vectored(): 6.923412ms
```
`LineWriter` (and by extension `Stdout`) isn't fully repaired by this because it looks for newlines. I could open an issue for that after this is merged, I think it's fixable but not trivially.
Add asm goto support to `asm!`
Tracking issue: #119364
This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto).
Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary.
r? ``@Amanieu``
cc ``@ojeda``
Improve std::fs::read_to_string example
Resolves [#118621](https://github.com/rust-lang/rust/issues/118621)
For the original code to succeed it requires address.txt to contain a socketaddress, however it is much easier to follow if this is just any strong - eg address could be a street address or just text.
Also changed the variable name from "foo" to something more meaningful as cargo clippy warns you against using foo as a placeholder.
```
$ cat main.rs
use std::fs;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let addr: String = fs::read_to_string("address.txt")?.parse()?;
println!("{}", addr);
Ok(())
}
$ cat address.txt
123 rusty lane
san francisco 94999
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `/home/haydon/workspace/rust-test-pr/tester/target/debug/tester`
123 rusty lane
san francisco 94999
```