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] 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 59439d80bac4..92a96a997bba 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 000000000000..01282f2ad24b --- /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 42cfdb22c372..2b6e830ec596 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 417d7e8481d0..796520e0ec71 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`.