Enable `--check-cfg` by default in UI tests
This PR enables-by-default `--check-cfg` in UI tests, now that it has become stable.
To do so this PR does 2 main things:
- it introduce the `no-auto-check-cfg` directive to `compiletest`, to prevent any `--check-cfg` args (only to be used for `--check-cfg` tests)
- it updates the _remaining_[^1] UI tests by either:
- allowing the lint when neither expecting the lint nor giving the check-cfg args make sense
- give the appropriate check-cfg args
- or expect the lint, when it useful
[^1]: some preparation work was done in #123577#123702
I highly recommend reviewing this PR commit-by-commit.
r? `@jieyouxu`
Change `SIGPIPE` ui from `#[unix_sigpipe = "..."]` to `-Zon-broken-pipe=...`
In the stabilization [attempt](https://github.com/rust-lang/rust/pull/120832) of `#[unix_sigpipe = "sig_dfl"]`, a concern was [raised ](https://github.com/rust-lang/rust/pull/120832#issuecomment-2007394609) related to using a language attribute for the feature: Long term, we want `fn lang_start()` to be definable by any crate, not just libstd. Having a special language attribute in that case becomes awkward.
So as a first step towards the next stabilization attempt, this PR changes the `#[unix_sigpipe = "..."]` attribute to a compiler flag `-Zon-broken-pipe=...` to remove that concern, since now the language is not "contaminated" by this feature.
Another point was [also raised](https://github.com/rust-lang/rust/pull/120832#issuecomment-1987023484), namely that the ui should not leak **how** it does things, but rather what the **end effect** is. The new flag uses the proposed naming. This is of course something that can be iterated on further before stabilization.
Tracking issue: https://github.com/rust-lang/rust/issues/97889
Use a proof tree visitor to refine the `Obligation` for error reporting in new solver
With the magic of `ProofTreeVisitor`, we can close the gap that we have on `ObligationCause`s being not as descriptive in the new trait solver.
r? lcnr
Needs some work and obviously documentation.
Some hir cleanups
It seemed odd to not put `AnonConst` in the arena, compared with the other types that we did put into an arena. This way we can also give it a `Span` without growing a lot of other HIR data structures because of the extra field.
r? compiler
Account for immutably borrowed locals in MIR copy-prop and GVN
For the most part, we consider that immutably borrowed `Freeze` locals still fulfill SSA conditions. As the borrow is immutable, any use of the local will have the value given by the single assignment, and there can be no surprise.
This allows copy-prop to merge a non-borrowed local with a borrowed local. We chose to keep copy-classes heads unborrowed, as those may be easier to optimize in later passes.
This also allows to GVN the value behind an immutable borrow. If a SSA local is borrowed, dereferencing that borrow is equivalent to copying the local's value: re-executing the assignment between the borrow and the dereference would be UB.
r? `@ghost` for perf
Allow fmt to run on rmake.rs test files
As discussed with `@jieyouxu,` `rmake.rs` from the `run-make` testsuite would benefit from being formatted as well.
Only thing needed to be done for it to work: allow support for `!` in our `rustfmt.toml` file parsing.
r? `@onur-ozkan`
Add support for inputing via stdin with run-make-support
This PR adds the facility to set a input bytes that will be passed via the standard input.
This is useful for testing `rustc -` (and soon `rustdoc -`).
In #124611 took the approach of having a dedicated `run` method but it is not very convenient to use and would necessitate many functions, one for success, one for fail, ...
Instead this PR takes a different approach and allows setting the input bytes as if it were a parameter and when calling the (now custom) `output` function, we write the input bytes into stdin. I think this gives us maximum flexibility in the implementation and a simple interface for users.
To test this new logic I ported `tests/run-make/stdin-non-utf8/` to an `rmake.rs` one.
r? `@jieyouxu`
In the stabilization attempt of `#[unix_sigpipe = "sig_dfl"]`, a concern
was raised related to using a language attribute for the feature: Long
term, we want `fn lang_start()` to be definable by any crate, not just
libstd. Having a special language attribute in that case becomes
awkward.
So as a first step towards towards the next stabilization attempt, this
PR changes the `#[unix_sigpipe = "..."]` attribute to a compiler flag
`-Zon-broken-pipe=...` to remove that concern, since now the language
is not "contaminated" by this feature.
Another point was also raised, namely that the ui should not leak
**how** it does things, but rather what the **end effect** is. The new
flag uses the proposed naming. This is of course something that can be
iterated on further before stabilization.
Cleanup: Rid the `rmake` test runners of `extern crate run_make_support;`
`run_make_support` is part of the *extern prelude* of `rmake` test runners rendering `extern crate run_make_support` redundant:
80451a485b/src/tools/compiletest/src/runtest.rs (L3826-L3827)
~~Contains some fmt'ing changes because I've enabled format-on-save in my editor and because we don't run `x fmt` for `rmake` test runners yet (this gets addressed by #124613). I can revert those if you'd like me to.~~ (reverted)
r? jieyouxu or testing-devex(?) or boostrap(?)
Use an explicit x86-64 cpu in tests that are sensitive to it
There are a few tests that depend on some target features **not** being
enabled by default, and usually they are correct with the default x86-64
target CPU. However, in downstream builds we have modified the default
to fit our distros -- `x86-64-v2` in RHEL 9 and `x86-64-v3` in RHEL 10
-- and the latter especially trips tests that expect not to have AVX.
These cases are few enough that we can just set them back explicitly.
Adjust `#[macro_export]`/doctest help suggestion for non_local_defs lint
This PR adjust the help suggestion of the `non_local_definitions` lint when encountering a `#[macro_export]` at top-level doctest.
So instead of a non-sentential help suggestion to move the `macro_rules!` up above the `rustdoc`-generated function. We now suggest users to declare their own function.
Fixes *(partially, needs backport)* #124534
Add a lint against never type fallback affecting unsafe code
~~I'm not very happy with the code quality... `VecGraph` not allowing you to get predecessors is very annoying. This should work though, so there is that.~~ (ended up updating `VecGraph` to support getting predecessors)
~~First few commits are from https://github.com/rust-lang/rust/pull/123934https://github.com/rust-lang/rust/pull/123980~~
Rewrite select (in the new solver) to use a `ProofTreeVisitor`
We can use a proof tree visitor rather than collecting and recomputing all the nested goals ourselves.
Based on #124415
There are a few tests that depend on some target features **not** being
enabled by default, and usually they are correct with the default x86-64
target CPU. However, in downstream builds we have modified the default
to fit our distros -- `x86-64-v2` in RHEL 9 and `x86-64-v3` in RHEL 10
-- and the latter especially trips tests that expect not to have AVX.
These cases are few enough that we can just set them back explicitly.
Cleanup: Replace item names referencing GitHub issues or error codes with something more meaningful
**lcnr** in https://github.com/rust-lang/rust/pull/117164#pullrequestreview-1969935387:
> […] while I know that there's precendent to name things `Issue69420`, I really dislike this as it requires looking up the issue to figure out the purpose of such a variant. Actually referring to the underlying issue, e.g. `AliasMayNormToUncovered` or whatever and then linking to the issue in a doc comment feels a lot more desirable to me. We should ideally rename all the functions and enums which currently use issue numbers.
I've grepped through `compiler/` like crazy and think that I've found all instances of this pattern.
However, I haven't renamed `compute_2229_migrations_*`. Should I?
The first commit introduces an abhorrent and super long name for an item because naming is hard but also scary looking / unwelcoming names are good for things related to temporary-ish backcompat hacks. I'll let you discover it by yourself.
Contains a bit of drive-by cleanup and a diag migration bc that was the simplest option.
r? lcnr or compiler
Lazily normalize inside trait ref during orphan check & consider ty params in rigid alias types to be uncovered
Fixes#99554, fixesrust-lang/types-team#104.
Fixes#114061.
Supersedes #100555.
Tracking issue for the future compatibility lint: #124559.
r? lcnr
Add test for issue 106269
Closes#106269
Made this an assembly test as the LLVM codegen is still quite verbose and doesn't really indicate the behaviour we want
Port repr128-dwarf run-make test to rmake
This PR ports the repr128-dwarf run-make test to rmake, using the `gimli` crate instead of the `llvm-dwarfdump` command.
Note that this PR changes `rmake.rs` files to be compiled with the 2021 edition (previously no edition was passed to `rustc`, meaning they were compiled with the 2015 edition). This means that `panic!("{variable}")` will now work as expected in `rmake.rs` files (there's already a usage in the [wasm-symbols-not-exported test](aca749eefc/tests/run-make/wasm-symbols-not-exported/rmake.rs (L34)) that this will fix).
Tracking issue: #121876
and replace it with a simple note suggesting
returning a value.
The type mismatch error was never due to
how many times the loop iterates. It is more
because of the peculiar structure of what the for
loop desugars to. So the note talking about
iteration count didn't make sense
Rollup of 4 pull requests
Successful merges:
- #124519 (adapt a codegen test for llvm 19)
- #124524 (Add StaticForeignItem and use it on ForeignItemKind)
- #124540 (Give proof tree visitors the ability to instantiate nested goals directly)
- #124543 (codegen tests: Tolerate `range()` qualifications in enum tests)
r? `@ghost`
`@rustbot` modify labels: rollup
codegen tests: Tolerate `range()` qualifications in enum tests
Current LLVM can infer range bounds on the i8s involved with these tests, and annotates it. Accept these bounds if present.
`@rustbot` label: +llvm-main
cc `@durin42`
Add StaticForeignItem and use it on ForeignItemKind
This is in preparation for unsafe extern blocks that adds a safe variant for functions inside extern blocks.
r? `@oli-obk`
cc `@compiler-errors`
coverage: Replace boolean options with a `CoverageLevel` enum
After #123409, and some discussion at https://github.com/rust-lang/rust/issues/79649#issuecomment-2042093553 and #124120, it became clear to me that we should have a unified concept of “coverage level”, instead of having several separate boolean flags that aren't actually independent.
This PR therefore introduces a `CoverageLevel` enum, to replace the existing boolean flags for `branch` and `mcdc`.
The `no-branch` value (for `-Zcoverage-options`) has been renamed to `block`, instructing the compiler to only instrument for block coverage, with no branch coverage or MD/DC instrumentation.
`@rustbot` label +A-code-coverage
cc `@ZhuUx` `@Lambdaris` `@RenjiSann`
Add a note to the ArbitraryExpressionInPattern error
The current "arbitrary expressions aren't allowed in patterns" error is confusing, as it fires for code where it *looks* like a pattern but the compiler still treats it as an expression. That this is due to the `:expr` fragment specifier forcing the expression-ness property on the code.
In the test suite, the "arbitrary expressions aren't allowed in patterns" error can only be found in combination with macro_rules macros that force expression-ness of their content, namely via `:expr` metavariables. I also can't come up with cases where there would be an expression instead of a pattern, so I think it's always coming from an `:expr`.
In order to make the error less confusing, this adds a note explaining the weird `:expr` fragment behaviour.
Fixes#99380
[Refactor] Rename `Lint` and `LintGroup`'s `is_loaded` to `is_externally_loaded`
The field being named `is_loaded` was very confusing. Turns out it's true for lints that are registered by external tools like Clippy (I had to look at https://github.com/rust-lang/rust/pull/116412 to know what the variable meant). So I renamed `is_loaded` to `is_externally_loaded` and added some docs.
Mark unions non-const-propagatable in `KnownPanicsLint` without calling layout
Fixes#123710
The ICE occurs during the layout calculation of the union `InvalidTag` in #123710 because the following assert fails:5fe8b697e7/compiler/rustc_abi/src/layout.rs (L289-L292)
The layout calculation is invoked by `KnownPanicsLint` when it is trying to figure out which locals it can const prop. Since `KnownPanicsLint` is never actually going to const props unions thanks to PR https://github.com/rust-lang/rust/pull/121628 there's no point calling layout to check if it can. So in this fix I skip the call to layout and just mark the local non-const propagatable if it is a union.
Fix#124478 - offset_of! returns a temporary
This was due to the must_use() call. Adding HIR's `OffsetOf` to the must_use checking within the compiler avoids this issue while maintaining the lint output.
Fixes#124478. `@tgross35`
MCDC coverage: support nested decision coverage
#123409 provided the initial MCDC coverage implementation.
As referenced in #124144, it does not currently support "nested" decisions, like the following example :
```rust
fn nested_if_in_condition(a: bool, b: bool, c: bool) {
if a && if b || c { true } else { false } {
say("yes");
} else {
say("no");
}
}
```
Note that there is an if-expression (`if b || c ...`) embedded inside a boolean expression in the decision of an outer if-expression.
This PR proposes a workaround for this cases, by introducing a Decision context stack, and by handing several `temporary condition bitmaps` instead of just one.
When instrumenting boolean expressions, if the current node is a leaf condition (i.e. not a `||`/`&&` logical operator nor a `!` not operator), we insert a new decision context, such that if there are more boolean expressions inside the condition, they are handled as separate expressions.
On the codegen LLVM side, we allocate as many `temp_cond_bitmap`s as necessary to handle the maximum encountered decision depth.
Port `print-cfg` run-make test to Rust-based rmake.rs
This PR port the `print-cfg` run-make test to Rust-based rmake.rs tests.
The actual test is now split in two:
- the first part for the `--print=cfg` part
- and the second part for the `=PATH` part of `--print`
Part of #121876.
r? `@jieyouxu`
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 ICE on invalid const param types
Fixes ICE #123863 which occurs because the const param has a type which is not a `bool`, `char` or an integral type.
The ICEing code path begins here in `typeck_with_fallback`: cb3752d20e/compiler/rustc_hir_typeck/src/lib.rs (L167)
The `fallback` invokes the `type_of` query and that eventually ends up calling `ct_infer` from the lowering code over here:
cb3752d20e/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs (L561) and `ct_infer` ICEs at this location: cb3752d20e/compiler/rustc_hir_analysis/src/collect.rs (L392)
To fix the ICE it I'm triggering a `span_delayed_bug` before we hit `ct_infer` if the type of the const param is not one of the supported types
### Edit
On `@lcnr's` suggestion I've changed the approach to not let `ReStatic` region hit the `bug!` in `ct_infer` instead of triggering a `span_delayed_bug`.
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;
| +
```
Start pointing to where bindings were 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 } => {},
| ++++++++
```
Improve diagnostic for unknown `--print` request
This PR improves the diagnostic when encountering a unknown `--print` request.
It also moves the run-make test to a simple UI test.