compile-time evaluation: detect writes through immutable pointers
This has two motivations:
- it unblocks https://github.com/rust-lang/rust/pull/116745 (and therefore takes a big step towards `const_mut_refs` stabilization), because we can now detect if the memory that we find in `const` can be interned as "immutable"
- it would detect the UB that was uncovered in https://github.com/rust-lang/rust/pull/117905, which was caused by accidental stabilization of `copy` functions in `const` that can only be called with UB
When UB is detected, we emit a future-compat warn-by-default lint. This is not a breaking change, so completely in line with [the const-UB RFC](https://rust-lang.github.io/rfcs/3016-const-ub.html), meaning we don't need t-lang FCP here. I made the lint immediately show up for dependencies since it is nearly impossible to even trigger this lint without `const_mut_refs` -- the accidentally stabilized `copy` functions are the only way this can happen, so the crates that popped up in #117905 are the only causes of such UB (in the code that crater covers), and the three cases of UB that we know about have all been fixed in their respective crates already.
The way this is implemented is by making use of the fact that our interpreter is already generic over the notion of provenance. For CTFE we now use the new `CtfeProvenance` type which is conceptually an `AllocId` plus a boolean `immutable` flag (but packed for a more efficient representation). This means we can mark a pointer as immutable when it is created as a shared reference. The flag will be propagated to all pointers derived from this one. We can then check the immutable flag on each write to reject writes through immutable pointers.
I just hope perf works out.
Fix `rustc_codegen_gcc` build and tests failure in CI
https://github.com/rust-lang/rust/pull/118463 seems to have broke the PR CI, more specificaly the `x86_64-gnu-llvm-16` builder which [fail with](https://github.com/rust-lang/rust/actions/runs/7128709674/job/19411205695?pr=118705#step:26:1668):
```
Building stage1 codegen backend gcc (x86_64-unknown-linux-gnu)
Compiling libc v0.2.147
Compiling rustix v0.38.8
Compiling memchr v2.5.0
Compiling bitflags v2.4.0
Compiling linux-raw-sys v0.4.5
Compiling fastrand v2.0.0
Compiling smallvec v1.10.0
error: invalid `--check-cfg` argument: `values(freebsd10)` (expected `cfg(name, values("value1", "value2", ... "valueN"))`)
error: could not compile `libc` (lib) due to previous error
```
Updating to `libc` version 0.2.150 fixes the build issue since it includes the support for the new check-cfg syntax.
Then it [failed](https://github.com/rust-lang/rust/actions/runs/7129280743/job/19413025132?pr=118706#step:26:2218) with a missing `#![allow(internal_features)]` in one of the example.
r? `@GuillaumeGomez`
Re-enable `rustc_codegen_gcc` tests in CI
When #117947 dropped llvm-15 from CI, we neglected to copy #117313's changes to enable `rustc_codegen_gcc` testing to the new base llvm-16. This is now restored, as well as copying the setup to llvm-17 as well so we hopefully won't miss it next time.
In addition, due to case mismatch in `$extra_env` updates in `docker/run.sh`, I think it wasn't actually getting enabled before, but this should now be fixed. I also avoided the linker hack for `libgccjit.so` that was present before, because that's not needed if the version matches the base `gcc` used for linking.
r? GuillaumeGomez
`EvaluatedToUnknown` -> `EvaluatedToAmbigStackDependent`, `EvaluatedToRecur` -> `EvaluatedToErrStackDependent`
Less confusing names, since the only difference between them and their parallel `EvalutedTo..` is that they are stack dependent.
r? lcnr
Remove `PolyGenSig` since it's always a dummy binder
Coroutines are never polymorphic in their signature. This cleans up a FIXME in the code:
```
/// Returns the "coroutine signature", which consists of its yield
/// and return types.
///
/// N.B., some bits of the code prefers to see this wrapped in a
/// binder, but it never contains bound regions. Probably this
/// function should be removed.
```
Fix is_foreign_item for StableMIR instance
Change the implementation of `Instance::is_foreign_item` to directly query the compiler for the instance `def_id` instead of incorrectly relying on the conversion to `CrateItem`. I also added a method to check if the instance has body, since the function already existed and it just wasn't exposed via public APIs. This makes it much cheaper for the user to check if the instance has body.
## Background:
- In pull https://github.com/rust-lang/rust/pull/118524, I fixed the conversion from Instance to CrateItem to avoid the conversion if the instance didn't have a body available. This broke the `is_foreign_item`.
r? `@ouz-a`
rustc_arena: add `alloc_str`
Two places called `from_utf8_unchecked` for strings from `alloc_slice`,
and one's SAFETY comment said this was for lack of `alloc_str` -- so
let's just add that instead!
Enforce `must_use` on associated types and RPITITs that have a must-use trait in bounds
Warn when an RPITIT or (un-normalized) associated type with a `#[must_use]` trait in its bounds is unused.
This is pending T-lang approval, since it changes the semantics of the `#[must_use]` attribute slightly, but I think it strictly catches more strange errors.
I could also limit this to just RPITITs, but that seems less useful.
Fixes#118444
tip for define macro name after `macro_rules!`
Fixes#118295
~Note that there are some bad case such as `macro_rules![]` or `macro_rules!()`. However, I think these are acceptable as they are likely to be seldom used (feel free to close this if you think its shortcomings outweigh its benefits)~
Edit: this problem was resolved by utilizing the `source_map.span_to_next_source`.
r? `@petrochenkov`
Suppress warnings in LLVM wrapper when targeting MSVC
The LLVM header files generate many warnings when compiled using MSVC. This makes it difficult to work on the LLVM wrapper code, because the warnings and errors that are relevant to local edits are obscured by the hundreds of lines of warnings from the LLVM Headers.
Use the glob binding in resolve_rustdoc_path process
Fixes#117920
Returning `None` seems enough.
I reproduces and tests this locally by `cargo +stage1 build`, but I cannot reproduce this ICE by putting [the following code](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=8b3ca8f4a7676eb90baf30437ba041a2) into `tests/ui/...` and then compiling it using `rustc +stage1 /path/to/test.rs` or `x.py test`:
```rust
#![crate_type = "lib"]
use super::Hasher;
/// [`Hasher`]
pub use core:#️⃣:*;
```
r? `@petrochenkov`
Change the implementation of `Instance::is_foreign_item` to directly
query the compiler for the instance `def_id` instead of incorrectly
relying on the conversion to `CrateItem`.
Background:
- In pull https://github.com/rust-lang/rust/pull/118524, I fixed the
conversion from Instance to CrateItem to avoid the conversion if the
instance didn't have a body available. This broke the `is_foreign_item`.
docs: remove #110800 from release notes
It's not stable yet, and shouldn't be mentioned here. At least, the message shouldn't be written like this.
I realize it's weird to go through an FCP, and then have the feature remain unstable, but this was an unusual case.
Rustdoc used to silently swallow unknown language tokens on code blocks, and now it produces a compatibility warning. The FCP got everyone's sign-off on the warning, not the finished feature, which remains unstable.
add comment about keeping flags in sync between bootstrap.py and bootstrap.rs
They got out of sync, probably because this comment was missing on the Python side (it only exists on the Rust side). https://github.com/rust-lang/rust/pull/118642 brings the flags back in sync but does not fix the comment, so let's do that here.
r? clubby789
Add ADT variant infomation to StableMIR and finish implementing TyKind::internal()
Introduce a `VariantDef` type and a mechanism to retrieve the definition from an `AdtDef`.
The `VariantDef` representation itself is just a combination of `AdtDef` and `VariantIdx`, which allow us to retrieve further information of a variant. I don't think we need to cache extra information for now, and we can translate on an on demand manner. I am leaving the fields public today due to https://github.com/rust-lang/project-stable-mir/issues/56, but they shouldn't. For this PR, I've only added a method to retrieve the variant name, and its fields. I also added an implementation of `RustcInternal` that allow users to retrieve more information using Rust internal APIs.
I have also finished the implementation of `RustcInternal` for `TyKind` which fixes https://github.com/rust-lang/project-stable-mir/issues/46.
## Motivation
Both of these changes are needed in order to properly interpret things like projections. For example,
- The variant definition is used to find out which variant we are downcasting to.
- Being able to create `Ty` from `TyKind` helps for example processing each stage of a projection, like the code in `place.ty()`.
`riscv32` platform support
This PR adds the following RISCV targets to the tier 2 list of targets:
- riscv32imafc-unknown-none-elf
- riscv32im-unknown-none-elf
The rationale behind adding them directly to tier 2, is that the other bare metal targets already exist at tier 2, and these new targets are the same with an additional target feature enabled.
As well as the additional targets, this PR fills out the platform support document(s) that were previously missing.
~~The RISC-V bare metal targets don't currently have a platform support document, but this will change soon as the RISC-V team from the Rust-embedded working group will maintain these once https://github.com/davidtwco/rust/pull/1 is merged (and `@davidtwco's` upstream PR is merged after). For the time being you can cc myself or any other member of the RISC-V team: https://github.com/orgs/rust-embedded/teams/riscv.~~
> A tier 2 target must have value to people other than its maintainers. (It may still be a niche target, but it must not be exclusively useful for an inherently closed group.)
RISC-V is an open specification, used and accessible to anyone including individuals.
> A tier 2 target must have a designated team of developers (the "target maintainers") available to consult on target-specific build-breaking issues, or if necessary to develop target-specific language or library implementation details. This team must have at least 2 developers.
This rust-embedded working group's [RISCV team](https://github.com/orgs/rust-embedded/teams/riscv) will maintain these targets.
> The target must not place undue burden on Rust developers not specifically concerned with that target. Rust developers are expected to not gratuitously break a tier 2 target, but are not expected to become experts in every tier 2 target, and are not expected to provide target-specific implementations for every tier 2 target.
I don't forsee this being an issue, the RISCV team will ensure we avoid undue burden for the general Rust community.
> The target must provide documentation for the Rust community explaining how to build for the target using cross-compilation, and explaining how to run tests for the target. If at all possible, this documentation should show how to run Rust programs and tests for the target using emulation, to allow anyone to do so. If the target cannot be feasibly emulated, the documentation should explain how to obtain and work with physical hardware, cloud systems, or equivalent.
There are links to resources we maintain in the re wg org in the platform support document.
> The target must document its baseline expectations for the features or versions of CPUs, operating systems, libraries, runtime environments, and similar.
Documented in the platform support document.
> If introducing a new tier 2 or higher target that is identical to an existing Rust target except for the baseline expectations for the features or versions of CPUs, operating systems, libraries, runtime environments, and similar, then the proposed target must document to the satisfaction of the approving teams why the specific difference in baseline expectations provides sufficient value to justify a separate target.
New target features in RISCV can drastically change the capability of a CPU, hence the need for a separate target to support different variants. We aim to support any ratified RISCV extensions.
> Tier 2 targets must not leave any significant portions of core or the standard library unimplemented or stubbed out, unless they cannot possibly be supported on the target.
`core` is fully implemented.
> The code generation backend for the target should not have deficiencies that invalidate Rust safety properties, as evaluated by the Rust compiler team. (This requirement does not apply to arbitrary security enhancements or mitigations provided by code generation backends, only to those properties needed to ensure safe Rust code cannot cause undefined behavior or other unsoundness.) If this requirement does not hold, the target must clearly and prominently document any such limitations as part of the target's entry in the target tier list, and ideally also via a failing test in the testsuite. The Rust compiler team must be satisfied with the balance between these limitations and the difficulty of implementing the necessary features.
RISCV is a well-established and well-maintained LLVM backend. To the best of my knowledge, the backend won't cause the generated code to have undefined behaviour.
> If the target supports C code, and the target has an interoperable calling convention for C code, the Rust target must support that C calling convention for the platform via extern "C". The C calling convention does not need to be the default Rust calling convention for the target, however.
The C calling convention is supported by RISCV.
> The target must build reliably in CI, for all components that Rust's CI considers mandatory.
For the last 4-5 years many of these RISCV targets have been building in CI without any known issues.
> The approving teams may additionally require that a subset of tests pass in CI, such as enough to build a functional "hello world" program, ./x.py test --no-run, or equivalent "smoke tests". In particular, this requirement may apply if the target builds host tools, or if the tests in question provide substantial value via early detection of critical problems.
Not applicable, in the future we may wish to add qemu tests but this is out of scope for now.
> Building the target in CI must not take substantially longer than the current slowest target in CI, and should not substantially raise the maintenance burden of the CI infrastructure. This requirement is subjective, to be evaluated by the infrastructure team, and will take the community importance of the target into account.
To the best of my knowledge, this will not induce a burden on the current CI infra.
> Tier 2 targets should, if at all possible, support cross-compiling. Tier 2 targets should not require using the target as the host for builds, even if the target supports host tools.
Cross-compilation is supported and documented in the platform support document.
> In addition to the legal requirements for all targets (specified in the tier 3 requirements), because a tier 2 target typically involves the Rust project building and supplying various compiled binaries, incorporating the target and redistributing any resulting compiled binaries (e.g. built libraries, host tools if any) must not impose any onerous license requirements on any members of the Rust project, including infrastructure team members and those operating CI systems. This is a subjective requirement, to be evaluated by the approving teams.
There are no additional license issues to worry about.
> Tier 2 targets must not impose burden on the authors of pull requests, or other developers in the community, to ensure that tests pass for the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on tests failing for the target. Do not send automated messages or notifications (via any medium, including via `@)` to a PR author or others involved with a PR regarding the PR breaking tests on a tier 2 target, unless they have opted into such messages.
The RISCV team agrees not to do this.
> The target maintainers should regularly run the testsuite for the target, and should fix any test failures in a reasonably timely fashion.
The RISCV team will fix any issues in a timely manner.
Provide context when `?` can't be called because of `Result<_, E>`
When a method chain ending in `?` causes an E0277 because the expression's `Result::Err` variant doesn't have a type that can be converted to the `Result<_, E>` type parameter in the return type, provide additional context of which parts of the chain can and can't support the `?` operator.
```
error[E0277]: `?` couldn't convert the error to `String`
--> $DIR/question-mark-result-err-mismatch.rs:27:25
|
LL | fn bar() -> Result<(), String> {
| ------------------ expected `String` because of this
LL | let x = foo();
| ----- this has type `Result<_, String>`
...
LL | .map_err(|_| ())?;
| ---------------^ the trait `From<()>` is not implemented for `String`
| |
| this can't be annotated with `?` because it has type `Result<_, ()>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
<String as From<char>>
<String as From<Box<str>>>
<String as From<Cow<'a, str>>>
<String as From<&str>>
<String as From<&mut str>>
<String as From<&String>>
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
```
Fix#72124.
Remove `#[rustc_host]`, use internal desugaring
Also removed a way for users to explicitly specify the host param since that isn't particularly useful. This should eliminate any pain with encoding attributes across crates and etc.
r? `@compiler-errors`
coverage: Be more strict about what counts as a "visible macro"
This is a follow-up to the workaround in #117827, and I believe it now properly fixes#117788.
The old code treats a span as having a “visible macro” if it is part of a macro-expansion, and its parent callsite's context is the same as the body span's context. But if the body span is itself part of an expansion, the macro in question might not actually be visible from the body span. That results in the macro name's length being meaningless as a span offset.
We now only consider spans whose parent callsite is the same as the source callsite, i.e. the parent has no parent.
---
I've also included some related cleanup for the code added by #117827. That code was more complicated than normal, because I wanted it to be easy to backport to stable/beta.
Added shadowed hint for overlapping associated types
Previously, when you tried to set an associated type that is shadowed by an associated type in a subtrait, like this:
```rust
trait A {
type X;
}
trait B: A {
type X; // note: this is legal
}
impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
fn clone(&self) -> Self {
todo!()
}
}
you got a confusing error message, that says nothing about the shadowing:
error[E0719]: the value of the associated type `X` (from trait `B`) is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` (from trait `A`) must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `X` defined here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ help: specify the associated type: `B<X=Y, X=Y, X = Type>`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
```
Now instead, the error shows that the associated type is shadowed, and suggests renaming as a potential fix.
```rust
error[E0719]: the value of the associated type `X` in trait `B` is already specified
--> test.rs:9:34
|
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| --- ^^^ re-bound here
| |
| `X` bound here first
error[E0191]: the value of the associated type `X` in `A` must be specified
--> test.rs:9:27
|
2 | type X;
| ------ `A::X` defined here
...
6 | type X; // note: this is legal
| ------ `A::X` shadowed here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
| ^^^^^^^^^^^ associated type `X` must be specified
|
help: consider renaming this associated type
--> test.rs:2:5
|
2 | type X;
| ^^^^^^
help: consider renaming this associated type
--> test.rs:6:5
|
6 | type X; // note: this is legal
| ^^^^^^
```
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
The rename help message is only emitted when the trait is local. This is true both for the supertrait as for the subtrait.
There might be cases where you can use the fully qualified path (for instance, in a where clause), but this PR currently does not deal with that.
fixes#100109
(continues from #117642, because I didn't know renaming the branch would close the PR)
Shadowing the associated type of a supertrait is allowed.
This however makes it impossible to set the associated type
of the supertrait in a dyn object.
This PR makes the error message for that case clearer, like
adding a note that shadowing is happening, as well as suggesting
renaming of one of the associated types.
r=petrochenckov
Use `unwinding` crate for unwinding on Xous platform
This patch adds support for using [unwinding](https://github.com/nbdd0121/unwinding) on platforms where libunwinding isn't viable. An example of such a platform is `riscv32imac-unknown-xous-elf`.
### Background
The Rust project maintains a fork of llvm at [llvm-project](https://github.com/rust-lang/llvm-project/) where it applies patches on top of the llvm project. This mostly seems to be to get unwinding support for the SGX project, and there may be other patches that I'm unaware of.
There is a lot of machinery in the build system to support compiling `libunwind` on other platforms, and I needed to add additional patches to llvm in order to add support for Xous.
Rather than continuing down this path, it seemed much easier to use a Rust-based library. The `unwinding` crate by `@nbdd0121` fits this description perfectly.
### Future work
This could potentially replace the custom patches for `libunwind` on other platforms such as SGX, and could enable unwinding support on many more exotic platforms.
### Anti-goals
This is not designed to replace `libunwind` on tier-one platforms or those where unwinding support already exists. There is already a well-established approach for unwinding there. Instead, this aims to enable unwinding on new platforms where C++ code may be difficult to compile.