about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-06-03 01:00:54 -0400
committerGitHub <noreply@github.com>2017-06-03 01:00:54 -0400
commitbef8fbd6db4ba1edf3f4cfbcf5dacb62a4b8c933 (patch)
treea78da2ce6d67731e5c5af007c93e99cb92e04108
parent25bbbb31198a60369d00b333162c1406dc13bac3 (diff)
parent4142d7bb890b631bae5d7872dce3e1c1a6816e9f (diff)
downloadrust-bef8fbd6db4ba1edf3f4cfbcf5dacb62a4b8c933.tar.gz
rust-bef8fbd6db4ba1edf3f4cfbcf5dacb62a4b8c933.zip
Rollup merge of #42368 - estebank:call-site, r=nikomatsakis
Use callsite's span for macro calls on suggestion

When suggesting an appropriate mutability for a macro call, use the call
span instead of the expanded macro's span.

```
error[E0308]: mismatched types
  --> $DIR/coerce-suggestions.rs:48:9
   |
48 |     s = format!("foo");
   |         ^^^^^^^^^^^^^^ expected mutable reference, found struct `std::string::String`
   |
   = note: expected type `&mut std::string::String`
              found type `std::string::String`
   = help: try with `&mut format!("foo")`
   = note: this error originates in a macro outside of the current crate
```
Fix #41858.
-rw-r--r--src/librustc_errors/emitter.rs8
-rw-r--r--src/librustc_errors/lib.rs1
-rw-r--r--src/librustc_typeck/check/demand.rs6
-rw-r--r--src/libsyntax/codemap.rs9
-rw-r--r--src/test/ui/span/coerce-suggestions.rs8
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr11
6 files changed, 36 insertions, 7 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index a9645f9ab7b..f820ea4c5e1 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -705,11 +705,9 @@ impl EmitterWriter {
                 if *sp == DUMMY_SP {
                     continue;
                 }
-                if cm.span_to_filename(sp.clone()).contains("macros>") {
-                    let v = sp.macro_backtrace();
-                    if let Some(use_site) = v.last() {
-                        before_after.push((sp.clone(), use_site.call_site.clone()));
-                    }
+                let call_sp = cm.call_span_if_macro(*sp);
+                if call_sp != *sp {
+                    before_after.push((sp.clone(), call_sp));
                 }
                 for trace in sp.macro_backtrace().iter().rev() {
                     // Only show macro locations that are local
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index d1aaaf4ba7b..8d5e9e776ed 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -102,6 +102,7 @@ pub trait CodeMapper {
     fn span_to_string(&self, sp: Span) -> String;
     fn span_to_filename(&self, sp: Span) -> FileName;
     fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span>;
+    fn call_span_if_macro(&self, sp: Span) -> Span;
 }
 
 impl CodeSuggestion {
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 40d53b5e979..9ed50dd1e4d 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -18,7 +18,7 @@ use syntax_pos::{self, Span};
 use rustc::hir;
 use rustc::hir::def::Def;
 use rustc::ty::{self, Ty, AssociatedItem};
-use errors::DiagnosticBuilder;
+use errors::{DiagnosticBuilder, CodeMapper};
 
 use super::method::probe;
 
@@ -187,7 +187,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                        checked_ty),
                 };
                 if self.can_coerce(ref_ty, expected) {
-                    if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
+                    // Use the callsite's span if this is a macro call. #41858
+                    let sp = self.sess().codemap().call_span_if_macro(expr.span);
+                    if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) {
                         return Some(format!("try with `{}{}`",
                                             match mutability.mutbl {
                                                 hir::Mutability::MutMutable => "&mut ",
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index bbe5bd4a10c..830a457df74 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -563,6 +563,15 @@ impl CodeMapper for CodeMap {
     fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
         self.merge_spans(sp_lhs, sp_rhs)
     }
+    fn call_span_if_macro(&self, sp: Span) -> Span {
+        if self.span_to_filename(sp.clone()).contains("macros>") {
+            let v = sp.macro_backtrace();
+            if let Some(use_site) = v.last() {
+                return use_site.call_site;
+            }
+        }
+        sp
+    }
 }
 
 #[derive(Clone)]
diff --git a/src/test/ui/span/coerce-suggestions.rs b/src/test/ui/span/coerce-suggestions.rs
index bc3122bf71c..32d80069f00 100644
--- a/src/test/ui/span/coerce-suggestions.rs
+++ b/src/test/ui/span/coerce-suggestions.rs
@@ -43,4 +43,12 @@ fn main() {
     //~| NOTE cyclic type of infinite size
     //~| NOTE expected type `_`
     //~| NOTE found type `Box<_>`
+
+    let s = &mut String::new();
+    s = format!("foo");
+    //~^ ERROR E0308
+    //~| NOTE expected mutable reference, found struct `std::string::String`
+    //~| NOTE expected type `&mut std::string::String`
+    //~| HELP try with `&mut format!("foo")`
+    //~| NOTE this error originates in a macro outside of the current crate
 }
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 47ede6f2eb1..e3bc64a2cfd 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -47,5 +47,16 @@ error[E0308]: mismatched types
    = note: expected type `_`
               found type `std::boxed::Box<_>`
 
+error[E0308]: mismatched types
+  --> $DIR/coerce-suggestions.rs:48:9
+   |
+48 |     s = format!("foo");
+   |         ^^^^^^^^^^^^^^ expected mutable reference, found struct `std::string::String`
+   |
+   = note: expected type `&mut std::string::String`
+              found type `std::string::String`
+   = help: try with `&mut format!("foo")`
+   = note: this error originates in a macro outside of the current crate
+
 error: aborting due to previous error(s)