diff options
| author | Corey Farwell <coreyf@rwell.org> | 2017-06-03 01:00:54 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-03 01:00:54 -0400 |
| commit | bef8fbd6db4ba1edf3f4cfbcf5dacb62a4b8c933 (patch) | |
| tree | a78da2ce6d67731e5c5af007c93e99cb92e04108 | |
| parent | 25bbbb31198a60369d00b333162c1406dc13bac3 (diff) | |
| parent | 4142d7bb890b631bae5d7872dce3e1c1a6816e9f (diff) | |
| download | rust-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.rs | 8 | ||||
| -rw-r--r-- | src/librustc_errors/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc_typeck/check/demand.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/span/coerce-suggestions.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/span/coerce-suggestions.stderr | 11 |
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) |
