about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-22 17:51:02 +0000
committerbors <bors@rust-lang.org>2018-06-22 17:51:02 +0000
commit8f024479d4e702647e7a772e06f77391abcfa571 (patch)
treea1a59791cfa56f9a12223883c8c3d10eab1371b5
parent4dc2d745b9103dc4493b49277337ef4580425d7c (diff)
parentcc0ab820912f24770f13985a6bc6474e547acf6e (diff)
downloadrust-8f024479d4e702647e7a772e06f77391abcfa571.tar.gz
rust-8f024479d4e702647e7a772e06f77391abcfa571.zip
Auto merge of #51670 - estebank:issue-51634, r=oli-obk
Don't suggest incorrect syntax

Fix #51634.
-rw-r--r--src/librustc_typeck/check/method/suggest.rs40
-rw-r--r--src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs14
-rw-r--r--src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs24
-rw-r--r--src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr34
4 files changed, 100 insertions, 12 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 90680b4156e..546ce34fe12 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -25,7 +25,8 @@ use util::nodemap::FxHashSet;
 use syntax::ast;
 use syntax::util::lev_distance::find_best_match_for_name;
 use errors::DiagnosticBuilder;
-use syntax_pos::Span;
+use syntax_pos::{Span, FileName};
+
 
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::hir;
@@ -187,7 +188,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 out_of_scope_traits,
                 lev_candidate,
                 mode,
-                ..
             }) => {
                 let tcx = self.tcx;
 
@@ -264,13 +264,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         let span = tcx.hir.span(node_id);
                                         let snippet = tcx.sess.codemap().span_to_snippet(span)
                                             .unwrap();
-                                        err.span_suggestion(span,
-                                                            &format!("you must specify a type for \
-                                                                      this binding, like `{}`",
-                                                                     concrete_type),
-                                                            format!("{}: {}",
-                                                                    snippet,
-                                                                    concrete_type));
+                                        let filename = tcx.sess.codemap().span_to_filename(span);
+
+                                        let parent_node = self.tcx.hir.get(
+                                            self.tcx.hir.get_parent_node(node_id),
+                                        );
+                                        let msg = format!(
+                                            "you must specify a type for this binding, like `{}`",
+                                            concrete_type,
+                                        );
+
+                                        match (filename, parent_node) {
+                                            (FileName::Real(_), hir_map::NodeLocal(hir::Local {
+                                                source: hir::LocalSource::Normal,
+                                                ty,
+                                                ..
+                                            })) => {
+                                                err.span_suggestion(
+                                                    // account for `let x: _ = 42;`
+                                                    //                  ^^^^
+                                                    span.to(ty.as_ref().map(|ty| ty.span)
+                                                        .unwrap_or(span)),
+                                                    &msg,
+                                                    format!("{}: {}", snippet, concrete_type),
+                                                );
+                                            }
+                                            _ => {
+                                                err.span_label(span, msg);
+                                            }
+                                        }
                                     }
                                 }
                             }
diff --git a/src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs b/src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs
new file mode 100644
index 00000000000..01282f2ad24
--- /dev/null
+++ b/src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs
@@ -0,0 +1,14 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_export]
+macro_rules! mac {
+    ($ident:ident) => { let $ident = 42; }
+}
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
index 9bf74c3875f..2b6e830ec59 100644
--- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
+++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
@@ -8,11 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// aux-build:macro-in-other-crate.rs
+
+#[macro_use] extern crate macro_in_other_crate;
+
+macro_rules! local_mac {
+    ($ident:ident) => { let $ident = 42; }
+}
+
 fn main() {
     let x = 2.0.neg();
     //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
+
     let y = 2.0;
     let x = y.neg();
     //~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
     println!("{:?}", x);
+
+    for i in 0..100 {
+        println!("{}", i.pow(2));
+        //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
+    }
+
+    local_mac!(local_bar);
+    local_bar.pow(2);
+    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
+}
+
+fn qux() {
+    mac!(bar);
+    bar.pow(2);
+    //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
 }
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
index 68c8be7dff8..796520e0ec7 100644
--- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
+++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
@@ -1,5 +1,5 @@
 error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
-  --> $DIR/method-on-ambiguous-numeric-type.rs:12:17
+  --> $DIR/method-on-ambiguous-numeric-type.rs:20:17
    |
 LL |     let x = 2.0.neg();
    |                 ^^^
@@ -9,7 +9,7 @@ LL |     let x = 2.0_f32.neg();
    |             ^^^^^^^
 
 error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
-  --> $DIR/method-on-ambiguous-numeric-type.rs:15:15
+  --> $DIR/method-on-ambiguous-numeric-type.rs:24:15
    |
 LL |     let x = y.neg();
    |               ^^^
@@ -18,6 +18,34 @@ help: you must specify a type for this binding, like `f32`
 LL |     let y: f32 = 2.0;
    |         ^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:29:26
+   |
+LL |     for i in 0..100 {
+   |         - you must specify a type for this binding, like `i32`
+LL |         println!("{}", i.pow(2));
+   |                          ^^^
+
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:34:15
+   |
+LL |     local_bar.pow(2);
+   |               ^^^
+help: you must specify a type for this binding, like `i32`
+   |
+LL |     ($ident:ident) => { let $ident: i32 = 42; }
+   |                             ^^^^^^^^^^^
+
+error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
+  --> $DIR/method-on-ambiguous-numeric-type.rs:40:9
+   |
+LL |     mac!(bar);
+   |     ---------- you must specify a type for this binding, like `i32`
+LL |     bar.pow(2);
+   |         ^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0689`.