Skip to content

Commit f7aed3e

Browse files
committed
Do not use casting for suggestion to add type to numeric literal
1 parent 87242f3 commit f7aed3e

File tree

7 files changed

+59
-22
lines changed

7 files changed

+59
-22
lines changed

src/librustc/hir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ pub struct LifetimeDef {
241241
}
242242

243243
/// A "Path" is essentially Rust's notion of a name; for instance:
244-
/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
244+
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
245245
/// along with a bunch of supporting information.
246246
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
247247
pub struct Path {

src/librustc_typeck/check/method/suggest.rs

+33-10
Original file line numberDiff line numberDiff line change
@@ -215,20 +215,43 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
215215
item_name,
216216
ty_string
217217
);
218-
let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
219-
.unwrap_or("4".to_string());
220218
let concrete_type = if actual.is_integral() {
221-
"u32"
219+
"i32"
222220
} else {
223221
"f32"
224222
};
225-
err.span_suggestion(expr.span,
226-
&format!("you must specify a concrete type for \
227-
this numeric value, like `{}`",
228-
concrete_type),
229-
format!("({} as {})",
230-
snippet,
231-
concrete_type));
223+
match expr.node {
224+
hir::ExprLit(_) => { // numeric literal
225+
let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
226+
.unwrap_or("<numeric literal>".to_string());
227+
// FIXME: use the literal for missing snippet
228+
229+
err.span_suggestion(expr.span,
230+
&format!("you must specify a concrete type for \
231+
this numeric value, like `{}`",
232+
concrete_type),
233+
format!("{}_{}",
234+
snippet,
235+
concrete_type));
236+
}
237+
hir::ExprPath(ref qpath) => { // local binding
238+
if let &hir::QPath::Resolved(_, ref path) = &qpath {
239+
if let hir::def::Def::Local(node_id) = path.def {
240+
let span = tcx.hir.span(node_id);
241+
let snippet = tcx.sess.codemap().span_to_snippet(span)
242+
.unwrap();
243+
err.span_suggestion(span,
244+
&format!("you must specify a type for \
245+
this binding, like `{}`",
246+
concrete_type),
247+
format!("{}: {}",
248+
snippet,
249+
concrete_type));
250+
}
251+
}
252+
}
253+
_ => {}
254+
}
232255
err.emit();
233256
return;
234257
} else {

src/librustc_typeck/diagnostics.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4661,9 +4661,10 @@ x.powi(2); // same error as above
46614661
Because of this, you must give the numeric literal or binding a type:
46624662
46634663
```
4664-
let _ = (2.0 as f32).powi(2);
4664+
let _ = 2.0_f32.powi(2);
46654665
let x: f32 = 2.0;
46664666
let _ = x.powi(2);
4667+
let _ = (2.0 as f32).powi(2);
46674668
```
46684669
"##,
46694670
}

src/test/ui/issue-41652/issue_41652.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
33
|
44
19 | 3.f()
55
| ^
6-
help: you must specify a concrete type for this numeric value, like `u32`
6+
help: you must specify a concrete type for this numeric value, like `i32`
77
|
8-
19 | (3 as u32).f()
9-
| ^^^^^^^^^^
8+
19 | 3_i32.f()
9+
| ^^^^^
1010

1111
error: aborting due to previous error
1212

src/test/ui/macros/macro-backtrace-invalid-internals.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
3535
| -------------------- in this macro invocation
3636
help: you must specify a concrete type for this numeric value, like `f32`
3737
|
38-
51 | (2.0 as f32).powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
39-
| ^^^^^^^^^^^^
38+
51 | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
39+
| ^^^^^^^
4040

4141
error[E0599]: no method named `fake` found for type `{integer}` in the current scope
4242
--> $DIR/macro-backtrace-invalid-internals.rs:33:13
@@ -75,8 +75,8 @@ error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
7575
| ------------------- in this macro invocation
7676
help: you must specify a concrete type for this numeric value, like `f32`
7777
|
78-
57 | (2.0 as f32).powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
79-
| ^^^^^^^^^^^^
78+
57 | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
79+
| ^^^^^^^
8080

8181
error: aborting due to 8 previous errors
8282

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

+3
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
fn main() {
1212
let x = 2.0.powi(2);
1313
//~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
14+
let y = 2.0;
15+
let x = y.powi(2);
16+
//~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
1417
println!("{:?}", x);
1518
}

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

+13-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@ error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
55
| ^^^^
66
help: you must specify a concrete type for this numeric value, like `f32`
77
|
8-
12 | let x = (2.0 as f32).powi(2);
9-
| ^^^^^^^^^^^^
8+
12 | let x = 2.0_f32.powi(2);
9+
| ^^^^^^^
1010

11-
error: aborting due to previous error
11+
error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
12+
--> $DIR/method-on-ambiguous-numeric-type.rs:15:15
13+
|
14+
15 | let x = y.powi(2);
15+
| ^^^^
16+
help: you must specify a type for this binding, like `f32`
17+
|
18+
14 | let y: f32 = 2.0;
19+
| ^^^^^^
20+
21+
error: aborting due to 2 previous errors
1222

0 commit comments

Comments
 (0)