Store #[stable] attribute's `since` value in structured form
Followup to https://github.com/rust-lang/rust/pull/116773#pullrequestreview-1680913901.
Prior to this PR, if you wrote an improper `since` version in a `stable` attribute, such as `#[stable(feature = "foo", since = "wat.0")]`, rustc would emit a diagnostic saying **_'since' must be a Rust version number, such as "1.31.0"_** and then throw out the whole `stable` attribute as if it weren't there. This strategy had 2 problems, both fixed in this PR:
1. If there was also a `#[deprecated]` attribute on the same item, rustc would want to enforce that the stabilization version is older than the deprecation version. This involved reparsing the `stable` attribute's `since` version, with a diagnostic **_invalid stability version found_** if it failed to parse. Of course this diagnostic was unreachable because an invalid `since` version would have already caused the `stable` attribute to be thrown out. This PR deletes that unreachable diagnostic.
2. By throwing out the `stable` attribute when `since` is invalid, you'd end up with a second diagnostic saying **_function has missing stability attribute_** even though your function is not missing a stability attribute. This PR preserves the `stable` attribute even when `since` cannot be parsed, avoiding the misleading second diagnostic.
Followups I plan to try next:
- Do the same for the `since` value of `#[deprecated]`.
- See whether it makes sense to also preserve `stable` and/or `unstable` attributes when they contain an invalid `feature`. What redundant/misleading diagnostics can this eliminate? What problems arise from not having a usable feature name for some API, in the situation that we're already failing compilation, so not concerned about anything that happens in downstream code?
Mark .rmeta files as /SAFESEH on x86 Windows.
Chrome links .rlibs with /WHOLEARCHIVE or -Wl,--whole-archive to prevent the linker from discarding static initializers. This works well, except on Windows x86, where lld complains:
error: /safeseh: lib.rmeta is not compatible with SEH
The fix is simply to mark the .rmeta as SAFESEH aware. This is trivially true, since the metadata file does not contain any executable code.
Stop telling people to submit bugs for internal feature ICEs
This keeps track of usage of internal features, and changes the message to instead tell them that using internal features is not supported.
I thought about several ways to do this but now used the explicit threading of an `Arc<AtomicBool>` through `Session`. This is not exactly incremental-safe, but this is fine, as this is set during macro expansion, which is pre-incremental, and also only affects the output of ICEs, at which point incremental correctness doesn't matter much anyways.
See [MCP 620.](https://github.com/rust-lang/compiler-team/issues/596)
![image](https://github.com/rust-lang/rust/assets/48135649/be661f05-b78a-40a9-b01d-81ad2dbdb690)
Rename AsyncCoroutineKind to CoroutineSource
pulled out of https://github.com/rust-lang/rust/pull/116447
Also refactors the printing infra of `CoroutineSource` to be ready for easily extending it with a `Gen` variant for `gen` blocks
Improve the warning messages for the `#[diagnostic::on_unimplemented]`
This commit improves warnings emitted for malformed on unimplemented attributes by:
* Improving the span of the warnings
* Adding a label message to them
* Separating the messages for missing and unexpected options
* Adding a help message that says which options are supported
r? `@compiler-errors`
I'm happy to work on further improvements, so feel free to make suggestions.
Return multiple object-safety violation errors and code improvements to the object-safety check
See individual commits for more information. Split off of #114260, since it turned out that the main intent of that PR was wrong.
r? oli-obk
This keeps track of usage of internal features, and changes the message
to instead tell them that using internal features is not supported.
See MCP 620.
Rollup of 7 pull requests
Successful merges:
- #117111 (Remove support for alias `-Z instrument-coverage`)
- #117141 (Require target features to match exactly during inlining)
- #117152 (Fix unwrap suggestion for async fn)
- #117154 (implement C ABI lowering for CSKY)
- #117159 (Work around the fact that `check_mod_type_wf` may spuriously return `ErrorGuaranteed`)
- #117163 (compiletest: Display compilation errors in mir-opt tests)
- #117173 (Make `Iterator` a lang item)
r? `@ghost`
`@rustbot` modify labels: rollup
Work around the fact that `check_mod_type_wf` may spuriously return `ErrorGuaranteed`
Even if that error is only emitted by `check_mod_item_types`.
fixes https://github.com/rust-lang/rust/issues/117153
A cleaner refactoring would merge/chain these queries in ways that ensure we only actually get an `ErrorGuaranteed` if there was an error emitted.
Fix unwrap suggestion for async fn
Use `body_fn_sig` to get the expected return type of the function instead of `ret_coercion` in `FnCtxt`. This avoids accessing the `ret_coercion` when it's already mutably borrowed (e.g. when checking `return` expressions).
Fixes#117144
r? `@chenyukang`
Require target features to match exactly during inlining
In general it is not correct to inline a callee with a target features
that are subset of the callee. Require target features to match exactly
during inlining.
The exact match could be potentially relaxed, but this would require
identifying specific feature that are allowed to differ, those that need
to match, and those that can be present in caller but not in callee.
This resolves MIR part of #116573. For other concerns with respect to
the previous implementation also see areInlineCompatible in LLVM.
Remove support for alias `-Z instrument-coverage`
This flag was stabilized in rustc 1.60.0 (2022-04-07) as `-C instrument-coverage`, but the old unstable flag was kept around (with a warning) as an alias to ease migration.
It should now be reasonable to remove the somewhat tricky code that implemented that alias.
Fixes#116980.
Merge `impl_wf_inference` (`check_mod_impl_wf`) check into coherence checking
Problem here is that we call `collect_impl_trait_in_trait_types` when checking `check_mod_impl_wf` which is performed before coherence. Due to the `tcx.sess.track_errors`, since we end up reporting an error, we never actually proceed to coherence checking, where we would be emitting a more useful impl overlap error.
This change means that we may report more errors in some cases, but can at least proceed far enough to leave a useful message for overlapping traits with RPITITs in them.
Fixes#116982
r? types
Remove fold code and add `Const::internal()` to StableMIR
We are not planning to support user generated constant in the foreseeable future, so we are cleaning up the fold logic and user created type for now. Users should use `Instance::resolve` in order to trigger monomorphization.
The Instance::resolve was however incomplete, since we weren't handling internalizing constants yet. Thus, I added that.
I decided to keep the `Const` fields private in case we decide to translate them lazily.
We are not planning to support user generated constant in the
foreseeable future, so we are removing the Fold logic for now in
favor of the Instance::resolve logic.
The Instance::resolve was however incomplete, since we weren't handling
internalizing constants yet. Thus, I added that.
I decided to keep the Const fields private in case we decide to
translate them lazily.
In general it is not correct to inline a callee with a target features
that are subset of the callee. Require target features to match exactly
during inlining.
The exact match could be potentially relaxed, but this would require
identifying specific feature that are allowed to differ, those that need
to match, and those that can be present in caller but not in callee.
This resolves MIR part of #116573. For other concerns with respect to
the previous implementation also see areInlineCompatible in LLVM.
Chrome links .rlibs with /WHOLEARCHIVE or -Wl,--whole-archive to prevent
the linker from discarding static initializers. This works well, except
on Windows x86, where lld complains:
error: /safeseh: lib.rmeta is not compatible with SEH
The fix is simply to mark the .rmeta as SAFESEH aware. This is trivially
true, since the metadata file does not contain any executable code.
Add method to convert internal to stable constructs
This is an alternative implementation to https://github.com/rust-lang/rust/pull/116999. I believe we can still improve the logic a bit here, but I wanted to see which direction we should go first.
In this implementation, the API is simpler and we keep Tables somewhat private. The definition is still public though, since we have to expose the Stable trait. However, there's a cost of keeping another thread-local and using `Rc`, but I'm hoping it will be a small cost.
r? ``@oli-obk``
r? ``@spastorino``
Suggest unwrap/expect for let binding type mismatch
Found it when investigating https://github.com/rust-lang/rust/issues/116738
I'm not sure whether it's a good style to suggest `unwrap`, seems it's may helpful for newcomers.
#116738 needs another fix to improve it.
Introduce `-C instrument-coverage=branch` to gate branch coverage
This was extracted from https://github.com/rust-lang/rust/pull/115061 and can land independently from other coverage related work.
The flag is unused for now, but is added in advance of adding branch coverage support.
It is an unstable, nightly only flag that needs to be used in combination with `-Zunstable-options`, like so: `-Zunstable-options -C instrument-coverage=branch`.
The goal is to develop branch coverage as an unstable opt-in feature first, before it matures and can be turned on by default.
Validate `feature` and `since` values inside `#[stable(…)]`
Previously the string passed to `#[unstable(feature = "...")]` would be validated as an identifier, but not `#[stable(feature = "...")]`. In the standard library there were `stable` attributes containing the empty string, and kebab-case string, neither of which should be allowed.
Pre-existing validation of `unstable`:
```rust
// src/lib.rs
#![allow(internal_features)]
#![feature(staged_api)]
#![unstable(feature = "kebab-case", issue = "none")]
#[unstable(feature = "kebab-case", issue = "none")]
pub struct Struct;
```
```console
error[E0546]: 'feature' is not an identifier
--> src/lib.rs:5:1
|
5 | #![unstable(feature = "kebab-case", issue = "none")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
For an `unstable` attribute, the need for an identifier is obvious because the downstream code needs to write a `#![feature(...)]` attribute containing that identifier. `#![feature(kebab-case)]` is not valid syntax and `#![feature(kebab_case)]` would not work if that is not the name of the feature.
Having a valid identifier even in `stable` is less essential but still useful because it allows for informative diagnostic about the stabilization of a feature. Compare:
```rust
// src/lib.rs
#![allow(internal_features)]
#![feature(staged_api)]
#![stable(feature = "kebab-case", since = "1.0.0")]
#[stable(feature = "kebab-case", since = "1.0.0")]
pub struct Struct;
```
```rust
// src/main.rs
#![feature(kebab_case)]
use repro::Struct;
fn main() {}
```
```console
error[E0635]: unknown feature `kebab_case`
--> src/main.rs:3:12
|
3 | #![feature(kebab_case)]
| ^^^^^^^^^^
```
vs the situation if we correctly use `feature = "snake_case"` and `#![feature(snake_case)]`, as enforced by this PR:
```console
warning: the feature `snake_case` has been stable since 1.0.0 and no longer requires an attribute to enable
--> src/main.rs:3:12
|
3 | #![feature(snake_case)]
| ^^^^^^^^^^
|
= note: `#[warn(stable_features)]` on by default
```