This is needed to track anon const parents properly once we implement
`ConstArgKind::Path` (which requires moving anon const def-creation
outside of `DefCollector`):
Why do we need this in addition to [`Self::current_hir_id_owner`]?
Currently (as of June 2024), anonymous constants are not HIR owners;
however, they do get their own DefIds. Some of these DefIds have to be
created during AST lowering, rather than def collection, because we
can't tell until after name resolution whether an anonymous constant
will end up instead being a [`rustc_hir::ConstArgKind::Path`]. However,
to compute which generics are available to an anonymous constant nested
inside another, we need to make sure that the parent is recorded as the
parent anon const, not the enclosing item. So we need to track parent
defs differently from HIR owners, since they will be finer-grained in
the case of anon consts.
Invert infer `error_reporting` mod struture
Parallel change to #127493, which moves `rustc_infer::infer::error_reporting` to `rustc_infer::error_reporting::infer`. After this, we should just be able to merge this into `rustc_trait_selection::error_reporting::infer`, and pull down `TypeErrCtxt` into that crate. 👍
r? lcnr
Deny keyword lifetimes pre-expansion
https://github.com/rust-lang/rust/pull/126452#issuecomment-2179464266
> Secondly, we confirmed that we're OK with moving the validation of keywords in lifetimes to pre-expansion from post-expansion. We similarly consider this a bug fix. While the breakage of the convenience feature of the with_locals crate that relies on this is unfortunate, and we wish we had not overlooked this earlier for that reason, we're fortunate that the breakage is contained to only one crate, and we're going to accept this breakage as the extra complexity we'd need to carry in the compiler to work around this isn't deemed worth it.
T-lang considers it to be a bugfix to deny `'keyword` lifetimes in the parser, rather than during AST validation that only happens post-expansion. This has one breakage: https://github.com/rust-lang/rust/pull/126452#issuecomment-2171654756
This probably should get lang FCP'd just for consistency.
Delegation: support coercion for target expression
(solves https://github.com/rust-lang/rust/issues/118212#issuecomment-2160723092)
The implementation consist of 2 parts. Firstly, method call is generated instead of fully qualified call in AST->HIR lowering if there were no generic arguments or `Qpath` were provided. These restrictions are imposed due to the loss of information after desugaring. For example in
```rust
trait Trait {
fn foo(&self) {}
}
reuse <u8 as Trait>::foo;
```
We would like to generate such a code:
```rust
fn foo<u8: Trait>(x: &u8) {
x.foo(x)
}
```
however, the signature is inherited during HIR analysis where `u8` was discarded.
Then, we probe the single pre-resolved method.
P.S In the future, we would like to avoid restrictions on the callee path by `Self` autoref/autoderef in fully qualified calls, but at the moment it didn't work out.
r? `@petrochenkov`
Sync ar_archive_writer to LLVM 18.1.3
From LLVM 15.0.0-rc3. This adds support for COFF archives containing Arm64EC object files and has various fixes for AIX big archive files.
Various ast validation simplifications
Changes pulled out of https://github.com/rust-lang/rust/pull/127524
These are needed to make ast validation a mutable visitor, as we can't keep immutable references to the AST around in that case. But I think they are simplifying things in general and can stand on their own
Fix a bunch of sites that were walking instead of visiting, making it impossible for visitor impls to look at these values
This doesn't affects anything right now, but a `MutVisitor` impl could be surprised by this.
The reason this doesn't affect anything is that no one overrrides `visit_lifetime` or `visit_param_bounds` currently.
Make ErrorGuaranteed discoverable outside types, consts, and lifetimes
types like `PatKind` could contain `ErrorGuaranteed`, but not return them via `tainted_by_errors` or `error_reported` (see https://github.com/rust-lang/rust/pull/127687#discussion_r1679027883). Now this happens, but it's a bit fragile as you can see with the `TypeSuperVisitable for Ty` impl.
We will catch any problems around Ty, Region or Const at runtime with an assert, and everything using derives will not have such issues, as it will just invoke the `TypeVisitable for ErrorGuaranteed` impl
Fix and enforce `unsafe_op_in_unsafe_fn` in compiler
In preparation for edition 2024, this PR previews the fallout of enabling the `unsafe_op_in_unsafe_fn` lint in the compiler, since it's defaulting to warn in the new edition (#112038).
The major annoyance comes primarily from the `rustc_codegen_llvm` module, where there's a ton of unsafe calls. I tended to wrap individual calls to unsafe fns in `unsafe {}`, but there a handful of places I chose to just wrap several calls in an `unsafe {}` block just because it would've been excessive to wrap each call individually.
This doesn't enable the lint for the standard library, since I'm not totally certain what T-libs prefers w/ this lint.
match lowering: Use an iterator to find `expand_until`
A small cleanup that I noticed while looking at #127164.
This makes it easier to see that the split point is always the index after the found item, or the whole list if no stopping point was found.
r? `@Nadrieril`
Make sure trait def ids match before zipping args in `note_function_argument_obligation`
Fixes#126416Fixes#127745
Didn't add both tests b/c I felt like it was unnecessary.
match lowering: Move `MatchPair` tree creation to its own module
This makes it easier to see that `MatchPair::new` has only one non-recursive caller, because the recursive callers are all in this module. No functional changes.
---
I have used `git diff --color-moved` to verify that the moved code is identical to the old code, except for reduced visibility on the helper methods.
coverage: Restrict `ExpressionUsed` simplification to `Code` mappings
In the future, branch and MC/DC mappings might have expressions that don't correspond to any single point in the control-flow graph. That makes it trickier to keep track of which expressions should expect an `ExpressionUsed` node.
We therefore sidestep that complexity by only performing `ExpressionUsed` simplification for expressions associated directly with ordinary `Code` mappings.
(This simplification step is inherited from the original coverage implementation, which only supported `Code` mappings anyway, so there's no particular reason to extend it to other kinds of mappings unless we specifically choose to.)
Relevant to:
- #124154
- #126677
- #124278
```@rustbot``` label +A-code-coverage
Stop using the `gen` identifier in the compiler
In preparation for edition 2024, this PR previews the fallout of removing usages of `gen` since it's being reserved as a keyword.
There are two notable changes here:
1. Had to rename `fn gen(..)` in gen/kill analysis to `gen_`. Not certain there's a better name than that.
2. There are (false?[^1]) positives in `rustc_macros` when using synstructure, which uses `gen impl` to mark an implementation. We could suppress this in a one-off way, or perhaps just ignore `gen` in macros altogether, since if an identifier ends up in expanded code then it'll get properly denied anyways.
Not relevant to the compiler, but it's gonna be really annoying to change `rand`'s `gen` fn in the library and miri...
[^1]: I haven't looked at the synstructure proc macro code itself so I'm not certain if it'll start to fail when converted to ed2024 (or, e.g., when syn starts parsing `gen` as a kw).
Make parse error suggestions verbose and fix spans
Go over all structured parser suggestions and make them verbose style.
When suggesting to add or remove delimiters, turn them into multiple suggestion parts.
offset_from: always allow pointers to point to the same address
This PR implements the last remaining part of the t-opsem consensus in https://github.com/rust-lang/unsafe-code-guidelines/issues/472: always permits offset_from when both pointers have the same address, no matter how they are computed. This is required to achieve *provenance monotonicity*.
Tracking issue: https://github.com/rust-lang/rust/issues/117945
### What is provenance monotonicity and why does it matter?
Provenance monotonicity is the property that adding arbitrary provenance to any no-provenance pointer must never make the program UB. More specifically, in the program state, data in memory is stored as a sequence of [abstract bytes](https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#abstract-byte), where each byte can optionally carry provenance. When a pointer is stored in memory, all of the bytes it is stored in carry that provenance. Provenance monotonicity means: if we take some byte that does not have provenance, and give it some arbitrary provenance, then that cannot change program behavior or introduce UB into a UB-free program.
We care about provenance monotonicity because we want to allow the optimizer to remove provenance-stripping operations. Removing a provenance-stripping operation effectively means the program after the optimization has provenance where the program before the optimization did not -- since the provenance removal does not happen in the optimized program. IOW, the compiler transformation added provenance to previously provenance-free bytes. This is exactly what provenance monotonicity lets us do.
We care about removing provenance-stripping operations because `*ptr = *ptr` is, in general, (likely) a provenance-stripping operation. Specifically, consider `ptr: *mut usize` (or any integer type), and imagine the data at `*ptr` is actually a pointer (i.e., we are type-punning between pointers and integers). Then `*ptr` on the right-hand side evaluates to the data in memory *without* any provenance (because [integers do not have provenance](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html#integers-do-not-have-provenance)). Storing that back to `*ptr` means that the abstract bytes `ptr` points to are the same as before, except their provenance is now gone. This makes `*ptr = *ptr` a provenance-stripping operation (Here we assume `*ptr` is fully initialized. If it is not initialized, evaluating `*ptr` to a value is UB, so removing `*ptr = *ptr` is trivially correct.)
### What does `offset_from` have to do with provenance monotonicity?
With `ptr = without_provenance(N)`, `ptr.offset_from(ptr)` is always well-defined and returns 0. By provenance monotonicity, I can now add provenance to the two arguments of `offset_from` and it must still be well-defined. Crucially, I can add *different* provenance to the two arguments, and it must still be well-defined. In other words, this must always be allowed: `ptr1.with_addr(N).offset_from(ptr2.with_addr(N))` (and it returns 0). But the current spec for `offset_from` says that the two pointers must either both be derived from an integer or both be derived from the same allocation, which is not in general true for arbitrary `ptr1`, `ptr2`.
To obtain provenance monotonicity, this PR hence changes the spec for offset_from to say that if both pointers have the same address, the function is always well-defined.
### What further consequences does this have?
It means the compiler can no longer transform `end2 = begin.offset(end.offset_from(begin))` into `end2 = end`. However, it can still be transformed into `end2 = begin.with_addr(end.addr())`, which later parts of the backend (when provenance has been erased) can trivially turn into `end2 = end`.
The only alternative I am aware of is a fundamentally different handling of zero-sized accesses, where a "no provenance" pointer is not allowed to do zero-sized accesses and instead we have a special provenance that indicates "may be used for zero-sized accesses (and nothing else)". `offset` and `offset_from` would then always be UB on a "no provenance" pointer, and permit zero-sized offsets on a "zero-sized provenance" pointer. This achieves provenance monotonicity. That is, however, a breaking change as it contradicts what we landed in https://github.com/rust-lang/rust/pull/117329. It's also a whole bunch of extra UB, which doesn't seem worth it just to achieve that transformation.
### What about the backend?
LLVM currently doesn't have an intrinsic for pointer difference, so we anyway cast to integer and subtract there. That's never UB so it is compatible with any relaxation we may want to apply.
If LLVM gets a `ptrsub` in the future, then plausibly it will be consistent with `ptradd` and [consider two equal pointers to be inbounds](https://github.com/rust-lang/rust/pull/124921#issuecomment-2205795829).
In the future, branch and MC/DC mappings might have expressions that don't
correspond to any single point in the control-flow graph. That makes it
trickier to keep track of which expressions should expect an `ExpressionUsed`
node.
We therefore sidestep that complexity by only performing `ExpressionUsed`
simplification for expressions associated directly with ordinary `Code`
mappings.
Fill out target-spec metadata for all targets
**What does this PR try to resolve?**
This PR completes the target-spec metadata fields for all targets. This is required for a corresponding Cargo PR which adds a check for whether a target supports building the standard library when the `-Zbuild-std=std` flag is passed ([see this issue](https://github.com/rust-lang/wg-cargo-std-aware/issues/87). This functionality in Cargo is reliant on the output of `--print=target-spec-json`.
**How should we test and review this PR?**
Check that a given target-spec metadata has been updated with:
```
$ ./x.py build library/std
$ build/host/stage1/bin/rustc --print=target-spec-json --target <target_name> -Zunstable-options
```
**Additional Information**
A few things to note:
* Where a targets 'std' or 'host tools' support is listed as '?' in the rust docs, these are left as 'None' with this PR. The corresponding changes in cargo will only reject an attempt to build std if the 'std' field is 'Some(false)'. In the case it is 'None', cargo will continue trying to build
* There's no rush for this to be merged. I understand that the format for this is not finalised yet.
* Related: #120745
Remove lang feature for type ascription (since it's a lib feature now)
It's not necessary since it's a library feature now, via the type ascription macro. We can't (and shouldn't) register it as a removed feature since I think that would give "this feature has been removed" errors even for people using the macro (well, I'm pretty sure, though I didn't check).
r? `@Nilstrieb`
Report usage of lib features in ast validation
No idea why it was split between ast validation for lang features and a later pass for lang features.
r? `@Nilstrieb`
Fix `DebugParser`.
I tried using this and it didn't work at all. `prev_token` is never eof, so the accumulator is always false, which means the `then_some` always returns `None`, which means `scan` always returns `None`, and `tokens` always ends up an empty vec. I'm not sure how this code was supposed to work.
(An aside: I find `Iterator::scan` to be a pretty wretched function, that produces code which is very hard to understand. Probably why this is just one of two uses of it in the entire compiler.)
This commit changes it to a simpler imperative style that produces a valid `tokens` vec.
r? `@workingjubilee`