Rollup merge of #47702 - etaoins:fix-into-cast-paren-precedence, r=petrochenkov
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. r? @petrochenkov
This commit is contained in:
commit
a809da3fee
3 changed files with 28 additions and 3 deletions
|
@ -15,7 +15,7 @@ use rustc::infer::InferOk;
|
||||||
use rustc::traits::ObligationCause;
|
use rustc::traits::ObligationCause;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::util::parser::AssocOp;
|
use syntax::util::parser::PREC_POSTFIX;
|
||||||
use syntax_pos::{self, Span};
|
use syntax_pos::{self, Span};
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::print;
|
use rustc::hir::print;
|
||||||
|
@ -336,7 +336,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
// For now, don't suggest casting with `as`.
|
// For now, don't suggest casting with `as`.
|
||||||
let can_cast = false;
|
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) {
|
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);
|
let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty);
|
||||||
|
|
|
@ -312,4 +312,9 @@ fn main() {
|
||||||
foo::<f32>(x_f64);
|
foo::<f32>(x_f64);
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
foo::<f32>(x_f32);
|
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);
|
312 | foo::<f32>(x_f64);
|
||||||
| ^^^^^ expected f32, found 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
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue