Do not ICE on invalid consts when walking mono-reachable blocks
The `bug!` here was written under the logic of "this condition is impossible, right?" except that of course, if the compiler is given code that results in an compile error, then the situation is possible.
So now we just direct errors into the already-existing path for when we can't do a mono-time optimization.
Fix substitution parts having a shifted underline in some cases
If two suggestions parts are side by side, the underline's offset:
(WIP PR as an example, not yet pushed)
```
error: expected a pattern, found an expression
--> ./main.rs:4:9
|
4 | 1 + 2 => 3
| ^^^^^ arbitrary expressions are not allowed in patterns
|
help: check the value in an arm guard
|
4 | n if n == 1 + 2 => 3
| ~ +++++++++++++
```
The emitter didn't take into account that the string had shrunk/grown if two substitution parts were side-by-side (surprisingly, there was only one case in the ui testsuite.)
```
help: check the value in an arm guard
|
4 | n if n == 1 + 2 => 3
| ~ +++++++++++++
```
``@rustbot`` label +A-suggestion-diagnostics
ast: Generalize item kind visiting
And avoid duplicating logic for visiting `Item`s with different kinds (regular, associated, foreign).
The diff is better viewed with whitespace ignored.
Port run-make `--print=native-static-libs` to rmake.rs
This PR port the run-make `--print=native-static-libs` test to rmake.rs
The dedup was really awful in the `Makefile`, I'm glad to finally have a proper dedup detection for this.
Related to https://github.com/rust-lang/rust/issues/121876
r? `@jieyouxu`
`obligations_for_self_ty`: use `ProofTreeVisitor` for nested goals
As always, dealing with proof trees continues to be a hacked together mess. After this PR and #124380 the only remaining blocker for core is https://github.com/rust-lang/trait-system-refactor-initiative/issues/90. There is also a `ProofTreeVisitor` issue causing an ICE when compiling `alloc` which I will handle in a separate PR. This issue likely affects coherence diagnostics more generally.
The core idea is to extend the proof tree visitor to support visiting nested candidates without using a `probe`. We then simply recurse into nested candidates if they are the only potentially applicable candidate for a given goal and check whether the self type matches the expected one.
For that to work, we need to improve `CanonicalState` to also handle unconstrained inference variables created inside of the trait solver. This is done by extending the `var_values` of `CanoncalState` with each fresh inference variables. Furthermore, we also store the state of all inference variables at the end of each probe. When recursing into `InspectCandidates` we then unify the values of all these states.
r? `@compiler-errors`
Keep the LIB env var in the compiler-builtins test
The `tests/run-make/compiler-builtins` test was failing for me with Visual Studio 2022, complaining that it couldn't find `kernel32.lib`.
For whatever reason, with VS 2022 we need to keep the `LIB` environment variable when invoking Cargo so that the linker can find the Windows SDK libs.
uses a `ProofTreeVisitor` to look into nested
goals when looking at the pending obligations
during hir typeck. Used by closure signature
inference, coercion, and for async functions.
`-Z debug-macros` is "stabilized" by enabling it by default and removing.
`-Z collapse-macro-debuginfo` is stabilized as `-C collapse-macro-debuginfo`.
It now supports all typical boolean values (`parse_opt_bool`) in addition to just yes/no.
Default value of `collapse_debuginfo` was changed from `false` to `external` (i.e. collapsed if external, not collapsed if local).
`#[collapse_debuginfo]` attribute without a value is no longer supported to avoid guessing the default.
Don't ICE when `codegen_select_candidate` returns ambiguity in new solver
Because we merge identical candidates, we may have >1 impl candidate to in `codegen_select_error` but *not* have a trait error.
r? lcnr
Detect borrow error involving sub-slices and suggest `split_at_mut`
```
error[E0499]: cannot borrow `foo` as mutable more than once at a time
--> $DIR/suggest-split-at-mut.rs:13:18
|
LL | let a = &mut foo[..2];
| --- first mutable borrow occurs here
LL | let b = &mut foo[2..];
| ^^^ second mutable borrow occurs here
LL | a[0] = 5;
| ---- first borrow later used here
|
= help: use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
```
Address most of #58792.
For follow up work, we should emit a structured suggestion for cases where we can identify the exact `let (a, b) = foo.split_at_mut(2);` call that is needed.
```
error[E0499]: cannot borrow `foo` as mutable more than once at a time
--> $DIR/suggest-split-at-mut.rs:13:18
|
LL | let a = &mut foo[..2];
| --- first mutable borrow occurs here
LL | let b = &mut foo[2..];
| ^^^ second mutable borrow occurs here
LL | a[0] = 5;
| ---- first borrow later used here
|
= help: use `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
```
Address most of #58792.
For follow up work, we should emit a structured suggestion for cases where we can identify the exact `let (a, b) = foo.split_at_mut(2);` call that is needed.
Enforce closure args + return type are WF
I found this out when investigating https://github.com/rust-lang/rust/issues/123461#issuecomment-2040894359. Turns out we don't register WF obligations for closure args and return types, leading to the ICE.
~~I think this is a useful thing to check for, but I'd like to check what the fallout is.~~ crater is complete.
~~Worst case, I think we should enforce this across an edition boundary (and possibly eventually migrate this for all editions) -- this should be super easy to do, since this is a check in HIR wfcheck, so it can be made edition dependent.~~ I believe the regressions are manageable enough to not necessitate edition-specific behavior.
Fixes#123461
Set writable and dead_on_unwind attributes for sret arguments
Set the `writable` and `dead_on_unwind` attributes for `sret` arguments. This allows call slot optimization to remove more memcpy's.
See https://llvm.org/docs/LangRef.html#parameter-attributes for the specification of these attributes. In short, the statement we're making here is that:
* The return slot is writable.
* The return slot will not be read if the function unwinds.
Fixes https://github.com/rust-lang/rust/issues/90595.
Rewrite the `no-input-file.stderr` test in Rust and support diff
Rewrite the `no-input-file.stderr` test from #121876.
Use the `similar` lib to replace the `diff` command.
Provide more context and suggestions in borrowck errors involving closures
Start pointing to where bindings where declared when they are captured in closures:
```
error[E0597]: `x` does not live long enough
--> $DIR/suggest-return-closure.rs:23:9
|
LL | let x = String::new();
| - binding `x` declared here
...
LL | |c| {
| --- value captured here
LL | x.push(c);
| ^ borrowed value does not live long enough
...
LL | }
| -- borrow later used here
| |
| `x` dropped here while still borrowed
```
Suggest cloning in more cases involving closures:
```
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
|
LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {},
| ++++++++
```
Mention when type parameter could be Clone
```
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:7:9
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait
...
LL | (t, t)
| - ^ value used here after move
| |
| value moved here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/use_of_moved_value_copy_suggestions.rs:4:16
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | (t, t)
| - you could clone this value
help: consider restricting type parameter `T`
|
LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) {
| ++++++
```
The `help` is new. On ADTs, we also extend the output with span labels:
```
error[E0507]: cannot move out of static item `FOO`
--> $DIR/issue-17718-static-move.rs:6:14
|
LL | let _a = FOO;
| ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/issue-17718-static-move.rs:1:1
|
LL | struct Foo;
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _a = FOO;
| --- you could clone this value
help: consider borrowing here
|
LL | let _a = &FOO;
| +
```
Suggest cloning captured binding in move closure
```
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-move-by-capture.rs:9:29
|
LL | let bar: Box<_> = Box::new(3);
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
| -- captured by this `FnMut` closure
LL | let _h = to_fn_once(move || -> isize { *bar });
| ^^^^^^^^^^^^^^^^ ----
| | |
| | variable moved due to use in closure
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| `bar` is moved here
|
help: clone the value before moving it into the closure 1
|
LL ~ let value = bar.clone();
LL ~ let _h = to_fn_once(move || -> isize { value });
|
```
```
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
--> $DIR/borrowck-move-by-capture.rs:9:29
|
LL | let bar: Box<_> = Box::new(3);
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
| -- captured by this `FnMut` closure
LL | let _h = to_fn_once(move || -> isize { *bar });
| ^^^^^^^^^^^^^^^^ ----
| | |
| | variable moved due to use in closure
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| `bar` is moved here
|
help: clone the value before moving it into the closure
|
LL ~ let value = bar.clone();
LL ~ let _h = to_fn_once(move || -> isize { value });
|
```
```
error[E0382]: use of moved value: `t`
--> $DIR/use_of_moved_value_copy_suggestions.rs:7:9
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| - move occurs because `t` has type `T`, which does not implement the `Copy` trait
...
LL | (t, t)
| - ^ value used here after move
| |
| value moved here
|
help: if `T` implemented `Clone`, you could clone the value
--> $DIR/use_of_moved_value_copy_suggestions.rs:4:16
|
LL | fn duplicate_t<T>(t: T) -> (T, T) {
| ^ consider constraining this type parameter with `Clone`
...
LL | (t, t)
| - you could clone this value
help: consider restricting type parameter `T`
|
LL | fn duplicate_t<T: Copy>(t: T) -> (T, T) {
| ++++++
```
The `help` is new. On ADTs, we also extend the output with span labels:
```
error[E0507]: cannot move out of static item `FOO`
--> $DIR/issue-17718-static-move.rs:6:14
|
LL | let _a = FOO;
| ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/issue-17718-static-move.rs:1:1
|
LL | struct Foo;
| ^^^^^^^^^^ consider implementing `Clone` for this type
...
LL | let _a = FOO;
| --- you could clone this value
help: consider borrowing here
|
LL | let _a = &FOO;
| +
```