Rollup of 9 pull requests
Successful merges:
- #135340 (Add `explicit_extern_abis` Feature and Enforce Explicit ABIs)
- #139440 (rustc_target: RISC-V: feature addition batch 2)
- #139667 (cfi: Remove #[no_sanitize(cfi)] for extern weak functions)
- #139828 (Don't require rigid alias's trait to hold)
- #139854 (Improve parse errors for stray lifetimes in type position)
- #139889 (Clean UI tests 3 of n)
- #139894 (Fix `opt-dist` CLI flag and make it work without LLD)
- #139900 (stepping into impls for normalization is unproductive)
- #139915 (replace some #[rustc_intrinsic] usage with use of the libcore declarations)
r? `@ghost`
`@rustbot` modify labels: rollup
Stabilize `cfg_boolean_literals`
Closes#131204
`@rustbot` labels +T-lang +I-lang-nominated
This will end up conflicting with the test in #138293 so whichever doesn't land first will need updating
--
# Stabilization Report
## General design
### What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized?
[RFC 3695](https://github.com/rust-lang/rfcs/pull/3695), none.
### What behavior are we committing to that has been controversial? Summarize the major arguments pro/con.
None
### Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those?
None
## Has a call-for-testing period been conducted? If so, what feedback was received?
Yes; only positive feedback was received.
## Implementation quality
### Summarize the major parts of the implementation and provide links into the code (or to PRs)
Implemented in [#131034](https://github.com/rust-lang/rust/pull/131034).
### Summarize existing test coverage of this feature
- [Basic usage, including `#[cfg()]`, `cfg!()` and `#[cfg_attr()]`](6d71251cf9/tests/ui/cfg/true-false.rs)
- [`--cfg=true/false` on the command line being accessible via `r#true/r#false`](6d71251cf9/tests/ui/cfg/raw-true-false.rs)
- [Interaction with the unstable `#[doc(cfg(..))]` feature](https://github.com/rust-lang/rust/tree/6d71251/tests/rustdoc-ui/cfg-boolean-literal.rs)
- [Denying `--check-cfg=cfg(true/false)`](https://github.com/rust-lang/rust/tree/6d71251/tests/ui/check-cfg/invalid-arguments.rs)
- Ensuring `--cfg false` on the command line doesn't change the meaning of `cfg(false)`: `tests/ui/cfg/cmdline-false.rs`
- Ensuring both `cfg(true)` and `cfg(false)` on the same item result in it being disabled: `tests/ui/cfg/both-true-false.rs`
### What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking?
The above mentioned issue; it should not block as it interacts with another unstable feature.
### What FIXMEs are still in the code for that feature and why is it ok to leave them there?
None
### Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization
- `@clubby789` (RFC)
- `@Urgau` (Implementation in rustc)
### Which tools need to be adjusted to support this feature. Has this work been done?
`rustdoc`'s unstable`#[doc(cfg(..)]` has been updated to respect it. `cargo` has been updated with a forward compatibility lint to enable supporting it in cargo once stabilized.
## Type system and execution rules
### What updates are needed to the reference/specification? (link to PRs when they exist)
A few lines to be added to the reference for configuration predicates, specified in the RFC.
Improve parse errors for stray lifetimes in type position
While technically & syntactically speaking lifetimes do begin[^1] types in type contexts (this essentially excludes generic argument lists) and require a following `+` to form a complete type (`'a +` denotes a bare trait object type), the likelihood that a user meant to write a lifetime-prefixed bare trait object type in *modern* editions (Rust ≥2021) when placing a lifetime into a type context is incredibly low (they would need to add at least three tokens to turn it into a *semantically* well-formed TOT: `'a` → `dyn 'a + Trait`).
Therefore let's *lie* in modern editions (just like in PR https://github.com/rust-lang/rust/pull/131239, a precedent if you will) by stating "*expected type, found lifetime*" in such cases which is a lot more a approachable, digestible and friendly compared to "*lifetime in trait object type must be followed by `+`*" (as added in PR https://github.com/rust-lang/rust/pull/69760).
I've also added recovery for "ampersand-less" reference types (e.g., `'a ()`, `'a mut Ty`) in modern editions because it was trivial to do and I think it's not unlikely to occur in practice.
Fixes#133413.
[^1]: For example, in the context of decl macros, this implies that a lone `'a` always matches syntax fragment `ty` ("even if" there's a later macro matcher expecting syntax fragment `lifetime`). Rephrased, lifetimes (in type contexts) *commit* to the type parser.
Detect and provide suggestion for `&raw EXPR`
When emitting an error in the parser, and we detect that the previous token was `raw` and we *could* have consumed `const`/`mut`, suggest that this may have been a mistyped raw ref expr. To do this, we add `const`/`mut` to the expected token set when parsing `&raw` as an expression (which does not affect the "good path" of parsing, for the record).
This is kind of a rudimentary error improvement, since it doesn't actually attempt to recover anything, leading to some other knock-on errors b/c we still treat `&raw` as the expression that was parsed... but at least we add the suggestion! I don't think the parser grammar means we can faithfully recover `&raw EXPR` early, i.e. during `parse_expr_borrow`.
Fixes#133231
```
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
--> $DIR/attempted-access-non-fatal.rs:7:15
|
LL | let _ = 2.l;
| ^
|
help: if intended to be a floating point literal, consider adding a `0` after the period and a `f64` suffix
|
LL - let _ = 2.l;
LL + let _ = 2.0f64;
|
```
Trim extra whitespace when suggesting removal of invalid qualifiers when
parsing function pointer type.
Fixes: #133083
Signed-off-by: Tyrone Wu <wudevelops@gmail.com>
On parse errors where an ident is found where one wasn't expected, see if the next elements might have been meant as method call or field access.
```
error: expected one of `.`, `;`, `?`, `else`, or an operator, found `map`
--> $DIR/missing-dot-on-statement-expression.rs:7:29
|
LL | let _ = [1, 2, 3].iter()map(|x| x);
| ^^^ expected one of `.`, `;`, `?`, `else`, or an operator
|
help: you might have meant to write a method call
|
LL | let _ = [1, 2, 3].iter().map(|x| x);
| +
```
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body".
```
error: expected `{`, found `map`
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30
|
LL | for _ in [1, 2, 3].iter()map(|x| x) {}
| ^^^ expected `{`
|
help: you might have meant to write a method call
|
LL | for _ in [1, 2, 3].iter().map(|x| x) {}
| +
```
```
error: expected a pattern, found an expression
--> f889.rs:3:13
|
3 | let (x, y.drop()) = (1, 2); //~ ERROR
| ^^^^^^^^ not a pattern
|
= note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
error[E0532]: expected a pattern, found a function call
--> f889.rs:2:13
|
2 | let (x, drop(y)) = (1, 2); //~ ERROR
| ^^^^ not a tuple struct or tuple variant
|
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
```
Fix#97200.
The second suggestion shown here would previously incorrectly assume that the span corresponding to `⩵` was 2 bytes wide composed by 2 1 byte wide chars, so a span pointing at `==` could point only at one of the `=` to remove it. Instead, we now replace the whole thing (as we should have the whole time):
```
error: unknown start of token: \u{2a75}
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: Unicode character '⩵' (Two Consecutive Equals Signs) looks like '==' (Double Equals Sign), but it is not
|
LL | const A: usize == 2;
| ~~
error: unexpected `==`
--> $DIR/unicode-double-equals-recovery.rs:1:16
|
LL | const A: usize ⩵ 2;
| ^
|
help: try using `=` instead
|
LL | const A: usize = 2;
| ~
```
Go over all structured parser suggestions and make them verbose style.
When suggesting to add or remove delimiters, turn them into multiple suggestion parts.
When we have long code skips, we write `...` in the line number gutter.
For suggestions, we were "centering" the `...` with the line, but that was consistent with what we do in every other case.
Detect pub structs never constructed and unused associated constants
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.
This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using
r? <reviewer name>
-->
Lints never constructed public structs.
If we don't provide public methods to construct public structs with private fields, and don't construct them in the local crate. They would be never constructed. So that we can detect such public structs.
---
Update:
Also lints unused associated constants in traits.
The suggestion to use `let else` with an uninitialized refutable `let`
statement was erroneous: `let else` cannot be used with deferred
initialization.
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span
arround and mention it. If the type could continue being parsed as an
expression, suggest replacing the `:` with a `=`.
```
error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
--> file.rs:2:32
|
2 | let _: std::env::temp_dir().join("foo");
| - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
| |
| while parsing the type for `_`
| help: use `=` if you meant to assign
```
Fix#119665.
When encountering a verbose/multipart suggestion that has changes
that are only caused by different capitalization of ASCII letters that have
little differenciation, expand the message to highlight that fact (like we
already do for inline suggestions).
The logic to do this was already present, but implemented incorrectly.
Change the implicit `Sized` `Obligation` `Span` for call expressions to
include the whole expression. This aids the existing deduplication
machinery to reduce the number of errors caused by a single unsized
expression.