Skip to content

Commit

Permalink
Rollup merge of rust-lang#47702 - etaoins:fix-into-cast-paren-precede…
Browse files Browse the repository at this point in the history
…nce, r=petrochenkov

Fix into() cast paren check precedence

As discussed in rust-lang#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 rust-lang#47699.

r? @petrochenkov
  • Loading branch information
GuillaumeGomez committed Jan 25, 2018
2 parents 3a863a3 + 65b1e86 commit a809da3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc::infer::InferOk;
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;
Expand Down Expand Up @@ -336,7 +336,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// 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);
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/suggestions/numeric-cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
22 changes: 21 additions & 1 deletion src/test/ui/suggestions/numeric-cast.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit a809da3

Please sign in to comment.