about summary refs log tree commit diff
path: root/src/librustc_mir
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-29 12:23:15 +0200
committerGitHub <noreply@github.com>2020-04-29 12:23:15 +0200
commitd0ff2295e071a25568bb21f47287e7f76468591a (patch)
treed03d4f09a48ee98451c5d40b89ab00acbf6752c4 /src/librustc_mir
parent92019986aa6532256277ca999006bdc77e9a95ad (diff)
parent2c6094e5d043087e6f7539bd5d484ff3ba4dcf5d (diff)
downloadrust-d0ff2295e071a25568bb21f47287e7f76468591a.tar.gz
rust-d0ff2295e071a25568bb21f47287e7f76468591a.zip
Rollup merge of #71217 - estebank:tail-borrow-sugg, r=pnkfelix
Suggest `;` or assignment to drop borrows in tail exprs

Address the diagnostics part of #70844.

```
error[E0597]: `counter` does not live long enough
  --> $DIR/issue-54556-niconii.rs:22:20
   |
LL |     if let Ok(_) = counter.lock() { }
   |                    ^^^^^^^-------
   |                    |
   |                    borrowed value does not live long enough
   |                    a temporary with access to the borrow is created here ...
...
LL | }
   | -
   | |
   | `counter` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<MutexGuard<'_>, ()>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
LL |     if let Ok(_) = counter.lock() { };
   |                                      ^
```
Diffstat (limited to 'src/librustc_mir')
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
index 7645182ad1f..5253acbba7f 100644
--- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
@@ -156,23 +156,32 @@ impl BorrowExplanation {
                         err.span_label(body.source_info(drop_loc).span, message);
 
                         if let Some(info) = &local_decl.is_block_tail {
-                            // FIXME: use span_suggestion instead, highlighting the
-                            // whole block tail expression.
-                            let msg = if info.tail_result_is_ignored {
-                                "The temporary is part of an expression at the end of a block. \
-                                 Consider adding semicolon after the expression so its temporaries \
-                                 are dropped sooner, before the local variables declared by the \
-                                 block are dropped."
+                            if info.tail_result_is_ignored {
+                                err.span_suggestion_verbose(
+                                    info.span.shrink_to_hi(),
+                                    "consider adding semicolon after the expression so its \
+                                     temporaries are dropped sooner, before the local variables \
+                                     declared by the block are dropped",
+                                    ";".to_string(),
+                                    Applicability::MaybeIncorrect,
+                                );
                             } else {
-                                "The temporary is part of an expression at the end of a block. \
-                                 Consider forcing this temporary to be dropped sooner, before \
-                                 the block's local variables are dropped. \
-                                 For example, you could save the expression's value in a new \
-                                 local variable `x` and then make `x` be the expression \
-                                 at the end of the block."
+                                err.note(
+                                    "the temporary is part of an expression at the end of a \
+                                     block;\nconsider forcing this temporary to be dropped sooner, \
+                                     before the block's local variables are dropped",
+                                );
+                                err.multipart_suggestion(
+                                    "for example, you could save the expression's value in a new \
+                                     local variable `x` and then make `x` be the expression at the \
+                                     end of the block",
+                                    vec![
+                                        (info.span.shrink_to_lo(), "let x = ".to_string()),
+                                        (info.span.shrink_to_hi(), "; x".to_string()),
+                                    ],
+                                    Applicability::MaybeIncorrect,
+                                );
                             };
-
-                            err.note(msg);
                         }
                     }
                 }