never_patterns: Parse match arms with no body
Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
None => { foo(); }
Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).
~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit
r? `@compiler-errors`
Resolve associated item bindings by namespace
This is the 3rd commit split off from #118360 with tests reblessed (they no longer contain duplicated diags which were caused by 4c0addc80af4666f26d7ad51fe34a0e2dd0b8b74) & slightly adapted (removed supertraits from a UI test, cc #118040).
> * Resolve all assoc item bindings (type, const, fn (feature `return_type_notation`)) by namespace instead of trying to resolve a type first (in the non-RTN case) and falling back to consts afterwards. This is consistent with RTN. E.g., for `Tr<K = {…}>` we now always try to look up assoc consts (this extends to supertrait bounds). This gets rid of assoc tys shadowing assoc consts in assoc item bindings which is undesirable & inconsistent (types and consts live in different namespaces after all)
> * Consolidate the resolution of assoc {ty, const} bindings and RTN (dedup, better diags for RTN)
> * Fix assoc consts being labeled as assoc *types* in several diagnostics
> * Make a bunch of diagnostics translatable
Fixes#112560 (error → pass).
As discussed
r? `@compiler-errors`
---
**Addendum**: What I call “associated item bindings” are commonly referred to as “type bindings” for historical reasons. Nowadays, “type bindings” include assoc type bindings, assoc const bindings and RTN (return type notation) which is why I prefer not to use this outdated term.
discard invalid spans in external blocks
Fixes#116203
This PR has discarded the invalid `const_span`, thereby making the format more neat.
r? ``@Nilstrieb``
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.
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`
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`
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`
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
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:28:25
|
LL | fn bar() -> Result<(), String> {
| ------------------ expected `String` because of this
LL | let x = foo();
| ----- this can be annotated with `?` because it has type `Result<String, String>`
LL | let one = x
LL | .map(|s| ())
| ----------- this can be annotated with `?` because it 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.
Add `deeply_normalize_for_diagnostics`, use it in coherence
r? lcnr
Normalize trait refs used for coherence error reporting with `-Ztrait-solver=next-coherence`.
Two things:
1. I said before that we can't add this to `TyErrCtxt` because we compute `OverlapResult`s even if there are no diagnostics being emitted, e.g. for a reservation impl.
2. I didn't want to add this to an `InferCtxtExt` trait because I felt it was unnecessary. I don't particularly care about the API though.
Pretty print `Fn<(..., ...)>` trait refs with parentheses (almost) always
It's almost always better, at least in diagnostics, to print `Fn(i32, u32)` instead of `Fn<(i32, u32)>`.
Related to but doesn't fix#118225. That needs a separate fix.
Add support for making lib features internal
We have the notion of an "internal" lang feature: a feature that is never intended to be stabilized, and using which can cause ICEs and other issues without that being considered a bug.
This extends that idea to lib features as well. It is an alternative to https://github.com/rust-lang/rust/pull/115623: instead of using an attribute to declare lib features internal, we simply do this based on the name. Everything ending in `_internals` or `_internal` is considered internal.
Then we rename `core_intrinsics` to `core_intrinsics_internal`, which fixes https://github.com/rust-lang/rust/issues/115597.
Add support for `gen fn`
This builds on #116447 to add support for `gen fn` functions. For the most part we follow the same approach as desugaring `async fn`, but replacing `Future` with `Iterator` and `async {}` with `gen {}` for the body.
The version implemented here uses the return type of a `gen fn` as the yield type. For example:
```rust
gen fn count_to_three() -> i32 {
yield 1;
yield 2;
yield 3;
}
```
In the future, I think we should experiment with a syntax like `gen fn count_to_three() yield i32 { ... }`, but that can go in another PR.
cc `@oli-obk` `@compiler-errors`
Remove the `precise_pointer_size_matching` feature gate
`usize` and `isize` are special for pattern matching because their range might depend on the platform. To make code portable across platforms, the following is never considered exhaustive:
```rust
let x: usize = ...;
match x {
0..=18446744073709551615 => {}
}
```
Because of how rust handles constants, this also unfortunately counts `0..=usize::MAX` as non-exhaustive. The [`precise_pointer_size_matching`](https://github.com/rust-lang/rust/issues/56354) feature gate was introduced both for this convenience and for the possibility that the lang team could decide to allow the above.
Since then, [half-open range patterns](https://github.com/rust-lang/rust/issues/67264) have been implemented, and since #116692 they correctly support `usize`/`isize`:
```rust
match 0usize { // exhaustive!
0..5 => {}
5.. => {}
}
```
I believe this subsumes all the use cases of the feature gate. Moreover no attempt has been made to stabilize it in the 5 years of its existence. I therefore propose we retire this feature gate.
Closes https://github.com/rust-lang/rust/issues/56354
Tweak unclosed generics errors
Remove unnecessary span label for parse errors that already have a suggestion.
Provide structured suggestion to close generics in more cases.
Tweak `.clone()` suggestion to work in more cases
When going through auto-deref, the `<T as Clone>` impl sometimes needs to be specified for rustc to actually clone the value and not the reference.
```
error[E0507]: cannot move out of dereference of `S`
--> $DIR/needs-clone-through-deref.rs:15:18
|
LL | for _ in self.clone().into_iter() {}
| ^^^^^^^^^^^^ ----------- value moved due to this method call
| |
| move occurs because value has type `Vec<usize>`, which does not implement the `Copy` trait
|
note: `into_iter` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | for _ in <Vec<usize> as Clone>::clone(&self.clone()).into_iter() {}
| ++++++++++++++++++++++++++++++ +
```
When encountering a move error, look for implementations of `Clone` for the moved type. If there is one, check if all its obligations are met. If they are, we suggest cloning without caveats. If they aren't, we suggest cloning while mentioning the unmet obligations, potentially suggesting `#[derive(Clone)]` when appropriate.
```
error[E0507]: cannot move out of a shared reference
--> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:20:28
|
LL | let mut copy: Vec<U> = map.clone().into_values().collect();
| ^^^^^^^^^^^ ------------- value moved due to this method call
| |
| move occurs because value has type `HashMap<T, U, Hash128_1>`, which does not implement the `Copy` trait
|
note: `HashMap::<K, V, S>::into_values` takes ownership of the receiver `self`, which moves value
--> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
help: you could `clone` the value and consume it, if the `Hash128_1: Clone` trait bound could be satisfied
|
LL | let mut copy: Vec<U> = <HashMap<T, U, Hash128_1> as Clone>::clone(&map.clone()).into_values().collect();
| ++++++++++++++++++++++++++++++++++++++++++++ +
help: consider annotating `Hash128_1` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | pub struct Hash128_1;
|
```
Fix#109429.
When encountering multiple mutable borrows, suggest cloning and adding
derive annotations as needed.
```
error[E0596]: cannot borrow `sm.x` as mutable, as it is behind a `&` reference
--> $DIR/accidentally-cloning-ref-borrow-error.rs:32:9
|
LL | foo(&mut sm.x);
| ^^^^^^^^^ `sm` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: `Str` doesn't implement `Clone`, so this call clones the reference `&Str`
--> $DIR/accidentally-cloning-ref-borrow-error.rs:31:21
|
LL | let mut sm = sr.clone();
| ^^^^^^^
help: consider annotating `Str` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct Str {
|
help: consider specifying this binding's type
|
LL | let mut sm: &mut Str = sr.clone();
| ++++++++++
```
Fix#34629. Fix#76643. Fix#91532.
Structured `use` suggestion on privacy error
When encoutering a privacy error on an item through a re-export that is accessible in an alternative path, provide a structured suggestion with that path.
```
error[E0603]: module import `mem` is private
--> $DIR/private-std-reexport-suggest-public.rs:4:14
|
LL | use foo::mem;
| ^^^ private module import
|
note: the module import `mem` is defined here...
--> $DIR/private-std-reexport-suggest-public.rs:8:9
|
LL | use std::mem;
| ^^^^^^^^
note: ...and refers to the module `mem` which is defined here
--> $SRC_DIR/std/src/lib.rs:LL:COL
|
= note: you could import this
help: import `mem` through the re-export
|
LL | use std::mem;
| ~~~~~~~~
```
Fix#42909.
When encoutering a privacy error on an item through a re-export that is
accessible in an alternative path, provide a structured suggestion with
that path.
```
error[E0603]: module import `mem` is private
--> $DIR/private-std-reexport-suggest-public.rs:4:14
|
LL | use foo::mem;
| ^^^ private module import
|
note: the module import `mem` is defined here...
--> $DIR/private-std-reexport-suggest-public.rs:8:9
|
LL | use std::mem;
| ^^^^^^^^
note: ...and refers to the module `mem` which is defined here
--> $SRC_DIR/std/src/lib.rs:LL:COL
|
= note: you could import this
help: import `mem` through the re-export
|
LL | use std::mem;
| ~~~~~~~~
```
Fix#42909.