提交 65b1e86a 编写于 作者: R Ryan Cumming

Fix into() cast paren check precedence

As discussed in #47699 the logic for determining if an expression needs
parenthesis when suggesting an `.into()` cast is incorrect. Two broken
examples from nightly are:

```
error[E0308]: mismatched types
 --> main.rs:4:10
  |
4 |     test(foo as i8);
  |          ^^^^^^^^^ expected i32, found i8
help: you can cast an `i8` to `i32`, which will sign-extend the source value
  |
4 |     test(foo as i8.into());
  |
```

```
error[E0308]: mismatched types
 --> main.rs:4:10
  |
4 |     test(*foo);
  |          ^^^^ expected i32, found i8
help: you can cast an `i8` to `i32`, which will sign-extend the source value
  |
4 |     test(*foo.into());
  |
```

As suggested by @petrochenkov switch the precedence check to
PREC_POSTFIX. This catches both `as` and unary operators. Fixes #47699.
上级 a538fe7c
......@@ -15,7 +15,7 @@
use rustc::traits::ObligationCause;
use syntax::ast;
use syntax::util::parser::AssocOp;
use syntax::util::parser::PREC_POSTFIX;
use syntax_pos::{self, Span};
use rustc::hir;
use rustc::hir::print;
......@@ -336,7 +336,7 @@ fn check_for_cast(&self,
// For now, don't suggest casting with `as`.
let can_cast = false;
let needs_paren = expr.precedence().order() < (AssocOp::As.precedence() as i8);
let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8);
if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty);
......
......@@ -312,4 +312,9 @@ fn main() {
foo::<f32>(x_f64);
//~^ ERROR mismatched types
foo::<f32>(x_f32);
foo::<u32>(x_u8 as u16);
//~^ ERROR mismatched types
foo::<i32>(-x_i8);
//~^ ERROR mismatched types
}
......@@ -882,5 +882,25 @@ error[E0308]: mismatched types
312 | foo::<f32>(x_f64);
| ^^^^^ expected f32, found f64
error: aborting due to 132 previous errors
error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:316:16
|
316 | foo::<u32>(x_u8 as u16);
| ^^^^^^^^^^^ expected u32, found u16
help: you can cast an `u16` to `u32`, which will zero-extend the source value
|
316 | foo::<u32>((x_u8 as u16).into());
| ^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/numeric-cast.rs:318:16
|
318 | foo::<i32>(-x_i8);
| ^^^^^ expected i32, found i8
help: you can cast an `i8` to `i32`, which will sign-extend the source value
|
318 | foo::<i32>((-x_i8).into());
| ^^^^^^^^^^^^^^
error: aborting due to 134 previous errors
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册