about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-05 06:13:39 +0900
committerGitHub <noreply@github.com>2021-06-05 06:13:39 +0900
commit5ebc4d3697ee12a1484ebc28d0e18d69834b7154 (patch)
treed85d0d4532ae16e933406e5fcbaa7e80de612de2
parentec9e7d5df1f3cec1889573f9fb470c174cf96dfa (diff)
parentecebb669d5fa442b903a3a17f72cbf2268a5a080 (diff)
downloadrust-5ebc4d3697ee12a1484ebc28d0e18d69834b7154.tar.gz
rust-5ebc4d3697ee12a1484ebc28d0e18d69834b7154.zip
Rollup merge of #85939 - m-ou-se:fix-remove-ref-macro-invocation, r=estebank
Fix suggestion for removing &mut from &mut macro!().

Fixes #85933

Before: (Note the suggestions.)
```
error[E0308]: mismatched types
 --> src/main.rs:2:21
  |
2 |     let _: String = &mut format!("");
  |            ------   ^^^^^^^^^^^^^^^^
  |            |        |
  |            |        expected struct `String`, found `&mut String`
  |            |        help: consider removing the borrow: `mut format!("")`
  |            expected due to this

error[E0308]: mismatched types
 --> src/main.rs:3:21
  |
3 |     let _: String = &mut (format!(""));
  |            ------   ^^^^^^^^^^^^^^^^^^
  |            |        |
  |            |        expected struct `String`, found `&mut String`
  |            |        help: consider removing the borrow: `mut (format!(""))`
  |            expected due to this
```

After:
```
error[E0308]: mismatched types
 --> src/main.rs:2:21
  |
2 |     let _: String = &mut format!("");
  |            ------   ^^^^^^^^^^^^^^^^
  |            |        |
  |            |        expected struct `String`, found `&mut String`
  |            |        help: consider removing the borrow: `format!("")`
  |            expected due to this

error[E0308]: mismatched types
 --> src/main.rs:3:21
  |
3 |     let _: String = &mut (format!(""));
  |            ------   ^^^^^^^^^^^^^^^^^^
  |            |        |
  |            |        expected struct `String`, found `&mut String`
  |            |        help: consider removing the borrow: `format!("")`
  |            expected due to this
```
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs14
-rw-r--r--src/test/ui/suggestions/format-borrow.rs4
-rw-r--r--src/test/ui/suggestions/format-borrow.stderr22
3 files changed, 36 insertions, 4 deletions
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 9cc435a0dec..33bc25accb3 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -17,6 +17,7 @@ use rustc_span::Span;
 use super::method::probe;
 
 use std::fmt;
+use std::iter;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn emit_coerce_suggestions(
@@ -573,12 +574,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // We have `&T`, check if what was expected was `T`. If so,
                 // we may want to suggest removing a `&`.
                 if sm.is_imported(expr.span) {
-                    if let Ok(src) = sm.span_to_snippet(sp) {
-                        if let Some(src) = src.strip_prefix('&') {
+                    // Go through the spans from which this span was expanded,
+                    // and find the one that's pointing inside `sp`.
+                    //
+                    // E.g. for `&format!("")`, where we want the span to the
+                    // `format!()` invocation instead of its expansion.
+                    if let Some(call_span) =
+                        iter::successors(Some(expr.span), |s| s.parent()).find(|&s| sp.contains(s))
+                    {
+                        if let Ok(code) = sm.span_to_snippet(call_span) {
                             return Some((
                                 sp,
                                 "consider removing the borrow",
-                                src.to_string(),
+                                code,
                                 Applicability::MachineApplicable,
                             ));
                         }
diff --git a/src/test/ui/suggestions/format-borrow.rs b/src/test/ui/suggestions/format-borrow.rs
index 63930e7f787..599a79fc08a 100644
--- a/src/test/ui/suggestions/format-borrow.rs
+++ b/src/test/ui/suggestions/format-borrow.rs
@@ -3,4 +3,8 @@ fn main() {
     //~^ ERROR mismatched types
     let b: String = &format!("b");
     //~^ ERROR mismatched types
+    let c: String = &mut format!("c");
+    //~^ ERROR mismatched types
+    let d: String = &mut (format!("d"));
+    //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr
index 05d8fcd3ed6..0881b024712 100644
--- a/src/test/ui/suggestions/format-borrow.stderr
+++ b/src/test/ui/suggestions/format-borrow.stderr
@@ -18,6 +18,26 @@ LL |     let b: String = &format!("b");
    |            |        help: consider removing the borrow: `format!("b")`
    |            expected due to this
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/format-borrow.rs:6:21
+   |
+LL |     let c: String = &mut format!("c");
+   |            ------   ^^^^^^^^^^^^^^^^^
+   |            |        |
+   |            |        expected struct `String`, found `&mut String`
+   |            |        help: consider removing the borrow: `format!("c")`
+   |            expected due to this
+
+error[E0308]: mismatched types
+  --> $DIR/format-borrow.rs:8:21
+   |
+LL |     let d: String = &mut (format!("d"));
+   |            ------   ^^^^^^^^^^^^^^^^^^^
+   |            |        |
+   |            |        expected struct `String`, found `&mut String`
+   |            |        help: consider removing the borrow: `format!("d")`
+   |            expected due to this
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.