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
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
Remove mention of rust to make the error message generic.
The deprecation notice is used when in crates as well. This applies to versions Rust or Crates.
Relates #118148
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.
The deprecation notice is used when in crates as well. This applies to versions Rust or Crates.
Fixes#118148
Signed-off-by: Harold Dost <h.dost@criteo.com>
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.
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();
| ++++++++++
```
```
error[E0596]: cannot borrow `*inner` as mutable, as it is behind a `&` reference
--> $DIR/issue-91206.rs:14:5
|
LL | inner.clear();
| ^^^^^ `inner` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: you can `clone` the `Vec<usize>` value and consume it, but this might not be your desired behavior
--> $DIR/issue-91206.rs:11:17
|
LL | let inner = client.get_inner_ref();
| ^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying this binding's type
|
LL | let inner: &mut Vec<usize> = client.get_inner_ref();
| +++++++++++++++++
```
When encountering a case where `let x: T = (val: &T).clone();` and
`T: !Clone`, already mention that the reference is being cloned. We now
also suggest `#[derive(Clone)]` not only on `T` but also on type
parameters to satisfy blanket implementations.
```
error[E0308]: mismatched types
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:17:39
|
LL | let mut x: HashSet<Day> = v.clone();
| ------------ ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
| |
| expected due to this
|
= note: expected struct `HashSet<Day>`
found reference `&HashSet<Day>`
note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
--> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:17:39
|
LL | let mut x: HashSet<Day> = v.clone();
| ^
= help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied
help: consider annotating `Day` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | enum Day {
|
```
Case taken from # #41825.
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 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() {}
| ++++++++++++++++++++++++++++++ +
```
CC #109429.
[rustdoc] Don't generate the "Fields" heading if there is no field displayed
Fixes https://github.com/rust-lang/rust/issues/118195.
If no field is displayed, we should not generate the `Fields` heading in enum struct variants.
r? ``@notriddle``
Restrict what symbols can be used in `#[diagnostic::on_unimplemented]` format strings
This commit restricts what symbols can be used in a format string for any option of the `diagnostic::on_unimplemented` attribute. We previously allowed all the ad-hoc options supported by the internal `#[rustc_on_unimplemented]` attribute. For the stable attribute we only want to support generic parameter names and `{Self}` as parameters. For any other parameter an warning is emitted and the parameter is replaced by the literal parameter string, so for example `{integer}` turns into `{integer}`. This follows the general design of attributes in the `#[diagnostic]` attribute namespace, that any syntax "error" is treated as warning and subsequently ignored.
r? `@compiler-errors`
This commit restricts what symbols can be used in a format string for
any option of the `diagnostic::on_unimplemented` attribute. We
previously allowed all the ad-hoc options supported by the internal
`#[rustc_on_unimplemented]` attribute. For the stable attribute we only
want to support generic parameter names and `{Self}` as parameters. For
any other parameter an warning is emitted and the parameter is replaced
by the literal parameter string, so for example `{integer}` turns into
`{integer}`. This follows the general design of attributes in the
`#[diagnostic]` attribute namespace, that any syntax "error" is treated
as warning and subsequently ignored.
Rollup of 3 pull requests
Successful merges:
- #117869 ([rustdoc] Add highlighting for comments in items declaration)
- #118525 (coverage: Skip spans that can't be un-expanded back to the function body)
- #118574 (rustc_session: Address all `rustc::potential_query_instability` lints)
r? `@ghost`
`@rustbot` modify labels: rollup
coverage: Skip spans that can't be un-expanded back to the function body
When we extract coverage spans from MIR, we try to "un-expand" them back to spans that are inside the function's body span.
In cases where that doesn't succeed, the current code just swaps in the entire body span instead. But that tends to result in coverage spans that are completely unrelated to the control flow of the affected code, so it's better to just discard those spans.
---
Extracted from #118305, since this is a general improvement that isn't specific to branch coverage.
---
`@rustbot` label +A-code-coverage
[rustdoc] Add highlighting for comments in items declaration
Fixes#117555.
So after the discussion in https://github.com/rust-lang/rust/pull/117643, the outcome was that having the comments in the item declaration at the same level (in term of color) as the rest of the code was actually a bit distracting and could be improved.
The current highlighting color for comments is "lighter" than the rest and I think it fits perfectly to improve the current situation. With this, we now have different "levels" which makes it easier to read and filter out what we want when reading the items declaration.
Here's a screenshot:
![image](https://github.com/rust-lang/rust/assets/3050060/dbd98029-e98b-4997-9a89-6b823eaac9a4)
r? `@notriddle`