Skip to content

Commit 096fbbb

Browse files
committed
Account for bindings with types and in crate macros
1 parent 70c88e5 commit 096fbbb

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed

src/librustc_typeck/check/method/suggest.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ use util::nodemap::FxHashSet;
2525
use syntax::ast;
2626
use syntax::util::lev_distance::find_best_match_for_name;
2727
use errors::DiagnosticBuilder;
28-
use syntax_pos::Span;
28+
use syntax_pos::{Span, FileName};
29+
2930

3031
use rustc::hir::def_id::LOCAL_CRATE;
3132
use rustc::hir;
@@ -263,6 +264,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
263264
let span = tcx.hir.span(node_id);
264265
let snippet = tcx.sess.codemap().span_to_snippet(span)
265266
.unwrap();
267+
let filename = tcx.sess.codemap().span_to_filename(span);
268+
let is_real_filename = match filename {
269+
FileName::Real(_) => true,
270+
_ => false,
271+
};
266272

267273
let parent_node = self.tcx.hir.get(
268274
self.tcx.hir.get_parent_node(node_id),
@@ -271,13 +277,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
271277
"you must specify a type for this binding, like `{}`",
272278
concrete_type,
273279
);
274-
match parent_node {
275-
hir_map::NodeLocal(hir::Local {
280+
281+
match (is_real_filename, parent_node) {
282+
(true, hir_map::NodeLocal(hir::Local {
276283
source: hir::LocalSource::Normal,
284+
ty,
277285
..
278-
}) => {
286+
})) => {
279287
err.span_suggestion(
280-
span,
288+
// account for `let x: _ = 42;`
289+
// ^^^^
290+
span.to(ty.as_ref().map(|ty| ty.span)
291+
.unwrap_or(span)),
281292
&msg,
282293
format!("{}: {}", snippet, concrete_type),
283294
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[macro_export]
12+
macro_rules! mac {
13+
($ident:ident) => { let $ident = 42; }
14+
}

src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs

+20
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,35 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// aux-build:macro-in-other-crate.rs
12+
13+
#[macro_use] extern crate macro_in_other_crate;
14+
15+
macro_rules! local_mac {
16+
($ident:ident) => { let $ident = 42; }
17+
}
18+
1119
fn main() {
1220
let x = 2.0.neg();
1321
//~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
22+
1423
let y = 2.0;
1524
let x = y.neg();
1625
//~^ ERROR can't call method `neg` on ambiguous numeric type `{float}`
1726
println!("{:?}", x);
27+
1828
for i in 0..100 {
1929
println!("{}", i.pow(2));
2030
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
2131
}
32+
33+
local_mac!(local_bar);
34+
local_bar.pow(2);
35+
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
36+
}
37+
38+
fn qux() {
39+
mac!(bar);
40+
bar.pow(2);
41+
//~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}`
2242
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
2-
--> $DIR/method-on-ambiguous-numeric-type.rs:12:17
2+
--> $DIR/method-on-ambiguous-numeric-type.rs:20:17
33
|
44
LL | let x = 2.0.neg();
55
| ^^^
@@ -9,7 +9,7 @@ LL | let x = 2.0_f32.neg();
99
| ^^^^^^^
1010

1111
error[E0689]: can't call method `neg` on ambiguous numeric type `{float}`
12-
--> $DIR/method-on-ambiguous-numeric-type.rs:15:15
12+
--> $DIR/method-on-ambiguous-numeric-type.rs:24:15
1313
|
1414
LL | let x = y.neg();
1515
| ^^^
@@ -19,13 +19,33 @@ LL | let y: f32 = 2.0;
1919
| ^^^^^^
2020

2121
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
22-
--> $DIR/method-on-ambiguous-numeric-type.rs:19:26
22+
--> $DIR/method-on-ambiguous-numeric-type.rs:29:26
2323
|
2424
LL | for i in 0..100 {
2525
| - you must specify a type for this binding, like `i32`
2626
LL | println!("{}", i.pow(2));
2727
| ^^^
2828

29-
error: aborting due to 3 previous errors
29+
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
30+
--> $DIR/method-on-ambiguous-numeric-type.rs:34:15
31+
|
32+
LL | local_bar.pow(2);
33+
| ^^^
34+
help: you must specify a type for this binding, like `i32`
35+
|
36+
LL | ($ident:ident) => { let $ident: i32 = 42; }
37+
| ^^^^^^^^^^^
38+
39+
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
40+
--> $DIR/method-on-ambiguous-numeric-type.rs:40:9
41+
|
42+
LL | mac!(bar);
43+
| ---------- you must specify a type for this binding, like `i32`
44+
LL | bar.pow(2);
45+
| ^^^
46+
|
47+
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
48+
49+
error: aborting due to 5 previous errors
3050

3151
For more information about this error, try `rustc --explain E0689`.

0 commit comments

Comments
 (0)