Make stable_mir::with_tables sound
See the first commit for the actual soundness fix. The rest is just fallout from that and is entirely safe code. Includes most of #120120
The major difference to #120120 is that we don't need an unsafe trait, as we can now rely on the type system (the only unsafe part, and the actual source of the unsoundness was in `with_tables`)
r? `@celinval`
coverage: Format all coverage tests with `rustfmt`
As suggested by <https://github.com/rust-lang/rust/pull/119984#discussion_r1452856806>.
Test files in `tests/` are normally ignored by `x fmt`, but sometimes those files end up being run through `rustfmt` anyway, either by `rust-analyzer` or by hand.
When that happens, it's annoying to have to manually revert formatting changes that are unrelated to the actual changes being made. So it's helpful for the tests in the repository to already have standard formatting beforehand.
However, there are several coverage tests that deliberately use non-standard formatting, so that line counts reveal more information about where code regions begin and end. In those cases, we can use `#[rustfmt::skip]` to prevent that code from being disturbed.
``@rustbot`` label +A-code-coverage
Use an interpreter in MIR jump threading
This allows to understand assignments of aggregate constants. This case appears more frequently with GVN promoting aggregates to constants.
Tweak the threshold for chunked swapping
Thanks to `@AngelicosPhosphoros` for the tests here, which I copied from #98892.
This is an experiment as a simple alternative to that PR that just tweaks the existing threshold, since that PR showed that 3×Align (like `String`) currently doesn't work as well as it could.
Remove special handling of `box` expressions from parser
#108471 added a temporary hack to parse `box expr`. It's been almost a year since then, so I think it's safe to remove the special handling.
As a drive-by cleanup, move `parser/removed-syntax*` tests to their own directory.
bjorn3 says:
> On errors we don't finalize the incr comp cache, but non-fatal diagnostics are cached afaik.
Otherwise we would have to replay the query in question, which we may not be able to do if the query
key is not reconstructible from the dep node fingerprint.
So we must track these flags to avoid replaying incorrect diagnostics.
`single_use_lifetimes`: Don't suggest deleting lifetimes with bounds
Closes#117965
```
9 | pub fn get<'b: 'a>(&'b self) -> &'a str {
| ^^ -- ...is used only here
| |
| this lifetime...
```
In this example, I think the `&'b self` can be replaced with the bound itself, yielding `&'a self`, but this would require a deeper refactor. Happy to do as a follow-on PR if desired.
Avoid ICEs in trait names without `dyn`
Check diagnostic is error before downgrading. Fix#119633.
Account for traits using self-trait by name without `dyn`. Fix#119652.
Stabilize single-field offset_of
This PR stabilizes offset_of for a single field. There has been some further discussion at https://github.com/rust-lang/rust/issues/106655 about whether this is advisable; I'm opening the PR anyway so that the code is available.
LLVM 18 x86 data layout update
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM.
This results in Rust overaligning things relative to LLVM on older LLVMs.
This implements MCP https://github.com/rust-lang/compiler-team/issues/683.
See #54341
Suggest `.swap()` when encountering conflicting borrows from `mem::swap` on a slice
This PR modifies the existing suggestion by matching on `[ProjectionElem::Deref, ProjectionElem::Index(_)]` instead of just `[ProjectionElem::Index(_)]`, which caused us to miss many cases. Additionally, it adds a more specific, machine-applicable suggestion in the case we determine `mem::swap` was used to swap elements in a slice.
Closes#102269
never_patterns: typecheck never patterns
This checks that a `!` pattern is only used on an uninhabited type (modulo match ergonomics, i.e. `!` is allowed on `&Void`).
r? `@compiler-errors`
Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.
The advantage of this is that it does not need to be assigned to a variable to be used in a `Context` creation, which is the most common thing to want to do with a noop waker. It also avoids unnecessarily executing the dynamically dispatched drop function when the noop waker is dropped.
If an owned noop waker is desired, it can be created by cloning, but the reverse is harder to do since it requires declaring a constant. Alternatively, both versions could be provided, like `futures::task::noop_waker()` and `futures::task::noop_waker_ref()`, but that seems to me to be API clutter for a very small benefit, whereas having the `&'static` reference available is a large reduction in boilerplate.
[Previous discussion on the tracking issue starting here](https://github.com/rust-lang/rust/issues/98286#issuecomment-1862159766)
use implied bounds compat mode in MIR borrowck
cc
- #119956
- #118553
This should hopefully fix bevy 🤔 `cargo test` ends up freezing my computer though, cargo build went from err to ok however 😁
r? `@jackh726`
Rollup of 10 pull requests
Successful merges:
- #118665 (Consolidate all associated items on the NonZero integer types into a single impl block per type)
- #118798 (Use AtomicU8 instead of AtomicUsize in backtrace.rs)
- #119062 (Deny braced macro invocations in let-else)
- #119138 (Docs: Use non-SeqCst in module example of atomics)
- #119907 (Update `fn()` trait implementation docs)
- #120083 (Warn when not having a profiler runtime means that coverage tests won't be run/blessed)
- #120107 (dead_code treats #[repr(transparent)] the same as #[repr(C)])
- #120110 (Update documentation for Vec::into_boxed_slice to be more clear about excess capacity)
- #120113 (Remove myself from review rotation)
- #120118 (Fix typo in documentation in base.rs)
r? `@ghost`
`@rustbot` modify labels: rollup
The internal function was unsound, it could cause UB in rare cases where
the user inadvertly stored the returned object in a location that could
outlive the TyCtxt.
In order to make it safe, we now take a type context as an argument to
the internal fn, and we ensure that interned items are lifted using the
provided context.
Thus, this change ensures that the compiler can properly enforce
that the object does not outlive the type context it was lifted to.
dead_code treats #[repr(transparent)] the same as #[repr(C)]
In #92972 we enabled linting on unused fields in tuple structs. In #118297 that lint was enabled by default. That exposed issues like #119659, where the fields of a struct marked `#[repr(transparent)]` were reported by the `dead_code` lint. The language team [decided](https://github.com/rust-lang/rust/issues/119659#issuecomment-1885172045) that the lint should treat `repr(transparent)` the same as `#[repr(C)]`.
Fixes#119659
Get rid of the hir_owner query.
This query was meant as a firewall between `hir_owner_nodes` which is supposed to change often, and the queries that only depend on the item signature. That firewall was inefficient, leaking the contents of the HIR body through `HirId`s.
`hir_owner` incurs a significant cost, as we need to hash HIR twice in multiple modes. This PR proposes to remove it, and simplify the hashing scheme.
For the future, `def_kind`, `def_span`... are much more efficient for incremental decoupling, and should be preferred.
Improved collapse_debuginfo attribute, added command-line flag
Improved attribute collapse_debuginfo with variants: `#[collapse_debuginfo=(no|external|yes)]`.
Added command-line flag for default behaviour.
Work-in-progress: will add more tests.
cc https://github.com/rust-lang/rust/issues/100758
Rollup of 8 pull requests
Successful merges:
- #119172 (Detect `NulInCStr` error earlier.)
- #119833 (Make tcx optional from StableMIR run macro and extend it to accept closures)
- #119967 (Add `PatKind::Err` to AST/HIR)
- #119978 (Move async closure parameters into the resultant closure's future eagerly)
- #120021 (don't store const var origins for known vars)
- #120038 (Don't create a separate "basename" when naming and opening a MIR dump file)
- #120057 (Don't ICE when deducing future output if other errors already occurred)
- #120073 (Remove spastorino from users_on_vacation)
r? `@ghost`
`@rustbot` modify labels: rollup
error on incorrect implied bounds in wfcheck except for Bevy dependents
Rebase of #109763
Additionally, special cases Bevy `ParamSet` types to not trigger the lint. This is tracked in #119956.
Fixes#109628
Don't ICE when deducing future output if other errors already occurred
The situation can't really happen outside of erroneous code. What was interesting is that it ICEd before emitting any other diagnostics. This was because the other errors were silenced due to cycle_delay_bug cycle errors.
r? ```@compiler-errors```
fixes#119890
Move async closure parameters into the resultant closure's future eagerly
Move async closure parameters into the closure's resultant future eagerly.
Before, we used to desugar `async |p1, p2, ..| { body }` as `|p1, p2, ..| { || async { body } }`. Now, we desugar the above like `|p1, p2, ..| { async move { let p1 = p1; let p2 = p2; ... body } }`. This mirrors the same desugaring that `async fn` does with its parameter types, and the compiler literally uses the same code via a shared helper function.
This removes the necessity for E0708, since now expressions like `async |x: i32| { x }` will not give you confusing borrow errors.
This does *not* fix the case where async closures have self-borrows. This will come with a general implementation of async closures, which is still in the works.
r? oli-obk
Make tcx optional from StableMIR run macro and extend it to accept closures
Change `run` macro to avoid sometimes unnecessary dependency on `TyCtxt`, and introduce `run_with_tcx` to capture use cases where `tcx` is required. Additionally, extend both macros to accept closures that may capture variables.
I've also modified the `internal()` method to make it safer, by accepting the type context to force the `'tcx` lifetime to match the context lifetime.
These are non-backward compatible changes, but they only affect internal APIs which are provided today as helper functions until we have a stable API to start the compiler.
Detect `NulInCStr` error earlier.
By making it an `EscapeError` instead of a `LitError`. This makes it like the other errors produced when checking string literals contents, e.g. for invalid escape sequences or bare CR chars.
NOTE: this means these errors are issued earlier, before expansion, which changes behaviour. It will be possible to move the check back to the later point if desired. If that happens, it's likely that all the string literal contents checks will be delayed together.
One nice thing about this: the old approach had some code in `report_lit_error` to calculate the span of the nul char from a range. This code used a hardwired `+2` to account for the `c"` at the start of a C string literal, but this should have changed to a `+3` for raw C string literals to account for the `cr"`, which meant that the caret in `cr"` nul error messages was one short of where it should have been. The new approach doesn't need any of this and avoids the off-by-one error.
r? ```@fee1-dead```
Construct closure type eagerly
Construct the returned closure type *before* checking the body, in the same match as we were previously deducing the coroutine types based off of the closure kind.
This simplifies some changes I'm doing in the async closure PR, and imo just seems easier to read (since we only need one match on closure kind, instead of two). There's no reason I can tell that we needed to create the closure type *after* the body was checked.
~~This also has the side-effect of making it so that the universe of the closure synthetic infer vars are lower than any infer vars that come from checking the body. We can also get rid of `next_root_ty_var` hack from closure checking (though in general we still need this, #119106). cc ```@lcnr``` since you may care about this hack 😆~~
r? ```@oli-obk```
Gracefully handle missing typeck information if typeck errored
fixes#116893
I created some logs and the typeck of `fn main` is exactly the same, no matter whether the constant's body is what it is, or if it is replaced with `panic!()`. The latter will cause the ICE not to be emitted though. The reason for that is that we abort compilation if *errors* were emitted, but not if *lint errors* were emitted. This took me way too long to debug, and is another reason why I would have liked https://github.com/rust-lang/compiler-team/issues/633
Don't ICE if TAIT-defining fn contains a closure with `_` in return type
The `delay_span_bug` got added in 0e82aaeb67 to reduce the amount of errors emitted for functions that have `_` in their return type, because inference doesn't apply to function items. But this logic shouldn't apply to closures, because their return types *can* be inferred.
Fixes https://github.com/rust-lang/rust/issues/119916.
tests: add sanity-check assembly test for every target
Fixes#119910.
Adds a basic assembly test checking that each target can produce assembly and update the target tier policy to require this.
cc rust-lang/compiler-team#655
r? `@wesleywiser`
Add way to express that no values are expected with check-cfg
This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`).
### Context
Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_.
This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list.
To give a more concrete example, Cargo `--check-cfg` currently needs to generate:
- `--check-cfg=cfg(feature, values(...))` for the case with declared features
- and `--check-cfg=cfg()` for the case without any features declared
This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it.
See [Cargo `check_cfg_args` function](92395d9010/src/cargo/core/compiler/mod.rs (L1263-L1281)) for more details.
### De-specializing *empty* `values()`
To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax.
> The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set.
Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in https://github.com/rust-lang/rust/pull/111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since https://github.com/rust-lang/rust/pull/119473 which introduced the `none()` syntax.
A simplified representation of the proposed "de-specialization" would be:
| Syntax | List/set of expected values |
|-----------------------------------------|-----------------------------|
| `cfg(name)`/`cfg(name, values(none()))` | `&[None]` |
| `cfg(name, values())` | `&[]` |
Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see https://github.com/rust-lang/cargo/pull/13011.
`@rustbot` label +F-check-cfg
r? `@petrochenkov`
cc `@epage`
Adds a basic assembly test checking that each target can produce assembly
and update the target tier policy to require this.
Signed-off-by: David Wood <david@davidtw.co>
fix fn/const items implied bounds and wf check (rebase)
A rebase of #104098, see that PR for discussion. This is pretty much entirely the work of `@aliemjay.` I received his permission for this rebase.
---
These are two distinct changes (edit: actually three, see below):
1. Wf-check all fn item args. This is a soundness fix.
Fixes#104005
2. Use implied bounds from impl header in borrowck of associated functions/consts. This strictly accepts more code and helps to mitigate the impact of other breaking changes.
Fixes#98852Fixes#102611
The first is a breaking change and will likely have a big impact without the the second one. See the first commit for how it breaks libstd.
Landing the second one without the first will allow more incorrect code to pass. For example an exploit of #104005 would be as simple as:
```rust
use core::fmt::Display;
trait ExtendLt<Witness> {
fn extend(self) -> Box<dyn Display>;
}
impl<T: Display> ExtendLt<&'static T> for T {
fn extend(self) -> Box<dyn Display> {
Box::new(self)
}
}
fn main() {
let val = (&String::new()).extend();
println!("{val}");
}
```
The third change is to to check WF of user type annotations before normalizing them (fixes#104764, fixes#104763). It is mutually dependent on the second change above: an attempt to land it separately in #104746 caused several crater regressions that can all be mitigated by using the implied from the impl header. It is also necessary for the soundness of associated consts that use the implied bounds of impl header. See #104763 and how the third commit fixes the soundness issue in `tests/ui/wf/wf-associated-const.rs` that was introduces by the previous commit.
r? types
I added `tcx` argument to `internal` to force 'tcx to be the same
lifetime as TyCtxt. The only other solution I could think is to change
this function to be `unsafe`.