From 70c88e500c6085cd2f79e4889856254aa335842c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 20 Jun 2018 16:55:52 -0700 Subject: [PATCH 1/3] Don't suggest incorrect syntax --- src/librustc_typeck/check/method/suggest.rs | 31 ++++++++++++++----- .../method-on-ambiguous-numeric-type.rs | 4 +++ .../method-on-ambiguous-numeric-type.stderr | 10 +++++- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 90680b4156e..59439d80bac 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -187,7 +187,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { out_of_scope_traits, lev_candidate, mode, - .. }) => { let tcx = self.tcx; @@ -264,13 +263,29 @@ 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 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 parent_node { + hir_map::NodeLocal(hir::Local { + source: hir::LocalSource::Normal, + .. + }) => { + err.span_suggestion( + span, + &msg, + format!("{}: {}", snippet, concrete_type), + ); + } + _ => { + err.span_label(span, msg); + } + } } } } 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..42cfdb22c37 100644 --- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs +++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs @@ -15,4 +15,8 @@ fn main() { 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}` + } } 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..417d7e8481d 100644 --- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr +++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr @@ -18,6 +18,14 @@ 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:19:26 + | +LL | for i in 0..100 { + | - you must specify a type for this binding, like `i32` +LL | println!("{}", i.pow(2)); + | ^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0689`. From 096fbbbe44d4c8886424e86d3e4aa4d9b999463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 21 Jun 2018 12:10:53 -0700 Subject: [PATCH 2/3] Account for bindings with types and in crate macros --- src/librustc_typeck/check/method/suggest.rs | 21 ++++++++++---- .../auxiliary/macro-in-other-crate.rs | 14 ++++++++++ .../method-on-ambiguous-numeric-type.rs | 20 +++++++++++++ .../method-on-ambiguous-numeric-type.stderr | 28 ++++++++++++++++--- 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/suggestions/auxiliary/macro-in-other-crate.rs diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 59439d80bac..92a96a997bb 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; @@ -263,6 +264,11 @@ 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(); + let filename = tcx.sess.codemap().span_to_filename(span); + let is_real_filename = match filename { + FileName::Real(_) => true, + _ => false, + }; let parent_node = self.tcx.hir.get( self.tcx.hir.get_parent_node(node_id), @@ -271,13 +277,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "you must specify a type for this binding, like `{}`", concrete_type, ); - match parent_node { - hir_map::NodeLocal(hir::Local { + + match (is_real_filename, parent_node) { + (true, hir_map::NodeLocal(hir::Local { source: hir::LocalSource::Normal, + ty, .. - }) => { + })) => { err.span_suggestion( - span, + // account for `let x: _ = 42;` + // ^^^^ + span.to(ty.as_ref().map(|ty| ty.span) + .unwrap_or(span)), &msg, format!("{}: {}", snippet, concrete_type), ); 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 or the MIT license +// , 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 42cfdb22c37..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,15 +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 417d7e8481d..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(); | ^^^ @@ -19,13 +19,33 @@ LL | let y: f32 = 2.0; | ^^^^^^ error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}` - --> $DIR/method-on-ambiguous-numeric-type.rs:19:26 + --> $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: aborting due to 3 previous errors +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`. From cc0ab820912f24770f13985a6bc6474e547acf6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 21 Jun 2018 15:52:48 -0700 Subject: [PATCH 3/3] review comment --- src/librustc_typeck/check/method/suggest.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 92a96a997bb..546ce34fe12 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -265,10 +265,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let snippet = tcx.sess.codemap().span_to_snippet(span) .unwrap(); let filename = tcx.sess.codemap().span_to_filename(span); - let is_real_filename = match filename { - FileName::Real(_) => true, - _ => false, - }; let parent_node = self.tcx.hir.get( self.tcx.hir.get_parent_node(node_id), @@ -278,8 +274,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { concrete_type, ); - match (is_real_filename, parent_node) { - (true, hir_map::NodeLocal(hir::Local { + match (filename, parent_node) { + (FileName::Real(_), hir_map::NodeLocal(hir::Local { source: hir::LocalSource::Normal, ty, ..