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`
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`.
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()`.
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.
`build_session` is passed an `EarlyErrorHandler` and then constructs a
`Handler`. But the `EarlyErrorHandler` is still used for some time after
that.
This commit changes `build_session` so it consumes the passed
`EarlyErrorHandler`, and also drops it as soon as the `Handler` is
built. As a result, `parse_cfg` and `parse_check_cfg` now take a
`Handler` instead of an `EarlyErrorHandler`.
Although, we would like to avoid crashes whenever
possible, and that's why I wanted to make this API fallible. It's
looking pretty hard to do proper validation.
I think many of our APIs will unfortunately depend on the user doing
the correct thing since at the MIR level we are working on,
we expect types to have been checked already.
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`
Provide structured suggestion for type mismatch in loop
We currently provide only a `help` message, this PR introduces the last two structured suggestions instead:
```
error[E0308]: mismatched types
--> $DIR/issue-98982.rs:2:5
|
LL | fn foo() -> i32 {
| --- expected `i32` because of return type
LL | / for i in 0..0 {
LL | | return i;
LL | | }
| |_____^ expected `i32`, found `()`
|
note: the function expects a value to always be returned, but loops might run zero times
--> $DIR/issue-98982.rs:2:5
|
LL | for i in 0..0 {
| ^^^^^^^^^^^^^ this might have zero elements to iterate on
LL | return i;
| -------- if the loop doesn't execute, this value would never get returned
help: return a value for the case when the loop has zero elements to iterate on
|
LL ~ }
LL ~ /* `i32` value */
|
help: otherwise consider changing the return type to account for that possibility
|
LL ~ fn foo() -> Option<i32> {
LL | for i in 0..0 {
LL ~ return Some(i);
LL ~ }
LL ~ None
|
```
Fix#98982.
Report errors in jobserver inherited through environment variables
This pr attempts to catch situations, when jobserver exists, but is not being inherited.
r? `@petrochenkov`
Because a macro invocation can expand to a never pattern, we can't rule
out a `arm!(),` arm at parse time. Instead we detect that case at
expansion time, if the macro tries to output a pattern followed by `=>`.
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.
move packed-struct tests into packed/ folder
We already have a bunch of other tests named `packed/packed-struct*`, no reason to have these two tests be separate.
Add more information to StableMIR Instance
Allow stable MIR users to retrieve an instance function signature, the index for a VTable instance and more information about its underlying definition.
These are needed to properly interpret function calls, either via VTable or direct calls. The `CrateDef` implementation will also allow users to emit diagnostic messages.
I also fixed a few issues that we had identified before with how we were retrieving body of things that may not have a body available.
Handle recursion limit for subtype and well-formed predicates
Adds a recursion limit check for subtype predicates and well-formed predicates.
`-Ztrait-solver=next` currently panics with unimplemented for these cases.
These cases are arguably bugs in the occurs check but:
- I could not find a simple way to fix the occurs check
- There should still be a recursion limit check to prevent hangs anyway.
closes#117151
r? types
Centralize live loans maintenance to fix scope differences due to liveness
As found in the recent [polonius crater run](https://github.com/rust-lang/rust/pull/117593#issuecomment-1801398892), NLLs and the location-insensitive polonius computed different scopes on some specific CFG shapes, e.g. the following.
![image](https://github.com/rust-lang/rust/assets/247183/c3649f5e-3058-454e-854e-1a6b336bdd5e)
I had missed that liveness data was pushed from different sources than just the liveness computation: there are a few places that do this -- and some of them may be unneeded or at the very least untested, as no tests changed when I tried removing some of them.
Here, `_6` is e.g. dead on entry to `bb2[0]` during `liveness::trace`, but its regions will be marked as live later during "constraint generation" (which I plan to refactor away and put in the liveness module soon). This should cause the inflowing loans to be marked live, but they were only computed in `liveness::trace`.
Therefore, this PR moves live loan maintenance to `LivenessValues`, so that the various places pushing liveness data will all also update live loans at the same time -- except for promoteds which I don't believe need them, and their liveness handling is already interesting/peculiar.
All the regressions I saw in the initial crater run were related to this kind of shapes, and this change did fix all of them on the [next run](https://github.com/rust-lang/rust/pull/117593#issuecomment-1826132145).
r? `@matthewjasper`
(This will conflict with #117880 but whichever lands first is fine by me, the end goal is the same for both)
Restore `#![no_builtins]` crates participation in LTO.
After #113716, we can make `#![no_builtins]` crates participate in LTO again.
`#![no_builtins]` with LTO does not result in undefined references to the error. I believe this type of issue won't happen again.
Fixes#72140. Fixes#112245. Fixes#110606. Fixes#105734. Fixes#96486. Fixes#108853. Fixes#108893. Fixes#78744. Fixes#91158. Fixes https://github.com/rust-lang/cargo/issues/10118. Fixes https://github.com/rust-lang/compiler-builtins/issues/347.
The `nightly-2023-07-20` version does not always reproduce problems due to changes in compiler-builtins, core, and user code. That's why this issue recurs and disappears.
Some issues were not tested due to the difficulty of reproducing them.
r? pnkfelix
cc `@bjorn3` `@japaric` `@alexcrichton` `@Amanieu`
Stabilize C string literals
RFC: https://rust-lang.github.io/rfcs/3348-c-str-literal.html
Tracking issue: https://github.com/rust-lang/rust/issues/105723
Documentation PR (reference manual): https://github.com/rust-lang/reference/pull/1423
# Stabilization report
Stabilizes C string and raw C string literals (`c"..."` and `cr#"..."#`), which are expressions of type [`&CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html). Both new literals require Rust edition 2021 or later.
```rust
const HELLO: &core::ffi::CStr = c"Hello, world!";
```
C strings may contain any byte other than `NUL` (`b'\x00'`), and their in-memory representation is guaranteed to end with `NUL`.
## Implementation
Originally implemented by PR https://github.com/rust-lang/rust/pull/108801, which was reverted due to unintentional changes to lexer behavior in Rust editions < 2021.
The current implementation landed in PR https://github.com/rust-lang/rust/pull/113476, which restricts C string literals to Rust edition >= 2021.
## Resolutions to open questions from the RFC
* Adding C character literals (`c'.'`) of type `c_char` is not part of this feature.
* Support for `c"..."` literals does not prevent `c'.'` literals from being added in the future.
* C string literals should not be blocked on making `&CStr` a thin pointer.
* It's possible to declare constant expressions of type `&'static CStr` in stable Rust (as of v1.59), so C string literals are not adding additional coupling on the internal representation of `CStr`.
* The unstable `concat_bytes!` macro should not accept `c"..."` literals.
* C strings have two equally valid `&[u8]` representations (with or without terminal `NUL`), so allowing them to be used in `concat_bytes!` would be ambiguous.
* Adding a type to represent C strings containing valid UTF-8 is not part of this feature.
* Support for a hypothetical `&Utf8CStr` may be explored in the future, should such a type be added to Rust.
generic_const_exprs: suggest to add the feature, not use it
Usually our missing feature messages look something like
```
= help: add `#![feature(inline_const)]` to the crate attributes to enable
```
However `generic_const_exprs` used a different verb. That's inconsistent and it also means playground won't add that nice hyperlink to add the feature automatically. So let's use the same verb as everywhere else.
rustdoc: `div.where` instead of fmt-newline class
This is about equally readable, a lot more terse, and stops special-casing functions and methods.
```console
$ du -hs doc-old/ doc-new/
671M doc-old/
670M doc-new/
```
Add `-Zfunction-return={keep,thunk-extern}` option
This is intended to be used for Linux kernel RETHUNK builds.
With this commit (optionally backported to Rust 1.73.0), plus a patched Linux kernel to pass the flag, I get a RETHUNK build with Rust enabled that is `objtool`-warning-free and is able to boot in QEMU and load a sample Rust kernel module.
Issue: https://github.com/rust-lang/rust/issues/116853.
On Fn arg mismatch for a fn path, suggest a closure
When encountering a fn call that has a path to another fn being passed in, where an `Fn` impl is expected, and the arguments differ, suggest wrapping the argument with a closure with the appropriate arguments.
The last `help` is new:
```
error[E0631]: type mismatch in function arguments
--> $DIR/E0631.rs:9:9
|
LL | fn f(_: u64) {}
| ------------ found signature defined here
...
LL | foo(f);
| --- ^ expected due to this
| |
| required by a bound introduced by this call
|
= note: expected function signature `fn(usize) -> _`
found function signature `fn(u64) -> _`
note: required by a bound in `foo`
--> $DIR/E0631.rs:3:11
|
LL | fn foo<F: Fn(usize)>(_: F) {}
| ^^^^^^^^^ required by this bound in `foo`
help: consider wrapping the function in a closure
|
LL | foo(|arg0: usize| f(/* u64 */));
| +++++++++++++ +++++++++++
```
This is intended to be used for Linux kernel RETHUNK builds.
With this commit (optionally backported to Rust 1.73.0), plus a
patched Linux kernel to pass the flag, I get a RETHUNK build with
Rust enabled that is `objtool`-warning-free and is able to boot in
QEMU and load a sample Rust kernel module.
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This is about equally readable, a lot more terse, and stops
special-casing functions and methods.
```console
$ du -hs doc-old/ doc-new/
671M doc-old/
670M doc-new/
```
Add thinlto support to codegen, assembly and coverage tests
Using `--emit=llvm-ir` with thinlto usually result in multiple IR files.
Resolve test case failure issue reported in #113923.
Tweak message on ADT with private fields building
When trying to create an inaccessible ADT due to private fields, handle the case when no fields were passed.
```
error: cannot construct `Foo` with struct literal syntax due to private fields
--> $DIR/issue-76077.rs:8:5
|
LL | foo::Foo {};
| ^^^^^^^^
|
= note: private field `you_cant_use_this_field` that was not provided
```
rustdoc-search: allow spaces around `::` in path query
This restriction made sense back when spaces separated function parameters, but now that they separate path components, there's no real ambiguity any more.
Additionally, the Rust language allows it.
The other two commits are misc code cleanup.
Fix `PartialEq` args when `#[const_trait]` is enabled
This is based off of your PR that enforces effects on all methods, so just see the last commits.
r? fee1-dead
When encountering a fn call that has a path to another fn being passed
in, where an `Fn` impl is expected, and the arguments differ, suggest
wrapping the argument with a closure with the appropriate arguments.
When trying to create an inaccessible ADT due to private fields, handle
the case when no fields were passed.
```
error: cannot construct `Foo` with struct literal syntax due to private fields
--> $DIR/issue-76077.rs:8:5
|
LL | foo::Foo {};
| ^^^^^^^^
|
= note: private field `you_cant_use_this_field` that was not provided
```
This restriction made sense back when spaces separated function
parameters, but now that they separate path components, there's
no real ambiguity any more.
Additionally, the Rust language allows it.
ConstProp: Correctly remove const if unknown value assigned to it.
Closes#118328
The problematic sequence of MIR is:
```rust
_1 = const 0_usize;
_1 = const _; // This is an associated constant we can't know before monomorphization.
_0 = _1;
```
1. When `ConstProp::visit_assign` happens on `_1 = const 0_usize;`, it records that `0x0usize` is the value for `_1`.
2. Next `visit_assign` happens on `_1 = const _;`. Because the rvalue `.has_param()`, it can't be const evaled.
3. Finaly, `visit_assign` happens on `_0 = _1;`. Here it would think the value of `_1` was `0x0usize` from step 1.
The solution is to remove consts when checking the RValue fails, as they may have contained values that should now be invalidated, as that local was overwritten.
This should probably be back-ported to beta. Stable is more iffy, as it's gone unidentified since 1.70, so I only think it's worthwhile if there's another reason for a 1.74.1 release anyway.
Suggest `let` or `==` on typo'd let-chain
When encountering a bare assignment in a let-chain, suggest turning the
assignment into a `let` expression or an equality check.
```
error: expected expression, found `let` statement
--> $DIR/bad-if-let-suggestion.rs:5:8
|
LL | if let x = 1 && i = 2 {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
|
LL | if let x = 1 && let i = 2 {}
| +++
help: you might have meant to compare for equality
|
LL | if let x = 1 && i == 2 {}
| +
```
Add `never_patterns` feature gate
This PR adds the feature gate and most basic parsing for the experimental `never_patterns` feature. See the tracking issue (https://github.com/rust-lang/rust/issues/118155) for details on the experiment.
`@scottmcm` has agreed to be my lang-team liaison for this experiment.
Fix coroutine validation for mixed panic strategy
Validation introduced in #113124 allows `UnwindAction::Continue` and `TerminatorKind::Resume` to occur only in functions with ABI that can unwind. The function ABI depends on the panic strategy, which can vary across crates.
Usually MIR is built and validated in the same crate. The coroutine drop glue thus far was an exception. As a result validation could fail when mixing different panic strategies.
Avoid the problem by executing `AbortUnwindingCalls` along with the validation.
Fixes#116953.
Eagerly return `ExprKind::Err` on `yield`/`await` in wrong coroutine context
This PR does 2 things:
1. Refuses to lower `.await` or `yield` when we are outside of the right coroutine context for the operator. Instead, we lower to `hir::ExprKind::Err`, to silence subsequent redundant errors.
2. Reworks a bit of the span tracking in `LoweringContext` to fix a bad span when we have something like `let x = [0; async_fn().await]` where the `await` is inside of an anon const. The span for the "item" still kinda sucks, since it overlaps with the `await` span, but at least it's accurate.