Skip to content

Commit

Permalink
Do not use casting for suggestion to add type to numeric literal
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jan 4, 2018
1 parent 87242f3 commit f7aed3e
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ pub struct LifetimeDef {
}

/// A "Path" is essentially Rust's notion of a name; for instance:
/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
/// along with a bunch of supporting information.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Path {
Expand Down
43 changes: 33 additions & 10 deletions src/librustc_typeck/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,20 +215,43 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
item_name,
ty_string
);
let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
.unwrap_or("4".to_string());
let concrete_type = if actual.is_integral() {
"u32"
"i32"
} else {
"f32"
};
err.span_suggestion(expr.span,
&format!("you must specify a concrete type for \
this numeric value, like `{}`",
concrete_type),
format!("({} as {})",
snippet,
concrete_type));
match expr.node {
hir::ExprLit(_) => { // numeric literal
let snippet = tcx.sess.codemap().span_to_snippet(expr.span)
.unwrap_or("<numeric literal>".to_string());
// FIXME: use the literal for missing snippet

err.span_suggestion(expr.span,
&format!("you must specify a concrete type for \
this numeric value, like `{}`",
concrete_type),
format!("{}_{}",
snippet,
concrete_type));
}
hir::ExprPath(ref qpath) => { // local binding
if let &hir::QPath::Resolved(_, ref path) = &qpath {
if let hir::def::Def::Local(node_id) = path.def {
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));
}
}
}
_ => {}
}
err.emit();
return;
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4661,9 +4661,10 @@ x.powi(2); // same error as above
Because of this, you must give the numeric literal or binding a type:
```
let _ = (2.0 as f32).powi(2);
let _ = 2.0_f32.powi(2);
let x: f32 = 2.0;
let _ = x.powi(2);
let _ = (2.0 as f32).powi(2);
```
"##,
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issue-41652/issue_41652.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ error[E0689]: can't call method `f` on ambiguous numeric type `{integer}`
|
19 | 3.f()
| ^
help: you must specify a concrete type for this numeric value, like `u32`
help: you must specify a concrete type for this numeric value, like `i32`
|
19 | (3 as u32).f()
| ^^^^^^^^^^
19 | 3_i32.f()
| ^^^^^

error: aborting due to previous error

8 changes: 4 additions & 4 deletions src/test/ui/macros/macro-backtrace-invalid-internals.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
| -------------------- in this macro invocation
help: you must specify a concrete type for this numeric value, like `f32`
|
51 | (2.0 as f32).powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
| ^^^^^^^^^^^^
51 | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
| ^^^^^^^

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

error: aborting due to 8 previous errors

3 changes: 3 additions & 0 deletions src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
fn main() {
let x = 2.0.powi(2);
//~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
let y = 2.0;
let x = y.powi(2);
//~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
println!("{:?}", x);
}
16 changes: 13 additions & 3 deletions src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
| ^^^^
help: you must specify a concrete type for this numeric value, like `f32`
|
12 | let x = (2.0 as f32).powi(2);
| ^^^^^^^^^^^^
12 | let x = 2.0_f32.powi(2);
| ^^^^^^^

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

error: aborting due to 2 previous errors

0 comments on commit f7aed3e

Please sign in to comment.