Commit graph

315 commits

Author SHA1 Message Date
Matthias Krüger
7850fc4b13
Rollup merge of #149101 - reddevilmidzy:mutable, r=eholk
Improve mutable-binding suggestion to include name

resolve: rust-lang/rust#148467
2025-12-05 16:17:07 +01:00
reddevilmidzy
d49075f083 Suppress ref mut suggestion for for-loop bindings 2025-12-04 15:13:40 +09:00
reddevilmidzy
f30eced2e3 Wrap binding name in parentheses in for-loop mut suggestion 2025-12-04 15:07:33 +09:00
xonx4l
4b000cfacd Merge E0412 into E0425 2025-12-02 18:25:13 +00:00
Aditya-PS-05
2b4b02e613 change test location 2025-11-28 18:52:18 +05:30
Stuart Cook
6197b5be4c
Rollup merge of #149107 - Enselic:option-inspect-mutation, r=jieyouxu
rustc_borrowck: Don't suggest changing closure param type not under user control

This changes output of a handful of tests more than the one added in the first commit, but as far as I can tell, all removed suggestions were invalid.

Closes rust-lang/rust#128381 which is **D-invalid-suggestion** with two 👍-votes.
2025-11-28 15:30:43 +11:00
Christian Poveda
7ae2823bc6
Gate 2018 UI tests 2025-11-27 14:13:58 -05:00
Christian Poveda
b2ab7cf980
Gate 2015 UI tests 2025-11-27 11:19:00 -05:00
Martin Nordholts
f186e53db9 rustc_borrowck: Don't suggest changing closure param type not under user control
All removed suggestions in tests were invalid.
2025-11-27 06:59:07 +01:00
Martin Nordholts
6004968e4a tests: Check stderr when trying to mutate inside Option::inspect() 2025-11-27 06:08:26 +01:00
reddevilmidzy
941a17a15a Relocate 5 tests from tests/ui/issues
Relocate issues/issue-51154.rs to closures/box-generic-closure.rs

Relocate issues/issue-51515.rs to
borrowck/assignment-to-immutable-ref.rs

Relocate issues/issue-53348.rs to mismatched_types/deref-string-assign.rs

Relocate issues/issue-52717.rs to
pattern/match-enum-struct-variant-field-missing.rs

Relocate issues/issue-53300.rs to
type/cannot-find-wrapper-with-impl-trait.rs
2025-11-27 00:39:52 +09:00
bors
d6deffe2de Auto merge of #148552 - chenyukang:yukang-fix-148392-closure-diag, r=petrochenkov
Provide more general note for borrowing outside of closure

Fixes rust-lang/rust#148392
2025-11-12 14:32:06 +00:00
Stuart Cook
b98d127133
Rollup merge of #147974 - JohnTitor:diag-detect-buf-reuse-pattern, r=estebank
Improve diagnostics for buffer reuse with borrowed references

Addresses rust-lang/rust#147694

I'm not sure the current note wording is the best so I appreciate any feedback.
2025-11-12 12:26:36 +11:00
Esteban Küber
71b0755a98 Provide more context when mutably borrowing an imutable borrow
Point at statics and consts being mutable borrowed or written to:

```
error[E0594]: cannot assign to immutable static item `NUM`
  --> $DIR/E0594.rs:4:5
   |
LL | static NUM: i32 = 18;
   | --------------- this `static` cannot be written to
...
LL |     NUM = 20;
   |     ^^^^^^^^ cannot assign
```

Point at the expression that couldn't be mutably borrowed from a pattern:

```
error[E0596]: cannot borrow data in a `&` reference as mutable
  --> $DIR/mut-pattern-of-immutable-borrow.rs:19:14
   |
LL |     match &arg.field {
   |           ---------- this cannot be borrowed as mutable
LL |         Some(ref mut s) => s.push('a'),
   |              ^^^^^^^^^ cannot borrow as mutable
```
2025-11-09 22:14:48 +00:00
yukang
883b2dc420 Provide more general note for borrowing outside of closure 2025-11-06 12:14:47 +08:00
Stuart Cook
ea4e037dd7
Rollup merge of #133149 - estebank:niko-rustnation, r=wesleywiser
Provide more context on `Fn` closure modifying binding

When modifying a binding from inside of an `Fn` closure, point at the binding definition and suggest using an `std::sync` type that would allow the code to compile.

```
error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure
 --> f703.rs:6:9
  |
4 |     let mut counter = 0;
  |         ----------- `counter` declared here, outside the closure
5 |     let x: Box<dyn Fn()> = Box::new(|| {
  |                                     -- in this closure
6 |         counter += 1;
  |         ^^^^^^^^^^^^ cannot assign
  |
  = help: consider using `std::sync::atomic::AtomicI32` instead, which allows for multiple threads to access and modify the value
```

This provides more context on where the binding being modified was declared, and more importantly, guides newcomers towards `std::sync` when encountering cases like these.

When the requirement comes from an argument of a local function, we already tell the user that they might want to change from `Fn` to `FnMut`:

```
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
  --> $DIR/borrow-immutable-upvar-mutation.rs:21:27
   |
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
   |                                              - change this to accept `FnMut` instead of `Fn`
...
LL |         let mut x = 0;
   |             ----- `x` declared here, outside the closure
LL |         let _f = to_fn(|| x = 42);
   |                  ----- -- ^^^^^^ cannot assign
   |                  |     |
   |                  |     in this closure
   |                  expects `Fn` instead of `FnMut`
   |
   = help: consider using `std::sync::atomic::AtomicI32` instead, which allows for multiple threads to access and modify the value
```

We might want to avoid the `help` in this case.

_Inspired by a [part of Niko's keynote at RustNation UK 2024](https://youtu.be/04gTQmLETFI?si=dgJL2OJRtuShkxdD&t=600)._
2025-11-04 13:44:47 +11:00
Esteban Küber
4ab1fc5127 Provide more context on Fn closure modifying binding
When modifying a binding from inside of an `Fn` closure, point at the binding definition and suggest using an `std::sync` type that would allow the code to compile.

```
error[E0594]: cannot assign to `counter`, as it is a captured variable in a `Fn` closure
 --> f703.rs:6:9
  |
4 |     let mut counter = 0;
  |         ----------- `counter` declared here, outside the closure
5 |     let x: Box<dyn Fn()> = Box::new(|| {
  |                                     -- in this closure
6 |         counter += 1;
  |         ^^^^^^^^^^^^ cannot assign
```
2025-11-03 20:26:18 +00:00
Matthias Krüger
549846e857
Rollup merge of #147141 - estebank:issue-81059, r=jackh726
Suggest making binding `mut` on `&mut` reborrow

When a binding needs to be mutably reborrowed multiple times, suggesting removing `&mut` will lead to follow up errors. Instead suggest both making the binding mutable and removing the reborrow.

```
error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable
 --> f14.rs:2:12
  |
2 |     match (&mut outer, 23) {
  |            ^^^^^^^^^^ cannot borrow as mutable
  |
note: the binding is already a mutable borrow
 --> f14.rs:1:16
  |
1 | fn test(outer: &mut Option<i32>) {
  |                ^^^^^^^^^^^^^^^^
help: consider making the binding mutable if you need to reborrow multiple times
  |
1 | fn test(mut outer: &mut Option<i32>) {
  |         +++
help: if there is only one mutable reborrow, remove the `&mut`
  |
2 -     match (&mut outer, 23) {
2 +     match (outer, 23) {
  |
```

Address rust-lang/rust#81059.
2025-11-03 21:20:20 +01:00
Stuart Cook
10e445c9c8
Rollup merge of #144194 - estebank:const-traits, r=davidtwco
Provide additional context to errors involving const traits

When encountering an unmet `Ty: [const] Trait` bound, if `Trait` is `#[const_trait]` and there's an `impl Trait for Ty` point at it. If local, suggest `impl const Trait for Ty`, otherwise just point at it.

```
error[E0277]: the trait bound `NonConstAdd: [const] Add` is not satisfied
  --> $DIR/assoc-type.rs:37:16
   |
LL |     type Bar = NonConstAdd;
   |                ^^^^^^^^^^^
   |
note: required by a bound in `Foo::Bar`
  --> $DIR/assoc-type.rs:33:15
   |
LL |     type Bar: [const] Add;
   |               ^^^^^^^^^^^ required by this bound in `Foo::Bar`
help: make the `impl` of trait `Add` `const`
   |
LL | impl const Add for NonConstAdd {
   |      +++++
```
```
error[E0277]: the trait bound `T: [const] PartialEq` is not satisfied
    --> tests/ui/traits/const-traits/call-generic-method-fail.rs:5:5
     |
5    |     *t == *t
     |     ^^^^^^^^
     |
note: trait `PartialEq` is implemented but not `const`
    --> /home/gh-estebank/rust/library/core/src/ptr/const_ptr.rs:1590:1
     |
1590 | impl<T: PointeeSized> PartialEq for *const T {
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: trait `PartialEq` is implemented but not `const`
    --> /home/gh-estebank/rust/library/core/src/ptr/mut_ptr.rs:2011:1
     |
2011 | impl<T: PointeeSized> PartialEq for *mut T {
     | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
2025-11-03 11:52:39 +11:00
Esteban Küber
a2c3913007 review comments 2025-11-02 20:12:26 +00:00
Esteban Küber
9bc814cc8d Point at the enclosing const context
```
error[E0015]: cannot call non-const associated function `Foo::{constant#0}::Foo::<17>::value` in constants
  --> $DIR/nested-type.rs:15:5
   |
LL |   struct Foo<const N: [u8; {
   |  __________________________-
LL | |     struct Foo<const N: usize>;
LL | |
LL | |     impl<const N: usize> Foo<N> {
...  |
LL | |     Foo::<17>::value()
   | |     ^^^^^^^^^^^^^^^^^^
LL | |
LL | | }]>;
   | |_- calls in constants are limited to constant functions, tuple structs and tuple variants
```
2025-11-02 20:12:26 +00:00
Esteban Küber
a08bdffb21 Point at non-const trait when using them in const context
Point at trait and associated item when that associated item is used in a const context. Suggest making the trait `#[const_trait]`.

```
error[E0015]: cannot call non-const method `<() as Trait>::foo` in constant functions
  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:26:8
   |
LL |     ().foo();
   |        ^^^^^
   |
note: method `foo` is not const because trait `Trait` is not const
  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:13:1
   |
LL | trait Trait {
   | ^^^^^^^^^^^ this trait is not const
LL |     fn foo(self);
   |     ------------- this method is not const
   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: consider making trait `Trait` const
   |
LL + #[const_trait]
LL | trait Trait {
   |
```
2025-11-02 20:12:26 +00:00
Ralf Jung
3796f7de57 compiletest: rename add-core-stubs to add-minicore 2025-11-02 16:20:06 +01:00
Esteban Küber
516a273144 Suggest making binding mut on &mut reborrow
When a binding needs to be mutably reborrowed multiple times, suggesting removing `&mut` will lead to follow up errors. Instead suggest both making the binding mutable and removing the reborrow.

```
error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable
 --> f14.rs:2:12
  |
2 |     match (&mut outer, 23) {
  |            ^^^^^^^^^^ cannot borrow as mutable
  |
note: the binding is already a mutable borrow
 --> f14.rs:1:16
  |
1 | fn test(outer: &mut Option<i32>) {
  |                ^^^^^^^^^^^^^^^^
help: consider making the binding mutable if you need to reborrow multiple times
  |
1 | fn test(mut outer: &mut Option<i32>) {
  |         +++
help: if there is only one mutable reborrow, remove the `&mut`
  |
2 -     match (&mut outer, 23) {
2 +     match (outer, 23) {
  |
```
2025-10-31 19:23:33 +00:00
Yuki Okushi
61b26f9f60 Improve diagnostics for buffer reuse with borrowed references 2025-10-22 21:11:02 +09:00
Matthias Krüger
5559313a14
Rollup merge of #146490 - Oneirical:uncountable-integer-12, r=jieyouxu
Rehome 26 `tests/ui/issues/` tests to other subdirectories under `tests/ui/` [#5 of Batch #2]

Part of rust-lang/rust#133895

Methodology:

1. Refer to the previously written `tests/ui/SUMMARY.md`
2. Find an appropriate category for the test, using the original issue thread and the test contents.
3. Add the issue URL at the bottom (not at the top, as that would mess up stderr line numbers)
4. Rename the tests to make their purpose clearer

Inspired by the methodology that Kivooeo was using.

r? ```@jieyouxu```
2025-10-18 23:54:44 +02:00
bors
ff6dc928c5 Auto merge of #142390 - cjgillot:mir-liveness, r=davidtwco
Perform unused assignment and unused variables lints on MIR.

Rebase of https://github.com/rust-lang/rust/pull/101500

Fixes https://github.com/rust-lang/rust/issues/51003.

The first commit moves detection of uninhabited types from the current liveness pass to MIR building.

In order to keep the same level of diagnostics, I had to instrument MIR a little more:
- keep for which original local a guard local is created;
- store in the `VarBindingForm` the list of introducer places and whether this was a shorthand pattern.

I am not very proud of the handling of self-assignments. The proposed scheme is in two parts: first detect probable self-assignments, by pattern matching on MIR, and second treat them specially during dataflow analysis. I welcome ideas.

Please review carefully the changes in tests. There are many small changes to behaviour, and I'm not sure all of them are desirable.
2025-10-12 13:00:04 +00:00
Oneirical
926599a45c Add test batch 5 2025-10-12 00:33:20 -04:00
Oneirical
6ca69812cd Add test batch 4 2025-10-11 21:59:51 -04:00
Camille GILLOT
ca0379d6cd Diagnose liveness on MIR. 2025-10-11 20:50:21 +00:00
Esteban Küber
4973903cd2 reword note 2025-09-28 20:55:35 +00:00
Esteban Küber
7a0319f01d Point at lifetime requirement origin in more cases 2025-09-28 20:55:34 +00:00
Esteban Küber
c3e0b29e79 Point at fn bound that introduced lifetime obligation
```
error[E0597]: `c` does not live long enough
  --> $DIR/without-precise-captures-we-are-powerless.rs:19:20
   |
LL | fn simple<'a>(x: &'a i32) {
   |           -- lifetime `'a` defined here
...
LL |     let c = async move || { println!("{}", *x); };
   |         - binding `c` declared here
LL |     outlives::<'a>(c());
   |     ---------------^---
   |     |              |
   |     |              borrowed value does not live long enough
   |     argument requires that `c` is borrowed for `'a`
LL |     outlives::<'a>(call_once(c));
LL | }
   | - `c` dropped here while still borrowed
   |
note: requirement that `c` is borrowed for `'a` introduced here
  --> $DIR/without-precise-captures-we-are-powerless.rs:7:33
   |
LL | fn outlives<'a>(_: impl Sized + 'a) {}
   |                                 ^^
```

When encountering a `ConstraintCategory::Predicate` in a funtion call, point at the `Span` for that `Predicate` to explain where the lifetime obligation originates from.
2025-09-28 20:55:34 +00:00
Stuart Cook
c2e8264b34
Rollup merge of #145838 - dianne:non-extending-super-let, r=jackh726,traviscross
don't apply temporary lifetime extension rules to non-extended `super let`

Reference PR: rust-lang/reference#1980

This changes the semantics for `super let` (and macros implemented in terms of it, such as `pin!`, `format_args!`, `write!`, and `println!`) as suggested by ````@theemathas```` in https://github.com/rust-lang/rust/issues/145784#issuecomment-3218658335, making `super let` initializers only count as [extending expressions](https://doc.rust-lang.org/nightly/reference/destructors.html#extending-based-on-expressions) when the `super let` itself is within an extending block. Since `super let` initializers aren't temporary drop scopes, their temporaries outside of inner temporary scopes are effectively always extended, even when not in extending positions; this only affects two cases as far as I can tell:
- Block tail expressions in Rust 2024. This PR makes `f(pin!({ &temp() }))` drop `temp()` at the end of the block in Rust 2024, whereas previously it would live until after the call to `f` because syntactically the `temp()` was in an extending position as a result of `super let` in `pin!`'s expansion.
- `super let` nested within a non-extended `super let` is no longer extended. i.e. a normal `let` is required to treat `super let`s as extending (in which case nested `super let`s will also be extending).

Closes rust-lang/rust#145784

This is a breaking change. Both static and dynamic semantics are affected. The most likely breakage is for programs to stop compiling, but it's technically possible for drop order to silently change as well (as in rust-lang/rust#145784). Since this affects stable macros, it probably would need a crater run.

Nominating for discussion alongside rust-lang/rust#145784: ````@rustbot```` label +I-lang-nominated +I-libs-api-nominated

Tracking issue for `super let`: rust-lang/rust#139076
2025-09-17 14:56:45 +10:00
dianne
0976d6ccac don't extend non-extended super let initializers' block tail temps 2025-09-04 10:14:25 -07:00
Oneirical
2e659f5894 Add test batch 1 2025-08-27 00:23:26 -04:00
dianne
9fd57df639 add tests, some with incorrect lifetime extension behavior 2025-08-25 19:35:26 -07:00
Karol Zwolak
d14b83e378 bless tests with new lint messages 2025-08-19 21:27:10 +02:00
许杰友 Jieyou Xu (Joe)
2d05870897
Rollup merge of #144983 - Oneirical:uncountable-integer, r=jieyouxu
Rehome 37 `tests/ui/issues/` tests to other subdirectories under `tests/ui/`

Part of rust-lang/rust#133895

Methodology:

1. Refer to the previously written `tests/ui/SUMMARY.md`
2. Find an appropriate category for the test, using the original issue thread and the test contents.
3. Add the issue URL at the bottom (not at the top, as that would mess up stderr line numbers)
4. Rename the tests to make their purpose clearer

Inspired by the methodology that ``@Kivooeo`` was using.

r? ``@jieyouxu``
2025-08-19 19:42:06 +08:00
Stuart Cook
f3f1847e40
Rollup merge of #145041 - lcnr:borrowck-limitations-error, r=BoxyUwU
rework GAT borrowck limitation error

The old one depends on the `ConstraintCategory` of the constraint which meant we did not emit this note if we had to prove the higher ranked trait bound due to e.g. normalization.

This made it annoying brittle and caused MIR borrowck errors to be order dependent, fixes the issue in https://github.com/rust-lang/rust/pull/140737#discussion_r2259592651.

r? types cc ```@amandasystems```
2025-08-19 14:18:22 +10:00
Oneirical
75e0263af9 Rehome tests/ui/issues/ tests [5/?] 2025-08-17 13:01:02 -04:00
Deadbeef
4335405fa7 overhaul &mut suggestions in borrowck errors 2025-08-16 22:34:17 +08:00
Jake Goulding
65d329d189 Adjust error message grammar to be less awkward 2025-08-14 12:50:07 -04:00
lcnr
a95a2ac476 rework add_placeholder_from_predicate_note 2025-08-13 14:03:26 +02:00
Esteban Küber
1aa5668d20 Point at the Fn() or FnMut() bound that coerced a closure, which caused a move error
When encountering a move error involving a closure because the captured value isn't `Copy`, and the obligation comes from a bound on a type parameter that requires `Fn` or `FnMut`, we point at it and explain that an `FnOnce` wouldn't cause the move error.

```
error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
  --> f111.rs:15:25
   |
14 | fn do_stuff(foo: Option<Foo>) {
   |             ---  ----------- move occurs because `foo` has type `Option<Foo>`, which does not implement the `Copy` trait
   |             |
   |             captured outer variable
15 |     require_fn_trait(|| async {
   |                      -- ^^^^^ `foo` is moved here
   |                      |
   |                      captured by this `Fn` closure
16 |         if foo.map_or(false, |f| f.foo()) {
   |            --- variable moved due to use in coroutine
   |
help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once
  --> f111.rs:12:53
   |
12 | fn require_fn_trait<F: Future<Output = ()>>(_: impl Fn() -> F) {}
   |                                                     ^^^^^^^^^
help: consider cloning the value if the performance cost is acceptable
   |
16 |         if foo.clone().map_or(false, |f| f.foo()) {
   |               ++++++++
```
2025-08-10 19:22:49 +00:00
Stuart Cook
62b406d4b1
Rollup merge of #144403 - Kivooeo:issue4, r=jieyouxu
`tests/ui/issues/`: The Issues Strike Back [4/N]

Some `tests/ui/issues/` housekeeping, to trim down number of tests directly under `tests/ui/issues/`. Part of https://github.com/rust-lang/rust/issues/133895.

r? ````````@jieyouxu````````
2025-08-10 19:45:48 +10:00
Kivooeo
16765639b3 comments 2025-08-09 16:27:20 +05:00
Jakub Beránek
e89ae47b97
Rollup merge of #144552 - Oneirical:uncountable-integer-3, r=jieyouxu
Rehome 33 `tests/ui/issues/` tests to other subdirectories under `tests/ui/`

rust-lang/rust#143902 divided into smaller, easier to review chunks.

Part of rust-lang/rust#133895

Methodology:

1. Refer to the previously written `tests/ui/SUMMARY.md`
2. Find an appropriate category for the test, using the original issue thread and the test contents.
3. Add the issue URL at the bottom (not at the top, as that would mess up stderr line numbers)
4. Rename the tests to make their purpose clearer

Inspired by the methodology that ``@Kivooeo`` was using.

r? ``@jieyouxu``
2025-08-06 15:55:42 +02:00
Samuel Tardieu
58b00b088e
Rollup merge of #144548 - Oneirical:uncountable-integer-2, r=jieyouxu
Rehome 21 `tests/ui/issues/` tests to other subdirectories under `tests/ui/`

rust-lang/rust#143902 divided into smaller, easier to review chunks.

Part of rust-lang/rust#133895

Methodology:

1. Refer to the previously written `tests/ui/SUMMARY.md`
2. Find an appropriate category for the test, using the original issue thread and the test contents.
3. Add the issue URL at the bottom (not at the top, as that would mess up stderr line numbers)
4. Rename the tests to make their purpose clearer

Inspired by the methodology that ``@Kivooeo`` was using.

r? ``@jieyouxu``
2025-08-05 03:51:33 +02:00
Oneirical
7196d8cd66 Rehome tests/ui/issues/ tests [3/?] 2025-08-04 16:43:53 -04:00