From aec16237e4cd8c2d4d650cacac72b9a33cac1f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 6 Jan 2018 21:10:51 -0800 Subject: [PATCH 1/6] Suggest casting on numeric type error --- src/librustc/hir/mod.rs | 31 + src/librustc_typeck/check/demand.rs | 176 ++- .../ui/mismatched_types/issue-26480.stderr | 4 + src/test/ui/suggestions/numeric-cast-2.rs | 17 + src/test/ui/suggestions/numeric-cast-2.stderr | 22 + src/test/ui/suggestions/numeric-cast.rs | 336 ++++ src/test/ui/suggestions/numeric-cast.stderr | 1364 +++++++++++++++++ 7 files changed, 1946 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/suggestions/numeric-cast-2.rs create mode 100644 src/test/ui/suggestions/numeric-cast-2.stderr create mode 100644 src/test/ui/suggestions/numeric-cast.rs create mode 100644 src/test/ui/suggestions/numeric-cast.stderr diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 8d43b9b4aa739..38b6bffcadd6b 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1173,6 +1173,37 @@ impl fmt::Debug for Expr { } } +impl Expr { + + /// If casting this expression to a given numeric type would be appropriate in case of a type + /// mismatch. + /// + /// We want to minimize the amount of casting operations that are suggested, as it can be a + /// lossy operation with potentially bad side effects, so we only suggest when encountering an + /// expression that indicates that the original type couldn't be directly changed. + pub fn could_cast_in_type_mismatch(&self) -> bool { + match self.node { + ExprCall(..) | + ExprMethodCall(..) | + ExprBinary(..) | + ExprField(..) | + ExprTupField(..) | + ExprIndex(..) | + ExprPath(..) => true, + _ => false, + } + } + + pub fn needs_parens_around_cast(&self) -> bool { + match self.node { + ExprBinary(..) | + ExprCast(..) | + ExprType(..) => true, + _ => false, + } + } +} + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Expr_ { /// A `box x` expression. diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 6703bbba86b1c..7c55df7ff445f 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -137,7 +137,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) { err.span_suggestion(expr.span, msg, suggestion); - } else { + } else if !self.check_for_cast(&mut err, expr, expr_ty, expected) { let methods = self.get_conversion_methods(expected, checked_ty); if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) { let suggestions = iter::repeat(expr_text).zip(methods.iter()) @@ -287,8 +287,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Maybe remove `&`? hir::ExprAddrOf(_, ref expr) => { if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(expr.span) { - return Some(("consider removing the borrow", - code)); + return Some(("consider removing the borrow", code)); } } @@ -303,7 +302,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { format!("*{}", code))); } } - }, + } } } None @@ -311,4 +310,173 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => None, } } + + fn check_for_cast(&self, + err: &mut DiagnosticBuilder<'tcx>, + expr: &hir::Expr, + checked_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>) + -> bool { + let will_truncate = "will truncate the source value"; + let depending_on_isize = "will truncate or zero-extend depending on the bit width of \ + `isize`"; + let depending_on_usize = "will truncate or zero-extend depending on the bit width of \ + `usize`"; + let will_sign_extend = "will sign-extend the source value"; + let will_zero_extend = "will zero-extend the source value"; + + let needs_paren = expr.needs_parens_around_cast(); + + if let (Ok(src), true) = (self.tcx.sess.codemap().span_to_snippet(expr.span), + expr.could_cast_in_type_mismatch()) { + let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty); + let suggestion = format!("{}{} as {}{}", + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }, + expected_ty); + + match (&expected_ty.sty, &checked_ty.sty) { + (&ty::TyInt(ref exp), &ty::TyInt(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + suggestion); + } + (None, _) | (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + suggestion); + } + } + true + } + (&ty::TyUint(ref exp), &ty::TyUint(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + suggestion); + } + (None, _) | (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_zero_extend), + suggestion); + } + } + true + } + (&ty::TyInt(ref exp), &ty::TyUint(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp - 1 => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_zero_extend), + suggestion); + } + } + true + } + (&ty::TyUint(ref exp), &ty::TyInt(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found - 1 > exp => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + suggestion); + } + } + true + } + (&ty::TyFloat(ref exp), &ty::TyFloat(ref found)) => { + if found.bit_width() > exp.bit_width() { + err.span_suggestion(expr.span, + &format!("{}, producing the closest possible value", + msg), + suggestion); + err.warn("casting here will cause Undefined Behavior if the value is \ + finite but larger or smaller than the largest or smallest \ + finite value representable by `f32` (this is a bug and will be \ + fixed)"); + } else { + err.span_suggestion(expr.span, + &format!("{} in a lossless way", + msg), + suggestion); + } + true + } + (&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => { + err.span_suggestion(expr.span, + &format!("{}, rounding the float towards zero", + msg), + suggestion); + err.warn("casting here will cause Undefined Behavior if the rounded value \ + cannot be represented by the target integer type, including `Inf` \ + and `NaN` (this is a bug and will be fixed)"); + true + } + (&ty::TyFloat(_), &ty::TyUint(_)) | (&ty::TyFloat(_), &ty::TyInt(_)) => { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point representation \ + of the integer, rounded if necessary", + msg), + suggestion); + true + } + _ => false, + } + } else { + false + } + } } diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 5d25cb2f93c15..36c5767fc0bd0 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -6,6 +6,10 @@ error[E0308]: mismatched types ... 37 | write!(hello); | -------------- in this macro invocation +help: you can cast an `usize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` + | +26 | ($arr.len() * size_of($arr[0]) as )u64); //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0605]: non-primitive cast: `{integer}` as `()` --> $DIR/issue-26480.rs:32:19 diff --git a/src/test/ui/suggestions/numeric-cast-2.rs b/src/test/ui/suggestions/numeric-cast-2.rs new file mode 100644 index 0000000000000..24796fbe46045 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo() -> i32 { + 4 +} +fn main() { + let x: u32 = foo(); + let z: i32 = x + x; +} diff --git a/src/test/ui/suggestions/numeric-cast-2.stderr b/src/test/ui/suggestions/numeric-cast-2.stderr new file mode 100644 index 0000000000000..c31095c102df1 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:15:18 + | +15 | let x: u32 = foo(); + | ^^^^^ expected u32, found i32 +help: you can cast an `i32` to `u32`, which will sign-extend the source value + | +15 | let x: u32 = foo() as u32; + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:16:18 + | +16 | let z: i32 = x + x; + | ^^^^^ expected i32, found u32 +help: you can cast an `u32` to `i32`, which will truncate the source value + | +16 | let z: i32 = (x + x as )i32; + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/suggestions/numeric-cast.rs b/src/test/ui/suggestions/numeric-cast.rs new file mode 100644 index 0000000000000..cca735d30d8cb --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.rs @@ -0,0 +1,336 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +fn foo(_x: N) {} + +fn main() { + let x_usize: usize = 1; + let x_u64: u64 = 2; + let x_u32: u32 = 3; + let x_u16: u16 = 4; + let x_u8: u8 = 5; + let x_isize: isize = 6; + let x_i64: i64 = 7; + let x_i32: i32 = 8; + let x_i16: i16 = 9; + let x_i8: i8 = 10; + let x_f64: f64 = 11.0; + let x_f32: f32 = 12.0; + + foo::(x_usize); + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + foo::(x_f32); + //~^ ERROR mismatched types + + foo::(x_usize); + //~^ ERROR mismatched types + foo::(x_u64); + //~^ ERROR mismatched types + foo::(x_u32); + //~^ ERROR mismatched types + foo::(x_u16); + //~^ ERROR mismatched types + foo::(x_u8); + //~^ ERROR mismatched types + foo::(x_isize); + //~^ ERROR mismatched types + foo::(x_i64); + //~^ ERROR mismatched types + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + //~| WARN casting here will cause Undefined Behavior + foo::(x_f32); +} diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr new file mode 100644 index 0000000000000..4f4e4205f1fbb --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -0,0 +1,1364 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:29:18 + | +29 | foo::(x_u64); + | ^^^^^ expected usize, found u64 +help: you can cast an `u64` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` + | +29 | foo::(x_u64 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:31:18 + | +31 | foo::(x_u32); + | ^^^^^ expected usize, found u32 +help: you can cast an `u32` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` + | +31 | foo::(x_u32 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:33:18 + | +33 | foo::(x_u16); + | ^^^^^ expected usize, found u16 +help: you can cast an `u16` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` + | +33 | foo::(x_u16 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:35:18 + | +35 | foo::(x_u8); + | ^^^^ expected usize, found u8 +help: you can cast an `u8` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` + | +35 | foo::(x_u8 as usize); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:37:18 + | +37 | foo::(x_isize); + | ^^^^^^^ expected usize, found isize +help: you can cast an `isize` to `usize`, which will sign-extend the source value + | +37 | foo::(x_isize as usize); + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:39:18 + | +39 | foo::(x_i64); + | ^^^^^ expected usize, found i64 +help: you can cast an `i64` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` + | +39 | foo::(x_i64 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:41:18 + | +41 | foo::(x_i32); + | ^^^^^ expected usize, found i32 +help: you can cast an `i32` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` + | +41 | foo::(x_i32 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:43:18 + | +43 | foo::(x_i16); + | ^^^^^ expected usize, found i16 +help: you can cast an `i16` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` + | +43 | foo::(x_i16 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:45:18 + | +45 | foo::(x_i8); + | ^^^^ expected usize, found i8 +help: you can cast an `i8` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` + | +45 | foo::(x_i8 as usize); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:47:18 + | +47 | foo::(x_f64); + | ^^^^^ expected usize, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `usize`, rounding the float towards zero + | +47 | foo::(x_f64 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:50:18 + | +50 | foo::(x_f32); + | ^^^^^ expected usize, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `usize`, rounding the float towards zero + | +50 | foo::(x_f32 as usize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:54:18 + | +54 | foo::(x_usize); + | ^^^^^^^ expected isize, found usize +help: you can cast an `usize` to `isize`, which will truncate the source value + | +54 | foo::(x_usize as isize); + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:56:18 + | +56 | foo::(x_u64); + | ^^^^^ expected isize, found u64 +help: you can cast an `u64` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` + | +56 | foo::(x_u64 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:58:18 + | +58 | foo::(x_u32); + | ^^^^^ expected isize, found u32 +help: you can cast an `u32` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` + | +58 | foo::(x_u32 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:60:18 + | +60 | foo::(x_u16); + | ^^^^^ expected isize, found u16 +help: you can cast an `u16` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` + | +60 | foo::(x_u16 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:62:18 + | +62 | foo::(x_u8); + | ^^^^ expected isize, found u8 +help: you can cast an `u8` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` + | +62 | foo::(x_u8 as isize); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:65:18 + | +65 | foo::(x_i64); + | ^^^^^ expected isize, found i64 +help: you can cast an `i64` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` + | +65 | foo::(x_i64 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:67:18 + | +67 | foo::(x_i32); + | ^^^^^ expected isize, found i32 +help: you can cast an `i32` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` + | +67 | foo::(x_i32 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:69:18 + | +69 | foo::(x_i16); + | ^^^^^ expected isize, found i16 +help: you can cast an `i16` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` + | +69 | foo::(x_i16 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:71:18 + | +71 | foo::(x_i8); + | ^^^^ expected isize, found i8 +help: you can cast an `i8` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` + | +71 | foo::(x_i8 as isize); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:73:18 + | +73 | foo::(x_f64); + | ^^^^^ expected isize, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `isize`, rounding the float towards zero + | +73 | foo::(x_f64 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:76:18 + | +76 | foo::(x_f32); + | ^^^^^ expected isize, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `isize`, rounding the float towards zero + | +76 | foo::(x_f32 as isize); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:80:16 + | +80 | foo::(x_usize); + | ^^^^^^^ expected u64, found usize +help: you can cast an `usize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` + | +80 | foo::(x_usize as u64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:83:16 + | +83 | foo::(x_u32); + | ^^^^^ expected u64, found u32 +help: you can cast an `u32` to `u64`, which will zero-extend the source value + | +83 | foo::(x_u32 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:85:16 + | +85 | foo::(x_u16); + | ^^^^^ expected u64, found u16 +help: you can cast an `u16` to `u64`, which will zero-extend the source value + | +85 | foo::(x_u16 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:87:16 + | +87 | foo::(x_u8); + | ^^^^ expected u64, found u8 +help: you can cast an `u8` to `u64`, which will zero-extend the source value + | +87 | foo::(x_u8 as u64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:89:16 + | +89 | foo::(x_isize); + | ^^^^^^^ expected u64, found isize +help: you can cast an `isize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` + | +89 | foo::(x_isize as u64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:91:16 + | +91 | foo::(x_i64); + | ^^^^^ expected u64, found i64 +help: you can cast an `i64` to `u64`, which will sign-extend the source value + | +91 | foo::(x_i64 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:93:16 + | +93 | foo::(x_i32); + | ^^^^^ expected u64, found i32 +help: you can cast an `i32` to `u64`, which will sign-extend the source value + | +93 | foo::(x_i32 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:95:16 + | +95 | foo::(x_i16); + | ^^^^^ expected u64, found i16 +help: you can cast an `i16` to `u64`, which will sign-extend the source value + | +95 | foo::(x_i16 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:97:16 + | +97 | foo::(x_i8); + | ^^^^ expected u64, found i8 +help: you can cast an `i8` to `u64`, which will sign-extend the source value + | +97 | foo::(x_i8 as u64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:99:16 + | +99 | foo::(x_f64); + | ^^^^^ expected u64, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `u64`, rounding the float towards zero + | +99 | foo::(x_f64 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:102:16 + | +102 | foo::(x_f32); + | ^^^^^ expected u64, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `u64`, rounding the float towards zero + | +102 | foo::(x_f32 as u64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:106:16 + | +106 | foo::(x_usize); + | ^^^^^^^ expected i64, found usize +help: you can cast an `usize` to `i64`, which will truncate or zero-extend depending on the bit width of `isize` + | +106 | foo::(x_usize as i64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:108:16 + | +108 | foo::(x_u64); + | ^^^^^ expected i64, found u64 +help: you can cast an `u64` to `i64`, which will truncate the source value + | +108 | foo::(x_u64 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:110:16 + | +110 | foo::(x_u32); + | ^^^^^ expected i64, found u32 +help: you can cast an `u32` to `i64`, which will zero-extend the source value + | +110 | foo::(x_u32 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:112:16 + | +112 | foo::(x_u16); + | ^^^^^ expected i64, found u16 +help: you can cast an `u16` to `i64`, which will zero-extend the source value + | +112 | foo::(x_u16 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:114:16 + | +114 | foo::(x_u8); + | ^^^^ expected i64, found u8 +help: you can cast an `u8` to `i64`, which will zero-extend the source value + | +114 | foo::(x_u8 as i64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:116:16 + | +116 | foo::(x_isize); + | ^^^^^^^ expected i64, found isize +help: you can cast an `isize` to `i64`, which will truncate or zero-extend depending on the bit width of `isize` + | +116 | foo::(x_isize as i64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:119:16 + | +119 | foo::(x_i32); + | ^^^^^ expected i64, found i32 +help: you can cast an `i32` to `i64`, which will sign-extend the source value + | +119 | foo::(x_i32 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:121:16 + | +121 | foo::(x_i16); + | ^^^^^ expected i64, found i16 +help: you can cast an `i16` to `i64`, which will sign-extend the source value + | +121 | foo::(x_i16 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:123:16 + | +123 | foo::(x_i8); + | ^^^^ expected i64, found i8 +help: you can cast an `i8` to `i64`, which will sign-extend the source value + | +123 | foo::(x_i8 as i64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:125:16 + | +125 | foo::(x_f64); + | ^^^^^ expected i64, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `i64`, rounding the float towards zero + | +125 | foo::(x_f64 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:128:16 + | +128 | foo::(x_f32); + | ^^^^^ expected i64, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `i64`, rounding the float towards zero + | +128 | foo::(x_f32 as i64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:132:16 + | +132 | foo::(x_usize); + | ^^^^^^^ expected u32, found usize +help: you can cast an `usize` to `u32`, which will truncate or zero-extend depending on the bit width of `usize` + | +132 | foo::(x_usize as u32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:134:16 + | +134 | foo::(x_u64); + | ^^^^^ expected u32, found u64 +help: you can cast an `u64` to `u32`, which will truncate the source value + | +134 | foo::(x_u64 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:137:16 + | +137 | foo::(x_u16); + | ^^^^^ expected u32, found u16 +help: you can cast an `u16` to `u32`, which will zero-extend the source value + | +137 | foo::(x_u16 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:139:16 + | +139 | foo::(x_u8); + | ^^^^ expected u32, found u8 +help: you can cast an `u8` to `u32`, which will zero-extend the source value + | +139 | foo::(x_u8 as u32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:141:16 + | +141 | foo::(x_isize); + | ^^^^^^^ expected u32, found isize +help: you can cast an `isize` to `u32`, which will truncate or zero-extend depending on the bit width of `usize` + | +141 | foo::(x_isize as u32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:143:16 + | +143 | foo::(x_i64); + | ^^^^^ expected u32, found i64 +help: you can cast an `i64` to `u32`, which will truncate the source value + | +143 | foo::(x_i64 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:145:16 + | +145 | foo::(x_i32); + | ^^^^^ expected u32, found i32 +help: you can cast an `i32` to `u32`, which will sign-extend the source value + | +145 | foo::(x_i32 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:147:16 + | +147 | foo::(x_i16); + | ^^^^^ expected u32, found i16 +help: you can cast an `i16` to `u32`, which will sign-extend the source value + | +147 | foo::(x_i16 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:149:16 + | +149 | foo::(x_i8); + | ^^^^ expected u32, found i8 +help: you can cast an `i8` to `u32`, which will sign-extend the source value + | +149 | foo::(x_i8 as u32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:151:16 + | +151 | foo::(x_f64); + | ^^^^^ expected u32, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `u32`, rounding the float towards zero + | +151 | foo::(x_f64 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:154:16 + | +154 | foo::(x_f32); + | ^^^^^ expected u32, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `u32`, rounding the float towards zero + | +154 | foo::(x_f32 as u32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:158:16 + | +158 | foo::(x_usize); + | ^^^^^^^ expected i32, found usize +help: you can cast an `usize` to `i32`, which will truncate or zero-extend depending on the bit width of `isize` + | +158 | foo::(x_usize as i32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:160:16 + | +160 | foo::(x_u64); + | ^^^^^ expected i32, found u64 +help: you can cast an `u64` to `i32`, which will truncate the source value + | +160 | foo::(x_u64 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:162:16 + | +162 | foo::(x_u32); + | ^^^^^ expected i32, found u32 +help: you can cast an `u32` to `i32`, which will truncate the source value + | +162 | foo::(x_u32 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:164:16 + | +164 | foo::(x_u16); + | ^^^^^ expected i32, found u16 +help: you can cast an `u16` to `i32`, which will zero-extend the source value + | +164 | foo::(x_u16 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:166:16 + | +166 | foo::(x_u8); + | ^^^^ expected i32, found u8 +help: you can cast an `u8` to `i32`, which will zero-extend the source value + | +166 | foo::(x_u8 as i32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:168:16 + | +168 | foo::(x_isize); + | ^^^^^^^ expected i32, found isize +help: you can cast an `isize` to `i32`, which will truncate or zero-extend depending on the bit width of `isize` + | +168 | foo::(x_isize as i32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:170:16 + | +170 | foo::(x_i64); + | ^^^^^ expected i32, found i64 +help: you can cast an `i64` to `i32`, which will truncate the source value + | +170 | foo::(x_i64 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:173:16 + | +173 | foo::(x_i16); + | ^^^^^ expected i32, found i16 +help: you can cast an `i16` to `i32`, which will sign-extend the source value + | +173 | foo::(x_i16 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:175:16 + | +175 | foo::(x_i8); + | ^^^^ expected i32, found i8 +help: you can cast an `i8` to `i32`, which will sign-extend the source value + | +175 | foo::(x_i8 as i32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:177:16 + | +177 | foo::(x_f64); + | ^^^^^ expected i32, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `i32`, rounding the float towards zero + | +177 | foo::(x_f64 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:180:16 + | +180 | foo::(x_f32); + | ^^^^^ expected i32, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `i32`, rounding the float towards zero + | +180 | foo::(x_f32 as i32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:184:16 + | +184 | foo::(x_usize); + | ^^^^^^^ expected u16, found usize +help: you can cast an `usize` to `u16`, which will truncate or zero-extend depending on the bit width of `usize` + | +184 | foo::(x_usize as u16); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:186:16 + | +186 | foo::(x_u64); + | ^^^^^ expected u16, found u64 +help: you can cast an `u64` to `u16`, which will truncate the source value + | +186 | foo::(x_u64 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:188:16 + | +188 | foo::(x_u32); + | ^^^^^ expected u16, found u32 +help: you can cast an `u32` to `u16`, which will truncate the source value + | +188 | foo::(x_u32 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:191:16 + | +191 | foo::(x_u8); + | ^^^^ expected u16, found u8 +help: you can cast an `u8` to `u16`, which will zero-extend the source value + | +191 | foo::(x_u8 as u16); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:193:16 + | +193 | foo::(x_isize); + | ^^^^^^^ expected u16, found isize +help: you can cast an `isize` to `u16`, which will truncate or zero-extend depending on the bit width of `usize` + | +193 | foo::(x_isize as u16); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:195:16 + | +195 | foo::(x_i64); + | ^^^^^ expected u16, found i64 +help: you can cast an `i64` to `u16`, which will truncate the source value + | +195 | foo::(x_i64 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:197:16 + | +197 | foo::(x_i32); + | ^^^^^ expected u16, found i32 +help: you can cast an `i32` to `u16`, which will truncate the source value + | +197 | foo::(x_i32 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:199:16 + | +199 | foo::(x_i16); + | ^^^^^ expected u16, found i16 +help: you can cast an `i16` to `u16`, which will sign-extend the source value + | +199 | foo::(x_i16 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:201:16 + | +201 | foo::(x_i8); + | ^^^^ expected u16, found i8 +help: you can cast an `i8` to `u16`, which will sign-extend the source value + | +201 | foo::(x_i8 as u16); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:203:16 + | +203 | foo::(x_f64); + | ^^^^^ expected u16, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `u16`, rounding the float towards zero + | +203 | foo::(x_f64 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:206:16 + | +206 | foo::(x_f32); + | ^^^^^ expected u16, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `u16`, rounding the float towards zero + | +206 | foo::(x_f32 as u16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:210:16 + | +210 | foo::(x_usize); + | ^^^^^^^ expected i16, found usize +help: you can cast an `usize` to `i16`, which will truncate or zero-extend depending on the bit width of `isize` + | +210 | foo::(x_usize as i16); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:212:16 + | +212 | foo::(x_u64); + | ^^^^^ expected i16, found u64 +help: you can cast an `u64` to `i16`, which will truncate the source value + | +212 | foo::(x_u64 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:214:16 + | +214 | foo::(x_u32); + | ^^^^^ expected i16, found u32 +help: you can cast an `u32` to `i16`, which will truncate the source value + | +214 | foo::(x_u32 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:216:16 + | +216 | foo::(x_u16); + | ^^^^^ expected i16, found u16 +help: you can cast an `u16` to `i16`, which will truncate the source value + | +216 | foo::(x_u16 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:218:16 + | +218 | foo::(x_u8); + | ^^^^ expected i16, found u8 +help: you can cast an `u8` to `i16`, which will zero-extend the source value + | +218 | foo::(x_u8 as i16); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:220:16 + | +220 | foo::(x_isize); + | ^^^^^^^ expected i16, found isize +help: you can cast an `isize` to `i16`, which will truncate or zero-extend depending on the bit width of `isize` + | +220 | foo::(x_isize as i16); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:222:16 + | +222 | foo::(x_i64); + | ^^^^^ expected i16, found i64 +help: you can cast an `i64` to `i16`, which will truncate the source value + | +222 | foo::(x_i64 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:224:16 + | +224 | foo::(x_i32); + | ^^^^^ expected i16, found i32 +help: you can cast an `i32` to `i16`, which will truncate the source value + | +224 | foo::(x_i32 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:227:16 + | +227 | foo::(x_i8); + | ^^^^ expected i16, found i8 +help: you can cast an `i8` to `i16`, which will sign-extend the source value + | +227 | foo::(x_i8 as i16); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:229:16 + | +229 | foo::(x_f64); + | ^^^^^ expected i16, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `i16`, rounding the float towards zero + | +229 | foo::(x_f64 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:232:16 + | +232 | foo::(x_f32); + | ^^^^^ expected i16, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `i16`, rounding the float towards zero + | +232 | foo::(x_f32 as i16); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:236:15 + | +236 | foo::(x_usize); + | ^^^^^^^ expected u8, found usize +help: you can cast an `usize` to `u8`, which will truncate or zero-extend depending on the bit width of `usize` + | +236 | foo::(x_usize as u8); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:238:15 + | +238 | foo::(x_u64); + | ^^^^^ expected u8, found u64 +help: you can cast an `u64` to `u8`, which will truncate the source value + | +238 | foo::(x_u64 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:240:15 + | +240 | foo::(x_u32); + | ^^^^^ expected u8, found u32 +help: you can cast an `u32` to `u8`, which will truncate the source value + | +240 | foo::(x_u32 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:242:15 + | +242 | foo::(x_u16); + | ^^^^^ expected u8, found u16 +help: you can cast an `u16` to `u8`, which will truncate the source value + | +242 | foo::(x_u16 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:245:15 + | +245 | foo::(x_isize); + | ^^^^^^^ expected u8, found isize +help: you can cast an `isize` to `u8`, which will truncate or zero-extend depending on the bit width of `usize` + | +245 | foo::(x_isize as u8); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:247:15 + | +247 | foo::(x_i64); + | ^^^^^ expected u8, found i64 +help: you can cast an `i64` to `u8`, which will truncate the source value + | +247 | foo::(x_i64 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:249:15 + | +249 | foo::(x_i32); + | ^^^^^ expected u8, found i32 +help: you can cast an `i32` to `u8`, which will truncate the source value + | +249 | foo::(x_i32 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:251:15 + | +251 | foo::(x_i16); + | ^^^^^ expected u8, found i16 +help: you can cast an `i16` to `u8`, which will truncate the source value + | +251 | foo::(x_i16 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:253:15 + | +253 | foo::(x_i8); + | ^^^^ expected u8, found i8 +help: you can cast an `i8` to `u8`, which will sign-extend the source value + | +253 | foo::(x_i8 as u8); + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:255:15 + | +255 | foo::(x_f64); + | ^^^^^ expected u8, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `u8`, rounding the float towards zero + | +255 | foo::(x_f64 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:258:15 + | +258 | foo::(x_f32); + | ^^^^^ expected u8, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `u8`, rounding the float towards zero + | +258 | foo::(x_f32 as u8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:262:15 + | +262 | foo::(x_usize); + | ^^^^^^^ expected i8, found usize +help: you can cast an `usize` to `i8`, which will truncate or zero-extend depending on the bit width of `isize` + | +262 | foo::(x_usize as i8); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:264:15 + | +264 | foo::(x_u64); + | ^^^^^ expected i8, found u64 +help: you can cast an `u64` to `i8`, which will truncate the source value + | +264 | foo::(x_u64 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:266:15 + | +266 | foo::(x_u32); + | ^^^^^ expected i8, found u32 +help: you can cast an `u32` to `i8`, which will truncate the source value + | +266 | foo::(x_u32 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:268:15 + | +268 | foo::(x_u16); + | ^^^^^ expected i8, found u16 +help: you can cast an `u16` to `i8`, which will truncate the source value + | +268 | foo::(x_u16 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:270:15 + | +270 | foo::(x_u8); + | ^^^^ expected i8, found u8 +help: you can cast an `u8` to `i8`, which will truncate the source value + | +270 | foo::(x_u8 as i8); + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:272:15 + | +272 | foo::(x_isize); + | ^^^^^^^ expected i8, found isize +help: you can cast an `isize` to `i8`, which will truncate or zero-extend depending on the bit width of `isize` + | +272 | foo::(x_isize as i8); + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:274:15 + | +274 | foo::(x_i64); + | ^^^^^ expected i8, found i64 +help: you can cast an `i64` to `i8`, which will truncate the source value + | +274 | foo::(x_i64 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:276:15 + | +276 | foo::(x_i32); + | ^^^^^ expected i8, found i32 +help: you can cast an `i32` to `i8`, which will truncate the source value + | +276 | foo::(x_i32 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:278:15 + | +278 | foo::(x_i16); + | ^^^^^ expected i8, found i16 +help: you can cast an `i16` to `i8`, which will truncate the source value + | +278 | foo::(x_i16 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:281:15 + | +281 | foo::(x_f64); + | ^^^^^ expected i8, found f64 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f64` to `i8`, rounding the float towards zero + | +281 | foo::(x_f64 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:284:15 + | +284 | foo::(x_f32); + | ^^^^^ expected i8, found f32 + | + = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. +help: you can cast an `f32` to `i8`, rounding the float towards zero + | +284 | foo::(x_f32 as i8); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:288:16 + | +288 | foo::(x_usize); + | ^^^^^^^ expected f64, found usize +help: you can cast an `usize` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +288 | foo::(x_usize as f64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:290:16 + | +290 | foo::(x_u64); + | ^^^^^ expected f64, found u64 +help: you can cast an `u64` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +290 | foo::(x_u64 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:292:16 + | +292 | foo::(x_u32); + | ^^^^^ expected f64, found u32 +help: you can cast an `u32` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +292 | foo::(x_u32 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:294:16 + | +294 | foo::(x_u16); + | ^^^^^ expected f64, found u16 +help: you can cast an `u16` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +294 | foo::(x_u16 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:296:16 + | +296 | foo::(x_u8); + | ^^^^ expected f64, found u8 +help: you can cast an `u8` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +296 | foo::(x_u8 as f64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:298:16 + | +298 | foo::(x_isize); + | ^^^^^^^ expected f64, found isize +help: you can cast an `isize` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +298 | foo::(x_isize as f64); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:300:16 + | +300 | foo::(x_i64); + | ^^^^^ expected f64, found i64 +help: you can cast an `i64` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +300 | foo::(x_i64 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:302:16 + | +302 | foo::(x_i32); + | ^^^^^ expected f64, found i32 +help: you can cast an `i32` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +302 | foo::(x_i32 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:304:16 + | +304 | foo::(x_i16); + | ^^^^^ expected f64, found i16 +help: you can cast an `i16` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +304 | foo::(x_i16 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:306:16 + | +306 | foo::(x_i8); + | ^^^^ expected f64, found i8 +help: you can cast an `i8` to `f64`, producing the floating point representation of the integer, rounded if necessary + | +306 | foo::(x_i8 as f64); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:309:16 + | +309 | foo::(x_f32); + | ^^^^^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +309 | foo::(x_f32 as f64); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:312:16 + | +312 | foo::(x_usize); + | ^^^^^^^ expected f32, found usize +help: you can cast an `usize` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +312 | foo::(x_usize as f32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:314:16 + | +314 | foo::(x_u64); + | ^^^^^ expected f32, found u64 +help: you can cast an `u64` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +314 | foo::(x_u64 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:316:16 + | +316 | foo::(x_u32); + | ^^^^^ expected f32, found u32 +help: you can cast an `u32` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +316 | foo::(x_u32 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:318:16 + | +318 | foo::(x_u16); + | ^^^^^ expected f32, found u16 +help: you can cast an `u16` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +318 | foo::(x_u16 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:320:16 + | +320 | foo::(x_u8); + | ^^^^ expected f32, found u8 +help: you can cast an `u8` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +320 | foo::(x_u8 as f32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:322:16 + | +322 | foo::(x_isize); + | ^^^^^^^ expected f32, found isize +help: you can cast an `isize` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +322 | foo::(x_isize as f32); + | ^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:324:16 + | +324 | foo::(x_i64); + | ^^^^^ expected f32, found i64 +help: you can cast an `i64` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +324 | foo::(x_i64 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:326:16 + | +326 | foo::(x_i32); + | ^^^^^ expected f32, found i32 +help: you can cast an `i32` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +326 | foo::(x_i32 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:328:16 + | +328 | foo::(x_i16); + | ^^^^^ expected f32, found i16 +help: you can cast an `i16` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +328 | foo::(x_i16 as f32); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:330:16 + | +330 | foo::(x_i8); + | ^^^^ expected f32, found i8 +help: you can cast an `i8` to `f32`, producing the floating point representation of the integer, rounded if necessary + | +330 | foo::(x_i8 as f32); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:332:16 + | +332 | foo::(x_f64); + | ^^^^^ expected f32, found f64 + | + = warning: Currently this will cause Undefined Behavior if the value is finite but larger or smaller than the largest or smallest finite value representable by `f32`. This is a bug and will be fixed. +help: you can cast an `f64` to `f32`, producing the closest possible value + | +332 | foo::(x_f64 as f32); + | ^^^^^^^^^^^^ + +error: aborting due to 132 previous errors + From af91d9955b036630657d69210ad4040e1725c14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 7 Jan 2018 12:27:03 -0800 Subject: [PATCH 2/6] Use `into` for casting when possible --- src/librustc/hir/mod.rs | 31 --- src/librustc_typeck/check/demand.rs | 246 +++++++++++------- .../ui/mismatched_types/issue-26480.stderr | 2 +- src/test/ui/suggestions/numeric-cast-2.rs | 2 + src/test/ui/suggestions/numeric-cast-2.stderr | 6 +- src/test/ui/suggestions/numeric-cast.rs | 2 +- src/test/ui/suggestions/numeric-cast.stderr | 88 +++---- 7 files changed, 205 insertions(+), 172 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 38b6bffcadd6b..8d43b9b4aa739 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1173,37 +1173,6 @@ impl fmt::Debug for Expr { } } -impl Expr { - - /// If casting this expression to a given numeric type would be appropriate in case of a type - /// mismatch. - /// - /// We want to minimize the amount of casting operations that are suggested, as it can be a - /// lossy operation with potentially bad side effects, so we only suggest when encountering an - /// expression that indicates that the original type couldn't be directly changed. - pub fn could_cast_in_type_mismatch(&self) -> bool { - match self.node { - ExprCall(..) | - ExprMethodCall(..) | - ExprBinary(..) | - ExprField(..) | - ExprTupField(..) | - ExprIndex(..) | - ExprPath(..) => true, - _ => false, - } - } - - pub fn needs_parens_around_cast(&self) -> bool { - match self.node { - ExprBinary(..) | - ExprCast(..) | - ExprType(..) => true, - _ => false, - } - } -} - #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Expr_ { /// A `box x` expression. diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 7c55df7ff445f..42cca2bbb5ebb 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -325,34 +325,58 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let will_sign_extend = "will sign-extend the source value"; let will_zero_extend = "will zero-extend the source value"; - let needs_paren = expr.needs_parens_around_cast(); + // If casting this expression to a given numeric type would be appropriate in case of a type + // mismatch. + // + // We want to minimize the amount of casting operations that are suggested, as it can be a + // lossy operation with potentially bad side effects, so we only suggest when encountering + // an expression that indicates that the original type couldn't be directly changed. + let can_cast = match expr.node { + hir::ExprPath(..) | + hir::ExprCall(..) | + hir::ExprMethodCall(..) | + hir::ExprBinary(..) => true, + _ => false, + }; + + let needs_paren = match expr.node { + hir::ExprBinary(..) => true, + _ => false, + }; - if let (Ok(src), true) = (self.tcx.sess.codemap().span_to_snippet(expr.span), - expr.could_cast_in_type_mismatch()) { + 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 suggestion = format!("{}{} as {}{}", - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }, - expected_ty); + let cast_suggestion = format!("{}{}{} as {}", + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }, + expected_ty); + let into_suggestion = format!("{}{}{}.into()", + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }); match (&expected_ty.sty, &checked_ty.sty) { (&ty::TyInt(ref exp), &ty::TyInt(ref found)) => { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found > exp => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_truncate), - suggestion); + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } } (None, _) | (_, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), - suggestion); + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + cast_suggestion); + } } _ => { err.span_suggestion(expr.span, &format!("{}, which {}", msg, will_sign_extend), - suggestion); + into_suggestion); } } true @@ -360,117 +384,155 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (&ty::TyUint(ref exp), &ty::TyUint(ref found)) => { match (found.bit_width(), exp.bit_width()) { (Some(found), Some(exp)) if found > exp => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_truncate), - suggestion); + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } } (None, _) | (_, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), - suggestion); + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + cast_suggestion); + } } _ => { err.span_suggestion(expr.span, &format!("{}, which {}", msg, will_zero_extend), - suggestion); + into_suggestion); } } true } (&ty::TyInt(ref exp), &ty::TyUint(ref found)) => { - match (found.bit_width(), exp.bit_width()) { - (Some(found), Some(exp)) if found > exp - 1 => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_truncate), - suggestion); - } - (None, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_truncate), - suggestion); - } - (None, _) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), - suggestion); - } - (_, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), - suggestion); - } - _ => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_zero_extend), - suggestion); + if can_cast { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp - 1 => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + cast_suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + cast_suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_zero_extend), + cast_suggestion); + } } } true } (&ty::TyUint(ref exp), &ty::TyInt(ref found)) => { - match (found.bit_width(), exp.bit_width()) { - (Some(found), Some(exp)) if found - 1 > exp => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_truncate), - suggestion); - } - (None, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_sign_extend), - suggestion); - } - (None, _) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), - suggestion); - } - (_, None) => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), - suggestion); - } - _ => { - err.span_suggestion(expr.span, - &format!("{}, which {}", msg, will_sign_extend), - suggestion); + if can_cast { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found - 1 > exp => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + cast_suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_usize), + cast_suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, depending_on_isize), + cast_suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + cast_suggestion); + } } } true } (&ty::TyFloat(ref exp), &ty::TyFloat(ref found)) => { - if found.bit_width() > exp.bit_width() { + if found.bit_width() < exp.bit_width() { + err.span_suggestion(expr.span, + &format!("{} in a lossless way", + msg), + into_suggestion); + } else if can_cast { err.span_suggestion(expr.span, &format!("{}, producing the closest possible value", msg), - suggestion); - err.warn("casting here will cause Undefined Behavior if the value is \ + cast_suggestion); + err.warn("casting here will cause undefined behavior if the value is \ finite but larger or smaller than the largest or smallest \ finite value representable by `f32` (this is a bug and will be \ fixed)"); - } else { + } + true + } + (&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => { + if can_cast { err.span_suggestion(expr.span, - &format!("{} in a lossless way", + &format!("{}, rounding the float towards zero", msg), - suggestion); + cast_suggestion); + err.warn("casting here will cause undefined behavior if the rounded value \ + cannot be represented by the target integer type, including \ + `Inf` and `NaN` (this is a bug and will be fixed)"); } true } - (&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => { - err.span_suggestion(expr.span, - &format!("{}, rounding the float towards zero", - msg), - suggestion); - err.warn("casting here will cause Undefined Behavior if the rounded value \ - cannot be represented by the target integer type, including `Inf` \ - and `NaN` (this is a bug and will be fixed)"); + (&ty::TyFloat(ref exp), &ty::TyUint(ref found)) => { + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + into_suggestion); + } else if can_cast { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + cast_suggestion); + } true } - (&ty::TyFloat(_), &ty::TyUint(_)) | (&ty::TyFloat(_), &ty::TyInt(_)) => { - err.span_suggestion(expr.span, - &format!("{}, producing the floating point representation \ - of the integer, rounded if necessary", - msg), - suggestion); + (&ty::TyFloat(ref exp), &ty::TyInt(ref found)) => { + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + into_suggestion); + } else if can_cast { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + cast_suggestion); + } true } _ => false, diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 36c5767fc0bd0..0641e09b552e5 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -8,7 +8,7 @@ error[E0308]: mismatched types | -------------- in this macro invocation help: you can cast an `usize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` | -26 | ($arr.len() * size_of($arr[0]) as )u64); //~ ERROR mismatched types +26 | ($arr.len() * size_of($arr[0])) as u64); //~ ERROR mismatched types | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0605]: non-primitive cast: `{integer}` as `()` diff --git a/src/test/ui/suggestions/numeric-cast-2.rs b/src/test/ui/suggestions/numeric-cast-2.rs index 24796fbe46045..4c905a090a68c 100644 --- a/src/test/ui/suggestions/numeric-cast-2.rs +++ b/src/test/ui/suggestions/numeric-cast-2.rs @@ -13,5 +13,7 @@ fn foo() -> i32 { } fn main() { let x: u32 = foo(); + //~^ ERROR mismatched types let z: i32 = x + x; + //~^ ERROR mismatched types } diff --git a/src/test/ui/suggestions/numeric-cast-2.stderr b/src/test/ui/suggestions/numeric-cast-2.stderr index c31095c102df1..44703867b7547 100644 --- a/src/test/ui/suggestions/numeric-cast-2.stderr +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -9,13 +9,13 @@ help: you can cast an `i32` to `u32`, which will sign-extend the source value | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast-2.rs:16:18 + --> $DIR/numeric-cast-2.rs:17:18 | -16 | let z: i32 = x + x; +17 | let z: i32 = x + x; | ^^^^^ expected i32, found u32 help: you can cast an `u32` to `i32`, which will truncate the source value | -16 | let z: i32 = (x + x as )i32; +17 | let z: i32 = (x + x) as i32; | ^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/numeric-cast.rs b/src/test/ui/suggestions/numeric-cast.rs index cca735d30d8cb..cd5e183ede942 100644 --- a/src/test/ui/suggestions/numeric-cast.rs +++ b/src/test/ui/suggestions/numeric-cast.rs @@ -331,6 +331,6 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior + //~| WARN casting here will cause undefined behavior foo::(x_f32); } diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr index 4f4e4205f1fbb..f074a3bc280a1 100644 --- a/src/test/ui/suggestions/numeric-cast.stderr +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -94,7 +94,7 @@ error[E0308]: mismatched types 47 | foo::(x_f64); | ^^^^^ expected usize, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `usize`, rounding the float towards zero | 47 | foo::(x_f64 as usize); @@ -106,7 +106,7 @@ error[E0308]: mismatched types 50 | foo::(x_f32); | ^^^^^ expected usize, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `usize`, rounding the float towards zero | 50 | foo::(x_f32 as usize); @@ -208,7 +208,7 @@ error[E0308]: mismatched types 73 | foo::(x_f64); | ^^^^^ expected isize, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `isize`, rounding the float towards zero | 73 | foo::(x_f64 as isize); @@ -220,7 +220,7 @@ error[E0308]: mismatched types 76 | foo::(x_f32); | ^^^^^ expected isize, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `isize`, rounding the float towards zero | 76 | foo::(x_f32 as isize); @@ -243,7 +243,7 @@ error[E0308]: mismatched types | ^^^^^ expected u64, found u32 help: you can cast an `u32` to `u64`, which will zero-extend the source value | -83 | foo::(x_u32 as u64); +83 | foo::(x_u32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -253,7 +253,7 @@ error[E0308]: mismatched types | ^^^^^ expected u64, found u16 help: you can cast an `u16` to `u64`, which will zero-extend the source value | -85 | foo::(x_u16 as u64); +85 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -263,7 +263,7 @@ error[E0308]: mismatched types | ^^^^ expected u64, found u8 help: you can cast an `u8` to `u64`, which will zero-extend the source value | -87 | foo::(x_u8 as u64); +87 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -322,7 +322,7 @@ error[E0308]: mismatched types 99 | foo::(x_f64); | ^^^^^ expected u64, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `u64`, rounding the float towards zero | 99 | foo::(x_f64 as u64); @@ -334,7 +334,7 @@ error[E0308]: mismatched types 102 | foo::(x_f32); | ^^^^^ expected u64, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `u64`, rounding the float towards zero | 102 | foo::(x_f32 as u64); @@ -407,7 +407,7 @@ error[E0308]: mismatched types | ^^^^^ expected i64, found i32 help: you can cast an `i32` to `i64`, which will sign-extend the source value | -119 | foo::(x_i32 as i64); +119 | foo::(x_i32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -417,7 +417,7 @@ error[E0308]: mismatched types | ^^^^^ expected i64, found i16 help: you can cast an `i16` to `i64`, which will sign-extend the source value | -121 | foo::(x_i16 as i64); +121 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -427,7 +427,7 @@ error[E0308]: mismatched types | ^^^^ expected i64, found i8 help: you can cast an `i8` to `i64`, which will sign-extend the source value | -123 | foo::(x_i8 as i64); +123 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -436,7 +436,7 @@ error[E0308]: mismatched types 125 | foo::(x_f64); | ^^^^^ expected i64, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `i64`, rounding the float towards zero | 125 | foo::(x_f64 as i64); @@ -448,7 +448,7 @@ error[E0308]: mismatched types 128 | foo::(x_f32); | ^^^^^ expected i64, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `i64`, rounding the float towards zero | 128 | foo::(x_f32 as i64); @@ -481,7 +481,7 @@ error[E0308]: mismatched types | ^^^^^ expected u32, found u16 help: you can cast an `u16` to `u32`, which will zero-extend the source value | -137 | foo::(x_u16 as u32); +137 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -491,7 +491,7 @@ error[E0308]: mismatched types | ^^^^ expected u32, found u8 help: you can cast an `u8` to `u32`, which will zero-extend the source value | -139 | foo::(x_u8 as u32); +139 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -550,7 +550,7 @@ error[E0308]: mismatched types 151 | foo::(x_f64); | ^^^^^ expected u32, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `u32`, rounding the float towards zero | 151 | foo::(x_f64 as u32); @@ -562,7 +562,7 @@ error[E0308]: mismatched types 154 | foo::(x_f32); | ^^^^^ expected u32, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `u32`, rounding the float towards zero | 154 | foo::(x_f32 as u32); @@ -645,7 +645,7 @@ error[E0308]: mismatched types | ^^^^^ expected i32, found i16 help: you can cast an `i16` to `i32`, which will sign-extend the source value | -173 | foo::(x_i16 as i32); +173 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -655,7 +655,7 @@ error[E0308]: mismatched types | ^^^^ expected i32, found i8 help: you can cast an `i8` to `i32`, which will sign-extend the source value | -175 | foo::(x_i8 as i32); +175 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -664,7 +664,7 @@ error[E0308]: mismatched types 177 | foo::(x_f64); | ^^^^^ expected i32, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `i32`, rounding the float towards zero | 177 | foo::(x_f64 as i32); @@ -676,7 +676,7 @@ error[E0308]: mismatched types 180 | foo::(x_f32); | ^^^^^ expected i32, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `i32`, rounding the float towards zero | 180 | foo::(x_f32 as i32); @@ -719,7 +719,7 @@ error[E0308]: mismatched types | ^^^^ expected u16, found u8 help: you can cast an `u8` to `u16`, which will zero-extend the source value | -191 | foo::(x_u8 as u16); +191 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -778,7 +778,7 @@ error[E0308]: mismatched types 203 | foo::(x_f64); | ^^^^^ expected u16, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `u16`, rounding the float towards zero | 203 | foo::(x_f64 as u16); @@ -790,7 +790,7 @@ error[E0308]: mismatched types 206 | foo::(x_f32); | ^^^^^ expected u16, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `u16`, rounding the float towards zero | 206 | foo::(x_f32 as u16); @@ -883,7 +883,7 @@ error[E0308]: mismatched types | ^^^^ expected i16, found i8 help: you can cast an `i8` to `i16`, which will sign-extend the source value | -227 | foo::(x_i8 as i16); +227 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -892,7 +892,7 @@ error[E0308]: mismatched types 229 | foo::(x_f64); | ^^^^^ expected i16, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `i16`, rounding the float towards zero | 229 | foo::(x_f64 as i16); @@ -904,7 +904,7 @@ error[E0308]: mismatched types 232 | foo::(x_f32); | ^^^^^ expected i16, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `i16`, rounding the float towards zero | 232 | foo::(x_f32 as i16); @@ -1006,7 +1006,7 @@ error[E0308]: mismatched types 255 | foo::(x_f64); | ^^^^^ expected u8, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `u8`, rounding the float towards zero | 255 | foo::(x_f64 as u8); @@ -1018,7 +1018,7 @@ error[E0308]: mismatched types 258 | foo::(x_f32); | ^^^^^ expected u8, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `u8`, rounding the float towards zero | 258 | foo::(x_f32 as u8); @@ -1120,7 +1120,7 @@ error[E0308]: mismatched types 281 | foo::(x_f64); | ^^^^^ expected i8, found f64 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f64` to `i8`, rounding the float towards zero | 281 | foo::(x_f64 as i8); @@ -1132,7 +1132,7 @@ error[E0308]: mismatched types 284 | foo::(x_f32); | ^^^^^ expected i8, found f32 | - = warning: Currently this will cause Undefined Behavior if the rounded value cannot be represented by the target integer type. This includes `Inf` and `NaN`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) help: you can cast an `f32` to `i8`, rounding the float towards zero | 284 | foo::(x_f32 as i8); @@ -1165,7 +1165,7 @@ error[E0308]: mismatched types | ^^^^^ expected f64, found u32 help: you can cast an `u32` to `f64`, producing the floating point representation of the integer, rounded if necessary | -292 | foo::(x_u32 as f64); +292 | foo::(x_u32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1175,7 +1175,7 @@ error[E0308]: mismatched types | ^^^^^ expected f64, found u16 help: you can cast an `u16` to `f64`, producing the floating point representation of the integer, rounded if necessary | -294 | foo::(x_u16 as f64); +294 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1185,7 +1185,7 @@ error[E0308]: mismatched types | ^^^^ expected f64, found u8 help: you can cast an `u8` to `f64`, producing the floating point representation of the integer, rounded if necessary | -296 | foo::(x_u8 as f64); +296 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -1215,7 +1215,7 @@ error[E0308]: mismatched types | ^^^^^ expected f64, found i32 help: you can cast an `i32` to `f64`, producing the floating point representation of the integer, rounded if necessary | -302 | foo::(x_i32 as f64); +302 | foo::(x_i32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1225,7 +1225,7 @@ error[E0308]: mismatched types | ^^^^^ expected f64, found i16 help: you can cast an `i16` to `f64`, producing the floating point representation of the integer, rounded if necessary | -304 | foo::(x_i16 as f64); +304 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1235,7 +1235,7 @@ error[E0308]: mismatched types | ^^^^ expected f64, found i8 help: you can cast an `i8` to `f64`, producing the floating point representation of the integer, rounded if necessary | -306 | foo::(x_i8 as f64); +306 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -1245,7 +1245,7 @@ error[E0308]: mismatched types | ^^^^^ expected f64, found f32 help: you can cast an `f32` to `f64` in a lossless way | -309 | foo::(x_f32 as f64); +309 | foo::(x_f32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1285,7 +1285,7 @@ error[E0308]: mismatched types | ^^^^^ expected f32, found u16 help: you can cast an `u16` to `f32`, producing the floating point representation of the integer, rounded if necessary | -318 | foo::(x_u16 as f32); +318 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1295,7 +1295,7 @@ error[E0308]: mismatched types | ^^^^ expected f32, found u8 help: you can cast an `u8` to `f32`, producing the floating point representation of the integer, rounded if necessary | -320 | foo::(x_u8 as f32); +320 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -1335,7 +1335,7 @@ error[E0308]: mismatched types | ^^^^^ expected f32, found i16 help: you can cast an `i16` to `f32`, producing the floating point representation of the integer, rounded if necessary | -328 | foo::(x_i16 as f32); +328 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types @@ -1345,7 +1345,7 @@ error[E0308]: mismatched types | ^^^^ expected f32, found i8 help: you can cast an `i8` to `f32`, producing the floating point representation of the integer, rounded if necessary | -330 | foo::(x_i8 as f32); +330 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types @@ -1354,7 +1354,7 @@ error[E0308]: mismatched types 332 | foo::(x_f64); | ^^^^^ expected f32, found f64 | - = warning: Currently this will cause Undefined Behavior if the value is finite but larger or smaller than the largest or smallest finite value representable by `f32`. This is a bug and will be fixed. + = warning: casting here will cause undefined behavior if the value is finite but larger or smaller than the largest or smallest finite value representable by `f32` (this is a bug and will be fixed) help: you can cast an `f64` to `f32`, producing the closest possible value | 332 | foo::(x_f64 as f32); From 509ea8efc630d4e329dc2a440a2c0fc2a3fea236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 7 Jan 2018 12:51:33 -0800 Subject: [PATCH 3/6] Only suggest casting numeric types using `into()` --- src/librustc_typeck/check/demand.rs | 34 +- .../ui/mismatched_types/issue-26480.stderr | 4 - src/test/ui/suggestions/numeric-cast-2.rs | 4 +- src/test/ui/suggestions/numeric-cast-2.stderr | 22 +- src/test/ui/suggestions/numeric-cast.rs | 21 - src/test/ui/suggestions/numeric-cast.stderr | 1016 +++++------------ 6 files changed, 303 insertions(+), 798 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 42cca2bbb5ebb..dbda8a6e32bab 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -331,13 +331,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // We want to minimize the amount of casting operations that are suggested, as it can be a // lossy operation with potentially bad side effects, so we only suggest when encountering // an expression that indicates that the original type couldn't be directly changed. - let can_cast = match expr.node { - hir::ExprPath(..) | - hir::ExprCall(..) | - hir::ExprMethodCall(..) | - hir::ExprBinary(..) => true, - _ => false, - }; + // + // For now, don't suggest casting with `as`. + let can_cast = false; let needs_paren = match expr.node { hir::ExprBinary(..) => true, @@ -369,7 +365,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (None, _) | (_, None) => { if can_cast { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), + &format!("{}, which {}", + msg, + depending_on_isize), cast_suggestion); } } @@ -393,7 +391,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (None, _) | (_, None) => { if can_cast { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), + &format!("{}, which {}", + msg, + depending_on_usize), cast_suggestion); } } @@ -420,12 +420,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (None, _) => { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), + &format!("{}, which {}", + msg, + depending_on_isize), cast_suggestion); } (_, None) => { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), + &format!("{}, which {}", + msg, + depending_on_usize), cast_suggestion); } _ => { @@ -452,12 +456,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (None, _) => { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_usize), + &format!("{}, which {}", + msg, + depending_on_usize), cast_suggestion); } (_, None) => { err.span_suggestion(expr.span, - &format!("{}, which {}", msg, depending_on_isize), + &format!("{}, which {}", + msg, + depending_on_isize), cast_suggestion); } _ => { diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 0641e09b552e5..5d25cb2f93c15 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -6,10 +6,6 @@ error[E0308]: mismatched types ... 37 | write!(hello); | -------------- in this macro invocation -help: you can cast an `usize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` - | -26 | ($arr.len() * size_of($arr[0])) as u64); //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0605]: non-primitive cast: `{integer}` as `()` --> $DIR/issue-26480.rs:32:19 diff --git a/src/test/ui/suggestions/numeric-cast-2.rs b/src/test/ui/suggestions/numeric-cast-2.rs index 4c905a090a68c..2092b6bce37c1 100644 --- a/src/test/ui/suggestions/numeric-cast-2.rs +++ b/src/test/ui/suggestions/numeric-cast-2.rs @@ -12,7 +12,9 @@ fn foo() -> i32 { 4 } fn main() { - let x: u32 = foo(); + let x: u16 = foo(); + //~^ ERROR mismatched types + let y: i64 = x + x; //~^ ERROR mismatched types let z: i32 = x + x; //~^ ERROR mismatched types diff --git a/src/test/ui/suggestions/numeric-cast-2.stderr b/src/test/ui/suggestions/numeric-cast-2.stderr index 44703867b7547..90086d247d6e9 100644 --- a/src/test/ui/suggestions/numeric-cast-2.stderr +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -1,22 +1,20 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-2.rs:15:18 | -15 | let x: u32 = foo(); - | ^^^^^ expected u32, found i32 -help: you can cast an `i32` to `u32`, which will sign-extend the source value - | -15 | let x: u32 = foo() as u32; - | ^^^^^^^^^^^^ +15 | let x: u16 = foo(); + | ^^^^^ expected u16, found i32 error[E0308]: mismatched types --> $DIR/numeric-cast-2.rs:17:18 | -17 | let z: i32 = x + x; - | ^^^^^ expected i32, found u32 -help: you can cast an `u32` to `i32`, which will truncate the source value +17 | let y: i64 = x + x; + | ^^^^^ expected i64, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:19:18 | -17 | let z: i32 = (x + x) as i32; - | ^^^^^^^^^^^^^^ +19 | let z: i32 = x + x; + | ^^^^^ expected i32, found u16 -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/numeric-cast.rs b/src/test/ui/suggestions/numeric-cast.rs index cd5e183ede942..6e144037ec220 100644 --- a/src/test/ui/suggestions/numeric-cast.rs +++ b/src/test/ui/suggestions/numeric-cast.rs @@ -46,10 +46,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -72,10 +70,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -98,10 +94,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -124,10 +118,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -150,10 +142,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -176,10 +166,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -202,10 +190,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -228,10 +214,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -254,10 +238,8 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -280,10 +262,8 @@ fn main() { foo::(x_i8); foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_f32); //~^ ERROR mismatched types - //~| WARN casting here will cause Undefined Behavior foo::(x_usize); //~^ ERROR mismatched types @@ -331,6 +311,5 @@ fn main() { //~^ ERROR mismatched types foo::(x_f64); //~^ ERROR mismatched types - //~| WARN casting here will cause undefined behavior foo::(x_f32); } diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr index f074a3bc280a1..9c05dacf4ec78 100644 --- a/src/test/ui/suggestions/numeric-cast.stderr +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -3,1362 +3,884 @@ error[E0308]: mismatched types | 29 | foo::(x_u64); | ^^^^^ expected usize, found u64 -help: you can cast an `u64` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` - | -29 | foo::(x_u64 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:31:18 | 31 | foo::(x_u32); | ^^^^^ expected usize, found u32 -help: you can cast an `u32` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` - | -31 | foo::(x_u32 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:33:18 | 33 | foo::(x_u16); | ^^^^^ expected usize, found u16 -help: you can cast an `u16` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` - | -33 | foo::(x_u16 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:35:18 | 35 | foo::(x_u8); | ^^^^ expected usize, found u8 -help: you can cast an `u8` to `usize`, which will truncate or zero-extend depending on the bit width of `usize` - | -35 | foo::(x_u8 as usize); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:37:18 | 37 | foo::(x_isize); | ^^^^^^^ expected usize, found isize -help: you can cast an `isize` to `usize`, which will sign-extend the source value - | -37 | foo::(x_isize as usize); - | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:39:18 | 39 | foo::(x_i64); | ^^^^^ expected usize, found i64 -help: you can cast an `i64` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` - | -39 | foo::(x_i64 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:41:18 | 41 | foo::(x_i32); | ^^^^^ expected usize, found i32 -help: you can cast an `i32` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` - | -41 | foo::(x_i32 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:43:18 | 43 | foo::(x_i16); | ^^^^^ expected usize, found i16 -help: you can cast an `i16` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` - | -43 | foo::(x_i16 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:45:18 | 45 | foo::(x_i8); | ^^^^ expected usize, found i8 -help: you can cast an `i8` to `usize`, which will truncate or zero-extend depending on the bit width of `isize` - | -45 | foo::(x_i8 as usize); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:47:18 | 47 | foo::(x_f64); | ^^^^^ expected usize, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `usize`, rounding the float towards zero - | -47 | foo::(x_f64 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:50:18 + --> $DIR/numeric-cast.rs:49:18 | -50 | foo::(x_f32); +49 | foo::(x_f32); | ^^^^^ expected usize, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `usize`, rounding the float towards zero - | -50 | foo::(x_f32 as usize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:54:18 + --> $DIR/numeric-cast.rs:52:18 | -54 | foo::(x_usize); +52 | foo::(x_usize); | ^^^^^^^ expected isize, found usize -help: you can cast an `usize` to `isize`, which will truncate the source value - | -54 | foo::(x_usize as isize); - | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:56:18 + --> $DIR/numeric-cast.rs:54:18 | -56 | foo::(x_u64); +54 | foo::(x_u64); | ^^^^^ expected isize, found u64 -help: you can cast an `u64` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` - | -56 | foo::(x_u64 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:58:18 + --> $DIR/numeric-cast.rs:56:18 | -58 | foo::(x_u32); +56 | foo::(x_u32); | ^^^^^ expected isize, found u32 -help: you can cast an `u32` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` - | -58 | foo::(x_u32 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:60:18 + --> $DIR/numeric-cast.rs:58:18 | -60 | foo::(x_u16); +58 | foo::(x_u16); | ^^^^^ expected isize, found u16 -help: you can cast an `u16` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` - | -60 | foo::(x_u16 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:62:18 + --> $DIR/numeric-cast.rs:60:18 | -62 | foo::(x_u8); +60 | foo::(x_u8); | ^^^^ expected isize, found u8 -help: you can cast an `u8` to `isize`, which will truncate or zero-extend depending on the bit width of `usize` - | -62 | foo::(x_u8 as isize); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:65:18 + --> $DIR/numeric-cast.rs:63:18 | -65 | foo::(x_i64); +63 | foo::(x_i64); | ^^^^^ expected isize, found i64 -help: you can cast an `i64` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` - | -65 | foo::(x_i64 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:67:18 + --> $DIR/numeric-cast.rs:65:18 | -67 | foo::(x_i32); +65 | foo::(x_i32); | ^^^^^ expected isize, found i32 -help: you can cast an `i32` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` - | -67 | foo::(x_i32 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:69:18 + --> $DIR/numeric-cast.rs:67:18 | -69 | foo::(x_i16); +67 | foo::(x_i16); | ^^^^^ expected isize, found i16 -help: you can cast an `i16` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` - | -69 | foo::(x_i16 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:71:18 + --> $DIR/numeric-cast.rs:69:18 | -71 | foo::(x_i8); +69 | foo::(x_i8); | ^^^^ expected isize, found i8 -help: you can cast an `i8` to `isize`, which will truncate or zero-extend depending on the bit width of `isize` - | -71 | foo::(x_i8 as isize); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:73:18 + --> $DIR/numeric-cast.rs:71:18 | -73 | foo::(x_f64); +71 | foo::(x_f64); | ^^^^^ expected isize, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `isize`, rounding the float towards zero - | -73 | foo::(x_f64 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:76:18 + --> $DIR/numeric-cast.rs:73:18 | -76 | foo::(x_f32); +73 | foo::(x_f32); | ^^^^^ expected isize, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `isize`, rounding the float towards zero - | -76 | foo::(x_f32 as isize); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:80:16 + --> $DIR/numeric-cast.rs:76:16 | -80 | foo::(x_usize); +76 | foo::(x_usize); | ^^^^^^^ expected u64, found usize -help: you can cast an `usize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` - | -80 | foo::(x_usize as u64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:83:16 + --> $DIR/numeric-cast.rs:79:16 | -83 | foo::(x_u32); +79 | foo::(x_u32); | ^^^^^ expected u64, found u32 help: you can cast an `u32` to `u64`, which will zero-extend the source value | -83 | foo::(x_u32.into()); +79 | foo::(x_u32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:85:16 + --> $DIR/numeric-cast.rs:81:16 | -85 | foo::(x_u16); +81 | foo::(x_u16); | ^^^^^ expected u64, found u16 help: you can cast an `u16` to `u64`, which will zero-extend the source value | -85 | foo::(x_u16.into()); +81 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:87:16 + --> $DIR/numeric-cast.rs:83:16 | -87 | foo::(x_u8); +83 | foo::(x_u8); | ^^^^ expected u64, found u8 help: you can cast an `u8` to `u64`, which will zero-extend the source value | -87 | foo::(x_u8.into()); +83 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:89:16 + --> $DIR/numeric-cast.rs:85:16 | -89 | foo::(x_isize); +85 | foo::(x_isize); | ^^^^^^^ expected u64, found isize -help: you can cast an `isize` to `u64`, which will truncate or zero-extend depending on the bit width of `usize` - | -89 | foo::(x_isize as u64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:91:16 + --> $DIR/numeric-cast.rs:87:16 | -91 | foo::(x_i64); +87 | foo::(x_i64); | ^^^^^ expected u64, found i64 -help: you can cast an `i64` to `u64`, which will sign-extend the source value - | -91 | foo::(x_i64 as u64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:93:16 + --> $DIR/numeric-cast.rs:89:16 | -93 | foo::(x_i32); +89 | foo::(x_i32); | ^^^^^ expected u64, found i32 -help: you can cast an `i32` to `u64`, which will sign-extend the source value - | -93 | foo::(x_i32 as u64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:95:16 + --> $DIR/numeric-cast.rs:91:16 | -95 | foo::(x_i16); +91 | foo::(x_i16); | ^^^^^ expected u64, found i16 -help: you can cast an `i16` to `u64`, which will sign-extend the source value - | -95 | foo::(x_i16 as u64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:97:16 + --> $DIR/numeric-cast.rs:93:16 | -97 | foo::(x_i8); +93 | foo::(x_i8); | ^^^^ expected u64, found i8 -help: you can cast an `i8` to `u64`, which will sign-extend the source value - | -97 | foo::(x_i8 as u64); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:99:16 + --> $DIR/numeric-cast.rs:95:16 | -99 | foo::(x_f64); +95 | foo::(x_f64); | ^^^^^ expected u64, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `u64`, rounding the float towards zero - | -99 | foo::(x_f64 as u64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:102:16 - | -102 | foo::(x_f32); - | ^^^^^ expected u64, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `u64`, rounding the float towards zero - | -102 | foo::(x_f32 as u64); - | ^^^^^^^^^^^^ + --> $DIR/numeric-cast.rs:97:16 + | +97 | foo::(x_f32); + | ^^^^^ expected u64, found f32 error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:106:16 + --> $DIR/numeric-cast.rs:100:16 | -106 | foo::(x_usize); +100 | foo::(x_usize); | ^^^^^^^ expected i64, found usize -help: you can cast an `usize` to `i64`, which will truncate or zero-extend depending on the bit width of `isize` - | -106 | foo::(x_usize as i64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:108:16 + --> $DIR/numeric-cast.rs:102:16 | -108 | foo::(x_u64); +102 | foo::(x_u64); | ^^^^^ expected i64, found u64 -help: you can cast an `u64` to `i64`, which will truncate the source value - | -108 | foo::(x_u64 as i64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:110:16 + --> $DIR/numeric-cast.rs:104:16 | -110 | foo::(x_u32); +104 | foo::(x_u32); | ^^^^^ expected i64, found u32 -help: you can cast an `u32` to `i64`, which will zero-extend the source value - | -110 | foo::(x_u32 as i64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:112:16 + --> $DIR/numeric-cast.rs:106:16 | -112 | foo::(x_u16); +106 | foo::(x_u16); | ^^^^^ expected i64, found u16 -help: you can cast an `u16` to `i64`, which will zero-extend the source value - | -112 | foo::(x_u16 as i64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:114:16 + --> $DIR/numeric-cast.rs:108:16 | -114 | foo::(x_u8); +108 | foo::(x_u8); | ^^^^ expected i64, found u8 -help: you can cast an `u8` to `i64`, which will zero-extend the source value - | -114 | foo::(x_u8 as i64); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:116:16 + --> $DIR/numeric-cast.rs:110:16 | -116 | foo::(x_isize); +110 | foo::(x_isize); | ^^^^^^^ expected i64, found isize -help: you can cast an `isize` to `i64`, which will truncate or zero-extend depending on the bit width of `isize` - | -116 | foo::(x_isize as i64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:119:16 + --> $DIR/numeric-cast.rs:113:16 | -119 | foo::(x_i32); +113 | foo::(x_i32); | ^^^^^ expected i64, found i32 help: you can cast an `i32` to `i64`, which will sign-extend the source value | -119 | foo::(x_i32.into()); +113 | foo::(x_i32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:121:16 + --> $DIR/numeric-cast.rs:115:16 | -121 | foo::(x_i16); +115 | foo::(x_i16); | ^^^^^ expected i64, found i16 help: you can cast an `i16` to `i64`, which will sign-extend the source value | -121 | foo::(x_i16.into()); +115 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:123:16 + --> $DIR/numeric-cast.rs:117:16 | -123 | foo::(x_i8); +117 | foo::(x_i8); | ^^^^ expected i64, found i8 help: you can cast an `i8` to `i64`, which will sign-extend the source value | -123 | foo::(x_i8.into()); +117 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:125:16 + --> $DIR/numeric-cast.rs:119:16 | -125 | foo::(x_f64); +119 | foo::(x_f64); | ^^^^^ expected i64, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `i64`, rounding the float towards zero - | -125 | foo::(x_f64 as i64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:128:16 + --> $DIR/numeric-cast.rs:121:16 | -128 | foo::(x_f32); +121 | foo::(x_f32); | ^^^^^ expected i64, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `i64`, rounding the float towards zero - | -128 | foo::(x_f32 as i64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:132:16 + --> $DIR/numeric-cast.rs:124:16 | -132 | foo::(x_usize); +124 | foo::(x_usize); | ^^^^^^^ expected u32, found usize -help: you can cast an `usize` to `u32`, which will truncate or zero-extend depending on the bit width of `usize` - | -132 | foo::(x_usize as u32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:134:16 + --> $DIR/numeric-cast.rs:126:16 | -134 | foo::(x_u64); +126 | foo::(x_u64); | ^^^^^ expected u32, found u64 -help: you can cast an `u64` to `u32`, which will truncate the source value - | -134 | foo::(x_u64 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:137:16 + --> $DIR/numeric-cast.rs:129:16 | -137 | foo::(x_u16); +129 | foo::(x_u16); | ^^^^^ expected u32, found u16 help: you can cast an `u16` to `u32`, which will zero-extend the source value | -137 | foo::(x_u16.into()); +129 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:139:16 + --> $DIR/numeric-cast.rs:131:16 | -139 | foo::(x_u8); +131 | foo::(x_u8); | ^^^^ expected u32, found u8 help: you can cast an `u8` to `u32`, which will zero-extend the source value | -139 | foo::(x_u8.into()); +131 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:141:16 + --> $DIR/numeric-cast.rs:133:16 | -141 | foo::(x_isize); +133 | foo::(x_isize); | ^^^^^^^ expected u32, found isize -help: you can cast an `isize` to `u32`, which will truncate or zero-extend depending on the bit width of `usize` - | -141 | foo::(x_isize as u32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:143:16 + --> $DIR/numeric-cast.rs:135:16 | -143 | foo::(x_i64); +135 | foo::(x_i64); | ^^^^^ expected u32, found i64 -help: you can cast an `i64` to `u32`, which will truncate the source value - | -143 | foo::(x_i64 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:145:16 + --> $DIR/numeric-cast.rs:137:16 | -145 | foo::(x_i32); +137 | foo::(x_i32); | ^^^^^ expected u32, found i32 -help: you can cast an `i32` to `u32`, which will sign-extend the source value - | -145 | foo::(x_i32 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:147:16 + --> $DIR/numeric-cast.rs:139:16 | -147 | foo::(x_i16); +139 | foo::(x_i16); | ^^^^^ expected u32, found i16 -help: you can cast an `i16` to `u32`, which will sign-extend the source value - | -147 | foo::(x_i16 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:149:16 + --> $DIR/numeric-cast.rs:141:16 | -149 | foo::(x_i8); +141 | foo::(x_i8); | ^^^^ expected u32, found i8 -help: you can cast an `i8` to `u32`, which will sign-extend the source value - | -149 | foo::(x_i8 as u32); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:151:16 + --> $DIR/numeric-cast.rs:143:16 | -151 | foo::(x_f64); +143 | foo::(x_f64); | ^^^^^ expected u32, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `u32`, rounding the float towards zero - | -151 | foo::(x_f64 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:154:16 + --> $DIR/numeric-cast.rs:145:16 | -154 | foo::(x_f32); +145 | foo::(x_f32); | ^^^^^ expected u32, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `u32`, rounding the float towards zero - | -154 | foo::(x_f32 as u32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:158:16 + --> $DIR/numeric-cast.rs:148:16 | -158 | foo::(x_usize); +148 | foo::(x_usize); | ^^^^^^^ expected i32, found usize -help: you can cast an `usize` to `i32`, which will truncate or zero-extend depending on the bit width of `isize` - | -158 | foo::(x_usize as i32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:160:16 + --> $DIR/numeric-cast.rs:150:16 | -160 | foo::(x_u64); +150 | foo::(x_u64); | ^^^^^ expected i32, found u64 -help: you can cast an `u64` to `i32`, which will truncate the source value - | -160 | foo::(x_u64 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:162:16 + --> $DIR/numeric-cast.rs:152:16 | -162 | foo::(x_u32); +152 | foo::(x_u32); | ^^^^^ expected i32, found u32 -help: you can cast an `u32` to `i32`, which will truncate the source value - | -162 | foo::(x_u32 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:164:16 + --> $DIR/numeric-cast.rs:154:16 | -164 | foo::(x_u16); +154 | foo::(x_u16); | ^^^^^ expected i32, found u16 -help: you can cast an `u16` to `i32`, which will zero-extend the source value - | -164 | foo::(x_u16 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:166:16 + --> $DIR/numeric-cast.rs:156:16 | -166 | foo::(x_u8); +156 | foo::(x_u8); | ^^^^ expected i32, found u8 -help: you can cast an `u8` to `i32`, which will zero-extend the source value - | -166 | foo::(x_u8 as i32); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:168:16 + --> $DIR/numeric-cast.rs:158:16 | -168 | foo::(x_isize); +158 | foo::(x_isize); | ^^^^^^^ expected i32, found isize -help: you can cast an `isize` to `i32`, which will truncate or zero-extend depending on the bit width of `isize` - | -168 | foo::(x_isize as i32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:170:16 + --> $DIR/numeric-cast.rs:160:16 | -170 | foo::(x_i64); +160 | foo::(x_i64); | ^^^^^ expected i32, found i64 -help: you can cast an `i64` to `i32`, which will truncate the source value - | -170 | foo::(x_i64 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:173:16 + --> $DIR/numeric-cast.rs:163:16 | -173 | foo::(x_i16); +163 | foo::(x_i16); | ^^^^^ expected i32, found i16 help: you can cast an `i16` to `i32`, which will sign-extend the source value | -173 | foo::(x_i16.into()); +163 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:175:16 + --> $DIR/numeric-cast.rs:165:16 | -175 | foo::(x_i8); +165 | foo::(x_i8); | ^^^^ expected i32, found i8 help: you can cast an `i8` to `i32`, which will sign-extend the source value | -175 | foo::(x_i8.into()); +165 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:177:16 + --> $DIR/numeric-cast.rs:167:16 | -177 | foo::(x_f64); +167 | foo::(x_f64); | ^^^^^ expected i32, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `i32`, rounding the float towards zero - | -177 | foo::(x_f64 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:180:16 + --> $DIR/numeric-cast.rs:169:16 | -180 | foo::(x_f32); +169 | foo::(x_f32); | ^^^^^ expected i32, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `i32`, rounding the float towards zero - | -180 | foo::(x_f32 as i32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:184:16 + --> $DIR/numeric-cast.rs:172:16 | -184 | foo::(x_usize); +172 | foo::(x_usize); | ^^^^^^^ expected u16, found usize -help: you can cast an `usize` to `u16`, which will truncate or zero-extend depending on the bit width of `usize` - | -184 | foo::(x_usize as u16); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:186:16 + --> $DIR/numeric-cast.rs:174:16 | -186 | foo::(x_u64); +174 | foo::(x_u64); | ^^^^^ expected u16, found u64 -help: you can cast an `u64` to `u16`, which will truncate the source value - | -186 | foo::(x_u64 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:188:16 + --> $DIR/numeric-cast.rs:176:16 | -188 | foo::(x_u32); +176 | foo::(x_u32); | ^^^^^ expected u16, found u32 -help: you can cast an `u32` to `u16`, which will truncate the source value - | -188 | foo::(x_u32 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:191:16 + --> $DIR/numeric-cast.rs:179:16 | -191 | foo::(x_u8); +179 | foo::(x_u8); | ^^^^ expected u16, found u8 help: you can cast an `u8` to `u16`, which will zero-extend the source value | -191 | foo::(x_u8.into()); +179 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:193:16 + --> $DIR/numeric-cast.rs:181:16 | -193 | foo::(x_isize); +181 | foo::(x_isize); | ^^^^^^^ expected u16, found isize -help: you can cast an `isize` to `u16`, which will truncate or zero-extend depending on the bit width of `usize` - | -193 | foo::(x_isize as u16); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:195:16 + --> $DIR/numeric-cast.rs:183:16 | -195 | foo::(x_i64); +183 | foo::(x_i64); | ^^^^^ expected u16, found i64 -help: you can cast an `i64` to `u16`, which will truncate the source value - | -195 | foo::(x_i64 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:197:16 + --> $DIR/numeric-cast.rs:185:16 | -197 | foo::(x_i32); +185 | foo::(x_i32); | ^^^^^ expected u16, found i32 -help: you can cast an `i32` to `u16`, which will truncate the source value - | -197 | foo::(x_i32 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:199:16 + --> $DIR/numeric-cast.rs:187:16 | -199 | foo::(x_i16); +187 | foo::(x_i16); | ^^^^^ expected u16, found i16 -help: you can cast an `i16` to `u16`, which will sign-extend the source value - | -199 | foo::(x_i16 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:201:16 + --> $DIR/numeric-cast.rs:189:16 | -201 | foo::(x_i8); +189 | foo::(x_i8); | ^^^^ expected u16, found i8 -help: you can cast an `i8` to `u16`, which will sign-extend the source value - | -201 | foo::(x_i8 as u16); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:203:16 + --> $DIR/numeric-cast.rs:191:16 | -203 | foo::(x_f64); +191 | foo::(x_f64); | ^^^^^ expected u16, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `u16`, rounding the float towards zero - | -203 | foo::(x_f64 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:206:16 + --> $DIR/numeric-cast.rs:193:16 | -206 | foo::(x_f32); +193 | foo::(x_f32); | ^^^^^ expected u16, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `u16`, rounding the float towards zero - | -206 | foo::(x_f32 as u16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:210:16 + --> $DIR/numeric-cast.rs:196:16 | -210 | foo::(x_usize); +196 | foo::(x_usize); | ^^^^^^^ expected i16, found usize -help: you can cast an `usize` to `i16`, which will truncate or zero-extend depending on the bit width of `isize` - | -210 | foo::(x_usize as i16); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:212:16 + --> $DIR/numeric-cast.rs:198:16 | -212 | foo::(x_u64); +198 | foo::(x_u64); | ^^^^^ expected i16, found u64 -help: you can cast an `u64` to `i16`, which will truncate the source value - | -212 | foo::(x_u64 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:214:16 + --> $DIR/numeric-cast.rs:200:16 | -214 | foo::(x_u32); +200 | foo::(x_u32); | ^^^^^ expected i16, found u32 -help: you can cast an `u32` to `i16`, which will truncate the source value - | -214 | foo::(x_u32 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:216:16 + --> $DIR/numeric-cast.rs:202:16 | -216 | foo::(x_u16); +202 | foo::(x_u16); | ^^^^^ expected i16, found u16 -help: you can cast an `u16` to `i16`, which will truncate the source value - | -216 | foo::(x_u16 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:218:16 + --> $DIR/numeric-cast.rs:204:16 | -218 | foo::(x_u8); +204 | foo::(x_u8); | ^^^^ expected i16, found u8 -help: you can cast an `u8` to `i16`, which will zero-extend the source value - | -218 | foo::(x_u8 as i16); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:220:16 + --> $DIR/numeric-cast.rs:206:16 | -220 | foo::(x_isize); +206 | foo::(x_isize); | ^^^^^^^ expected i16, found isize -help: you can cast an `isize` to `i16`, which will truncate or zero-extend depending on the bit width of `isize` - | -220 | foo::(x_isize as i16); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:222:16 + --> $DIR/numeric-cast.rs:208:16 | -222 | foo::(x_i64); +208 | foo::(x_i64); | ^^^^^ expected i16, found i64 -help: you can cast an `i64` to `i16`, which will truncate the source value - | -222 | foo::(x_i64 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:224:16 + --> $DIR/numeric-cast.rs:210:16 | -224 | foo::(x_i32); +210 | foo::(x_i32); | ^^^^^ expected i16, found i32 -help: you can cast an `i32` to `i16`, which will truncate the source value - | -224 | foo::(x_i32 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:227:16 + --> $DIR/numeric-cast.rs:213:16 | -227 | foo::(x_i8); +213 | foo::(x_i8); | ^^^^ expected i16, found i8 help: you can cast an `i8` to `i16`, which will sign-extend the source value | -227 | foo::(x_i8.into()); +213 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:229:16 + --> $DIR/numeric-cast.rs:215:16 | -229 | foo::(x_f64); +215 | foo::(x_f64); | ^^^^^ expected i16, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `i16`, rounding the float towards zero - | -229 | foo::(x_f64 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:232:16 + --> $DIR/numeric-cast.rs:217:16 | -232 | foo::(x_f32); +217 | foo::(x_f32); | ^^^^^ expected i16, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `i16`, rounding the float towards zero - | -232 | foo::(x_f32 as i16); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:236:15 + --> $DIR/numeric-cast.rs:220:15 | -236 | foo::(x_usize); +220 | foo::(x_usize); | ^^^^^^^ expected u8, found usize -help: you can cast an `usize` to `u8`, which will truncate or zero-extend depending on the bit width of `usize` - | -236 | foo::(x_usize as u8); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:238:15 + --> $DIR/numeric-cast.rs:222:15 | -238 | foo::(x_u64); +222 | foo::(x_u64); | ^^^^^ expected u8, found u64 -help: you can cast an `u64` to `u8`, which will truncate the source value - | -238 | foo::(x_u64 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:240:15 + --> $DIR/numeric-cast.rs:224:15 | -240 | foo::(x_u32); +224 | foo::(x_u32); | ^^^^^ expected u8, found u32 -help: you can cast an `u32` to `u8`, which will truncate the source value - | -240 | foo::(x_u32 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:242:15 + --> $DIR/numeric-cast.rs:226:15 | -242 | foo::(x_u16); +226 | foo::(x_u16); | ^^^^^ expected u8, found u16 -help: you can cast an `u16` to `u8`, which will truncate the source value - | -242 | foo::(x_u16 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:245:15 + --> $DIR/numeric-cast.rs:229:15 | -245 | foo::(x_isize); +229 | foo::(x_isize); | ^^^^^^^ expected u8, found isize -help: you can cast an `isize` to `u8`, which will truncate or zero-extend depending on the bit width of `usize` - | -245 | foo::(x_isize as u8); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:247:15 + --> $DIR/numeric-cast.rs:231:15 | -247 | foo::(x_i64); +231 | foo::(x_i64); | ^^^^^ expected u8, found i64 -help: you can cast an `i64` to `u8`, which will truncate the source value - | -247 | foo::(x_i64 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:249:15 + --> $DIR/numeric-cast.rs:233:15 | -249 | foo::(x_i32); +233 | foo::(x_i32); | ^^^^^ expected u8, found i32 -help: you can cast an `i32` to `u8`, which will truncate the source value - | -249 | foo::(x_i32 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:251:15 + --> $DIR/numeric-cast.rs:235:15 | -251 | foo::(x_i16); +235 | foo::(x_i16); | ^^^^^ expected u8, found i16 -help: you can cast an `i16` to `u8`, which will truncate the source value - | -251 | foo::(x_i16 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:253:15 + --> $DIR/numeric-cast.rs:237:15 | -253 | foo::(x_i8); +237 | foo::(x_i8); | ^^^^ expected u8, found i8 -help: you can cast an `i8` to `u8`, which will sign-extend the source value - | -253 | foo::(x_i8 as u8); - | ^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:255:15 + --> $DIR/numeric-cast.rs:239:15 | -255 | foo::(x_f64); +239 | foo::(x_f64); | ^^^^^ expected u8, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `u8`, rounding the float towards zero - | -255 | foo::(x_f64 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:258:15 + --> $DIR/numeric-cast.rs:241:15 | -258 | foo::(x_f32); +241 | foo::(x_f32); | ^^^^^ expected u8, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `u8`, rounding the float towards zero - | -258 | foo::(x_f32 as u8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:262:15 + --> $DIR/numeric-cast.rs:244:15 | -262 | foo::(x_usize); +244 | foo::(x_usize); | ^^^^^^^ expected i8, found usize -help: you can cast an `usize` to `i8`, which will truncate or zero-extend depending on the bit width of `isize` - | -262 | foo::(x_usize as i8); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:264:15 + --> $DIR/numeric-cast.rs:246:15 | -264 | foo::(x_u64); +246 | foo::(x_u64); | ^^^^^ expected i8, found u64 -help: you can cast an `u64` to `i8`, which will truncate the source value - | -264 | foo::(x_u64 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:266:15 + --> $DIR/numeric-cast.rs:248:15 | -266 | foo::(x_u32); +248 | foo::(x_u32); | ^^^^^ expected i8, found u32 -help: you can cast an `u32` to `i8`, which will truncate the source value - | -266 | foo::(x_u32 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:268:15 + --> $DIR/numeric-cast.rs:250:15 | -268 | foo::(x_u16); +250 | foo::(x_u16); | ^^^^^ expected i8, found u16 -help: you can cast an `u16` to `i8`, which will truncate the source value - | -268 | foo::(x_u16 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:270:15 + --> $DIR/numeric-cast.rs:252:15 | -270 | foo::(x_u8); +252 | foo::(x_u8); | ^^^^ expected i8, found u8 -help: you can cast an `u8` to `i8`, which will truncate the source value - | -270 | foo::(x_u8 as i8); - | ^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:272:15 + --> $DIR/numeric-cast.rs:254:15 | -272 | foo::(x_isize); +254 | foo::(x_isize); | ^^^^^^^ expected i8, found isize -help: you can cast an `isize` to `i8`, which will truncate or zero-extend depending on the bit width of `isize` - | -272 | foo::(x_isize as i8); - | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:274:15 + --> $DIR/numeric-cast.rs:256:15 | -274 | foo::(x_i64); +256 | foo::(x_i64); | ^^^^^ expected i8, found i64 -help: you can cast an `i64` to `i8`, which will truncate the source value - | -274 | foo::(x_i64 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:276:15 + --> $DIR/numeric-cast.rs:258:15 | -276 | foo::(x_i32); +258 | foo::(x_i32); | ^^^^^ expected i8, found i32 -help: you can cast an `i32` to `i8`, which will truncate the source value - | -276 | foo::(x_i32 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:278:15 + --> $DIR/numeric-cast.rs:260:15 | -278 | foo::(x_i16); +260 | foo::(x_i16); | ^^^^^ expected i8, found i16 -help: you can cast an `i16` to `i8`, which will truncate the source value - | -278 | foo::(x_i16 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:281:15 + --> $DIR/numeric-cast.rs:263:15 | -281 | foo::(x_f64); +263 | foo::(x_f64); | ^^^^^ expected i8, found f64 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f64` to `i8`, rounding the float towards zero - | -281 | foo::(x_f64 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:284:15 + --> $DIR/numeric-cast.rs:265:15 | -284 | foo::(x_f32); +265 | foo::(x_f32); | ^^^^^ expected i8, found f32 - | - = warning: casting here will cause undefined behavior if the rounded value cannot be represented by the target integer type, including `Inf` and `NaN` (this is a bug and will be fixed) -help: you can cast an `f32` to `i8`, rounding the float towards zero - | -284 | foo::(x_f32 as i8); - | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:288:16 + --> $DIR/numeric-cast.rs:268:16 | -288 | foo::(x_usize); +268 | foo::(x_usize); | ^^^^^^^ expected f64, found usize -help: you can cast an `usize` to `f64`, producing the floating point representation of the integer, rounded if necessary - | -288 | foo::(x_usize as f64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:290:16 + --> $DIR/numeric-cast.rs:270:16 | -290 | foo::(x_u64); +270 | foo::(x_u64); | ^^^^^ expected f64, found u64 -help: you can cast an `u64` to `f64`, producing the floating point representation of the integer, rounded if necessary - | -290 | foo::(x_u64 as f64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:292:16 + --> $DIR/numeric-cast.rs:272:16 | -292 | foo::(x_u32); +272 | foo::(x_u32); | ^^^^^ expected f64, found u32 help: you can cast an `u32` to `f64`, producing the floating point representation of the integer, rounded if necessary | -292 | foo::(x_u32.into()); +272 | foo::(x_u32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:294:16 + --> $DIR/numeric-cast.rs:274:16 | -294 | foo::(x_u16); +274 | foo::(x_u16); | ^^^^^ expected f64, found u16 help: you can cast an `u16` to `f64`, producing the floating point representation of the integer, rounded if necessary | -294 | foo::(x_u16.into()); +274 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:296:16 + --> $DIR/numeric-cast.rs:276:16 | -296 | foo::(x_u8); +276 | foo::(x_u8); | ^^^^ expected f64, found u8 help: you can cast an `u8` to `f64`, producing the floating point representation of the integer, rounded if necessary | -296 | foo::(x_u8.into()); +276 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:298:16 + --> $DIR/numeric-cast.rs:278:16 | -298 | foo::(x_isize); +278 | foo::(x_isize); | ^^^^^^^ expected f64, found isize -help: you can cast an `isize` to `f64`, producing the floating point representation of the integer, rounded if necessary - | -298 | foo::(x_isize as f64); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:300:16 + --> $DIR/numeric-cast.rs:280:16 | -300 | foo::(x_i64); +280 | foo::(x_i64); | ^^^^^ expected f64, found i64 -help: you can cast an `i64` to `f64`, producing the floating point representation of the integer, rounded if necessary - | -300 | foo::(x_i64 as f64); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:302:16 + --> $DIR/numeric-cast.rs:282:16 | -302 | foo::(x_i32); +282 | foo::(x_i32); | ^^^^^ expected f64, found i32 help: you can cast an `i32` to `f64`, producing the floating point representation of the integer, rounded if necessary | -302 | foo::(x_i32.into()); +282 | foo::(x_i32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:304:16 + --> $DIR/numeric-cast.rs:284:16 | -304 | foo::(x_i16); +284 | foo::(x_i16); | ^^^^^ expected f64, found i16 help: you can cast an `i16` to `f64`, producing the floating point representation of the integer, rounded if necessary | -304 | foo::(x_i16.into()); +284 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:306:16 + --> $DIR/numeric-cast.rs:286:16 | -306 | foo::(x_i8); +286 | foo::(x_i8); | ^^^^ expected f64, found i8 help: you can cast an `i8` to `f64`, producing the floating point representation of the integer, rounded if necessary | -306 | foo::(x_i8.into()); +286 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:309:16 + --> $DIR/numeric-cast.rs:289:16 | -309 | foo::(x_f32); +289 | foo::(x_f32); | ^^^^^ expected f64, found f32 help: you can cast an `f32` to `f64` in a lossless way | -309 | foo::(x_f32.into()); +289 | foo::(x_f32.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:312:16 + --> $DIR/numeric-cast.rs:292:16 | -312 | foo::(x_usize); +292 | foo::(x_usize); | ^^^^^^^ expected f32, found usize -help: you can cast an `usize` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -312 | foo::(x_usize as f32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:314:16 + --> $DIR/numeric-cast.rs:294:16 | -314 | foo::(x_u64); +294 | foo::(x_u64); | ^^^^^ expected f32, found u64 -help: you can cast an `u64` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -314 | foo::(x_u64 as f32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:316:16 + --> $DIR/numeric-cast.rs:296:16 | -316 | foo::(x_u32); +296 | foo::(x_u32); | ^^^^^ expected f32, found u32 -help: you can cast an `u32` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -316 | foo::(x_u32 as f32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:318:16 + --> $DIR/numeric-cast.rs:298:16 | -318 | foo::(x_u16); +298 | foo::(x_u16); | ^^^^^ expected f32, found u16 help: you can cast an `u16` to `f32`, producing the floating point representation of the integer, rounded if necessary | -318 | foo::(x_u16.into()); +298 | foo::(x_u16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:320:16 + --> $DIR/numeric-cast.rs:300:16 | -320 | foo::(x_u8); +300 | foo::(x_u8); | ^^^^ expected f32, found u8 help: you can cast an `u8` to `f32`, producing the floating point representation of the integer, rounded if necessary | -320 | foo::(x_u8.into()); +300 | foo::(x_u8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:322:16 + --> $DIR/numeric-cast.rs:302:16 | -322 | foo::(x_isize); +302 | foo::(x_isize); | ^^^^^^^ expected f32, found isize -help: you can cast an `isize` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -322 | foo::(x_isize as f32); - | ^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:324:16 + --> $DIR/numeric-cast.rs:304:16 | -324 | foo::(x_i64); +304 | foo::(x_i64); | ^^^^^ expected f32, found i64 -help: you can cast an `i64` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -324 | foo::(x_i64 as f32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:326:16 + --> $DIR/numeric-cast.rs:306:16 | -326 | foo::(x_i32); +306 | foo::(x_i32); | ^^^^^ expected f32, found i32 -help: you can cast an `i32` to `f32`, producing the floating point representation of the integer, rounded if necessary - | -326 | foo::(x_i32 as f32); - | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:328:16 + --> $DIR/numeric-cast.rs:308:16 | -328 | foo::(x_i16); +308 | foo::(x_i16); | ^^^^^ expected f32, found i16 help: you can cast an `i16` to `f32`, producing the floating point representation of the integer, rounded if necessary | -328 | foo::(x_i16.into()); +308 | foo::(x_i16.into()); | ^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:330:16 + --> $DIR/numeric-cast.rs:310:16 | -330 | foo::(x_i8); +310 | foo::(x_i8); | ^^^^ expected f32, found i8 help: you can cast an `i8` to `f32`, producing the floating point representation of the integer, rounded if necessary | -330 | foo::(x_i8.into()); +310 | foo::(x_i8.into()); | ^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/numeric-cast.rs:332:16 + --> $DIR/numeric-cast.rs:312:16 | -332 | foo::(x_f64); +312 | foo::(x_f64); | ^^^^^ expected f32, found f64 - | - = warning: casting here will cause undefined behavior if the value is finite but larger or smaller than the largest or smallest finite value representable by `f32` (this is a bug and will be fixed) -help: you can cast an `f64` to `f32`, producing the closest possible value - | -332 | foo::(x_f64 as f32); - | ^^^^^^^^^^^^ error: aborting due to 132 previous errors From 09efaaf0764ddfd366bf6627533ecd1ea6ffb234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 9 Jan 2018 18:41:24 -0800 Subject: [PATCH 4/6] Use `s::u::p::expr_precedence` and fix message - Use `syntax::util::parser::expr_precedence` to determine wether parenthesis are needed around the casting target. - Update message to not incorrectly mention rounding on `.into()` suggestions, as those types that do have that implemented will never round. --- src/librustc_typeck/check/demand.rs | 14 ++++++-------- src/test/ui/suggestions/numeric-cast.stderr | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index dbda8a6e32bab..d43d681c92595 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -15,6 +15,7 @@ use rustc::infer::InferOk; use rustc::traits::ObligationCause; use syntax::ast; +use syntax::util::parser::{expr_precedence, AssocOp}; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::print; @@ -335,10 +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 = match expr.node { - hir::ExprBinary(..) => true, - _ => false, - }; + let needs_paren = expr_precedence(expr) < (AssocOp::As.precedence() 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); @@ -508,11 +506,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { true } (&ty::TyFloat(ref exp), &ty::TyUint(ref found)) => { + // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { err.span_suggestion(expr.span, &format!("{}, producing the floating point \ - representation of the integer, rounded if \ - necessary", + representation of the integer", msg), into_suggestion); } else if can_cast { @@ -526,11 +524,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { true } (&ty::TyFloat(ref exp), &ty::TyInt(ref found)) => { + // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` if exp.bit_width() > found.bit_width().unwrap_or(256) { err.span_suggestion(expr.span, &format!("{}, producing the floating point \ - representation of the integer, rounded if \ - necessary", + representation of the integer", msg), into_suggestion); } else if can_cast { diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr index 9c05dacf4ec78..0ce3d087f3509 100644 --- a/src/test/ui/suggestions/numeric-cast.stderr +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -723,7 +723,7 @@ error[E0308]: mismatched types | 272 | foo::(x_u32); | ^^^^^ expected f64, found u32 -help: you can cast an `u32` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `u32` to `f64`, producing the floating point representation of the integer | 272 | foo::(x_u32.into()); | ^^^^^^^^^^^^ @@ -733,7 +733,7 @@ error[E0308]: mismatched types | 274 | foo::(x_u16); | ^^^^^ expected f64, found u16 -help: you can cast an `u16` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `u16` to `f64`, producing the floating point representation of the integer | 274 | foo::(x_u16.into()); | ^^^^^^^^^^^^ @@ -743,7 +743,7 @@ error[E0308]: mismatched types | 276 | foo::(x_u8); | ^^^^ expected f64, found u8 -help: you can cast an `u8` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `u8` to `f64`, producing the floating point representation of the integer | 276 | foo::(x_u8.into()); | ^^^^^^^^^^^ @@ -765,7 +765,7 @@ error[E0308]: mismatched types | 282 | foo::(x_i32); | ^^^^^ expected f64, found i32 -help: you can cast an `i32` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `i32` to `f64`, producing the floating point representation of the integer | 282 | foo::(x_i32.into()); | ^^^^^^^^^^^^ @@ -775,7 +775,7 @@ error[E0308]: mismatched types | 284 | foo::(x_i16); | ^^^^^ expected f64, found i16 -help: you can cast an `i16` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `i16` to `f64`, producing the floating point representation of the integer | 284 | foo::(x_i16.into()); | ^^^^^^^^^^^^ @@ -785,7 +785,7 @@ error[E0308]: mismatched types | 286 | foo::(x_i8); | ^^^^ expected f64, found i8 -help: you can cast an `i8` to `f64`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `i8` to `f64`, producing the floating point representation of the integer | 286 | foo::(x_i8.into()); | ^^^^^^^^^^^ @@ -823,7 +823,7 @@ error[E0308]: mismatched types | 298 | foo::(x_u16); | ^^^^^ expected f32, found u16 -help: you can cast an `u16` to `f32`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `u16` to `f32`, producing the floating point representation of the integer | 298 | foo::(x_u16.into()); | ^^^^^^^^^^^^ @@ -833,7 +833,7 @@ error[E0308]: mismatched types | 300 | foo::(x_u8); | ^^^^ expected f32, found u8 -help: you can cast an `u8` to `f32`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `u8` to `f32`, producing the floating point representation of the integer | 300 | foo::(x_u8.into()); | ^^^^^^^^^^^ @@ -861,7 +861,7 @@ error[E0308]: mismatched types | 308 | foo::(x_i16); | ^^^^^ expected f32, found i16 -help: you can cast an `i16` to `f32`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `i16` to `f32`, producing the floating point representation of the integer | 308 | foo::(x_i16.into()); | ^^^^^^^^^^^^ @@ -871,7 +871,7 @@ error[E0308]: mismatched types | 310 | foo::(x_i8); | ^^^^ expected f32, found i8 -help: you can cast an `i8` to `f32`, producing the floating point representation of the integer, rounded if necessary +help: you can cast an `i8` to `f32`, producing the floating point representation of the integer | 310 | foo::(x_i8.into()); | ^^^^^^^^^^^ From afe8d13a66e2f823847b39e8be7e038a67eaa337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 10 Jan 2018 11:40:16 -0800 Subject: [PATCH 5/6] Use single source of truth for expr precedence Introduce a new unified type that holds the expression precedence for both AST and HIR nodes. --- src/librustc/hir/mod.rs | 64 +++++++++- src/librustc/hir/print.rs | 51 +------- src/librustc_typeck/check/demand.rs | 4 +- src/libsyntax/ast.rs | 180 ++++++++++++++++++++++++++++ src/libsyntax/print/pprust.rs | 2 +- src/libsyntax/util/parser.rs | 62 +--------- 6 files changed, 248 insertions(+), 115 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 8d43b9b4aa739..0ee719d1157c5 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -34,13 +34,14 @@ use util::nodemap::{NodeMap, FxHashSet}; use syntax_pos::{Span, DUMMY_SP}; use syntax::codemap::{self, Spanned}; use syntax::abi::Abi; -use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; +use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax::tokenstream::TokenStream; use syntax::util::ThinVec; +use syntax::ast::ExprPrecedence; use ty::AdtKind; use rustc_data_structures::indexed_vec; @@ -958,6 +959,31 @@ impl BinOp_ { } } +impl Into for BinOp_ { + fn into(self) -> ast::BinOpKind { + match self { + BiAdd => ast::BinOpKind::Add, + BiSub => ast::BinOpKind::Sub, + BiMul => ast::BinOpKind::Mul, + BiDiv => ast::BinOpKind::Div, + BiRem => ast::BinOpKind::Rem, + BiAnd => ast::BinOpKind::And, + BiOr => ast::BinOpKind::Or, + BiBitXor => ast::BinOpKind::BitXor, + BiBitAnd => ast::BinOpKind::BitAnd, + BiBitOr => ast::BinOpKind::BitOr, + BiShl => ast::BinOpKind::Shl, + BiShr => ast::BinOpKind::Shr, + BiEq => ast::BinOpKind::Eq, + BiLt => ast::BinOpKind::Lt, + BiLe => ast::BinOpKind::Le, + BiNe => ast::BinOpKind::Ne, + BiGe => ast::BinOpKind::Ge, + BiGt => ast::BinOpKind::Gt, + } + } +} + pub type BinOp = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -1166,6 +1192,42 @@ pub struct Expr { pub hir_id: HirId, } +impl Expr { + pub fn precedence(&self) -> ExprPrecedence { + match self.node { + ExprBox(_) => ExprPrecedence::Box, + ExprArray(_) => ExprPrecedence::Array, + ExprCall(..) => ExprPrecedence::Call, + ExprMethodCall(..) => ExprPrecedence::MethodCall, + ExprTup(_) => ExprPrecedence::Tup, + ExprBinary(op, ..) => ExprPrecedence::Binary(op.node.into()), + ExprUnary(..) => ExprPrecedence::Unary, + ExprLit(_) => ExprPrecedence::Lit, + ExprType(..) | ExprCast(..) => ExprPrecedence::Cast, + ExprIf(..) => ExprPrecedence::If, + ExprWhile(..) => ExprPrecedence::While, + ExprLoop(..) => ExprPrecedence::Loop, + ExprMatch(..) => ExprPrecedence::Match, + ExprClosure(..) => ExprPrecedence::Closure, + ExprBlock(..) => ExprPrecedence::Block, + ExprAssign(..) => ExprPrecedence::Assign, + ExprAssignOp(..) => ExprPrecedence::AssignOp, + ExprField(..) => ExprPrecedence::Field, + ExprTupField(..) => ExprPrecedence::TupField, + ExprIndex(..) => ExprPrecedence::Index, + ExprPath(..) => ExprPrecedence::Path, + ExprAddrOf(..) => ExprPrecedence::AddrOf, + ExprBreak(..) => ExprPrecedence::Break, + ExprAgain(..) => ExprPrecedence::Continue, + ExprRet(..) => ExprPrecedence::Ret, + ExprInlineAsm(..) => ExprPrecedence::InlineAsm, + ExprStruct(..) => ExprPrecedence::Struct, + ExprRepeat(..) => ExprPrecedence::Repeat, + ExprYield(..) => ExprPrecedence::Yield, + } + } +} + impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "expr({}: {})", self.id, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index a8e55674ae521..4cfa7a470a4fa 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1104,7 +1104,7 @@ impl<'a> State<'a> { } pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) -> io::Result<()> { - let needs_par = expr_precedence(expr) < prec; + let needs_par = expr.precedence().order() < prec; if needs_par { self.popen()?; } @@ -2318,55 +2318,6 @@ fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool { } } - -fn expr_precedence(expr: &hir::Expr) -> i8 { - use syntax::util::parser::*; - - match expr.node { - hir::ExprClosure(..) => PREC_CLOSURE, - - hir::ExprBreak(..) | - hir::ExprAgain(..) | - hir::ExprRet(..) | - hir::ExprYield(..) => PREC_JUMP, - - // Binop-like expr kinds, handled by `AssocOp`. - hir::ExprBinary(op, _, _) => bin_op_to_assoc_op(op.node).precedence() as i8, - - hir::ExprCast(..) => AssocOp::As.precedence() as i8, - hir::ExprType(..) => AssocOp::Colon.precedence() as i8, - - hir::ExprAssign(..) | - hir::ExprAssignOp(..) => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - hir::ExprBox(..) | - hir::ExprAddrOf(..) | - hir::ExprUnary(..) => PREC_PREFIX, - - // Unary, postfix - hir::ExprCall(..) | - hir::ExprMethodCall(..) | - hir::ExprField(..) | - hir::ExprTupField(..) | - hir::ExprIndex(..) | - hir::ExprInlineAsm(..) => PREC_POSTFIX, - - // Never need parens - hir::ExprArray(..) | - hir::ExprRepeat(..) | - hir::ExprTup(..) | - hir::ExprLit(..) | - hir::ExprPath(..) | - hir::ExprIf(..) | - hir::ExprWhile(..) | - hir::ExprLoop(..) | - hir::ExprMatch(..) | - hir::ExprBlock(..) | - hir::ExprStruct(..) => PREC_PAREN, - } -} - fn bin_op_to_assoc_op(op: hir::BinOp_) -> AssocOp { use hir::BinOp_::*; match op { diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index d43d681c92595..b6b863cfea6e6 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -15,7 +15,7 @@ use rustc::infer::InferOk; use rustc::traits::ObligationCause; use syntax::ast; -use syntax::util::parser::{expr_precedence, AssocOp}; +use syntax::util::parser::AssocOp; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::print; @@ -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(expr) < (AssocOp::As.precedence() as i8); + let needs_paren = expr.precedence().order() < (AssocOp::As.precedence() 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); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9c0622e7bef97..b45de7787a16e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,6 +15,17 @@ pub use self::UnsafeSource::*; pub use self::PathParameters::*; pub use symbol::{Ident, Symbol as Name}; pub use util::ThinVec; +pub use util::parser::{ + AssocOp, + PREC_RESET, + PREC_CLOSURE, + PREC_JUMP, + PREC_RANGE, + PREC_PREFIX, + PREC_POSTFIX, + PREC_PAREN, + PREC_FORCE_PAREN, +}; use syntax_pos::{Span, DUMMY_SP}; use codemap::{respan, Spanned}; @@ -28,6 +39,7 @@ use tokenstream::{ThinTokenStream, TokenStream}; use serialize::{self, Encoder, Decoder}; use std::collections::HashSet; +use std::cmp::Ordering; use std::fmt; use std::rc::Rc; use std::u32; @@ -730,6 +742,7 @@ impl BinOpKind { _ => false } } + pub fn is_comparison(&self) -> bool { use self::BinOpKind::*; match *self { @@ -740,6 +753,7 @@ impl BinOpKind { false, } } + /// Returns `true` if the binary operator takes its arguments by value pub fn is_by_value(&self) -> bool { !self.is_comparison() @@ -903,6 +917,129 @@ pub struct Expr { pub attrs: ThinVec } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExprPrecedence { + Closure, + Break, + Continue, + Ret, + Yield, + + Range, + + Binary(BinOpKind), + + InPlace, + Cast, + Type, + + Assign, + AssignOp, + + Box, + AddrOf, + Unary, + + Call, + MethodCall, + Field, + TupField, + Index, + Try, + InlineAsm, + Mac, + + Array, + Repeat, + Tup, + Lit, + Path, + Paren, + If, + IfLet, + While, + WhileLet, + ForLoop, + Loop, + Match, + Block, + Catch, + Struct, +} + +impl PartialOrd for ExprPrecedence { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.order().cmp(&other.order())) + } +} + +impl Ord for ExprPrecedence { + fn cmp(&self, other: &Self) -> Ordering { + self.order().cmp(&other.order()) + } +} + +impl ExprPrecedence { + pub fn order(self) -> i8 { + match self { + ExprPrecedence::Closure => PREC_CLOSURE, + + ExprPrecedence::Break | + ExprPrecedence::Continue | + ExprPrecedence::Ret | + ExprPrecedence::Yield => PREC_JUMP, + + // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to + // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence + // ensures that `pprust` will add parentheses in the right places to get the desired + // parse. + ExprPrecedence::Range => PREC_RANGE, + + // Binop-like expr kinds, handled by `AssocOp`. + ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, + ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8, + ExprPrecedence::Cast => AssocOp::As.precedence() as i8, + ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, + + ExprPrecedence::Assign | + ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, + + // Unary, prefix + ExprPrecedence::Box | + ExprPrecedence::AddrOf | + ExprPrecedence::Unary => PREC_PREFIX, + + // Unary, postfix + ExprPrecedence::Call | + ExprPrecedence::MethodCall | + ExprPrecedence::Field | + ExprPrecedence::TupField | + ExprPrecedence::Index | + ExprPrecedence::Try | + ExprPrecedence::InlineAsm | + ExprPrecedence::Mac => PREC_POSTFIX, + + // Never need parens + ExprPrecedence::Array | + ExprPrecedence::Repeat | + ExprPrecedence::Tup | + ExprPrecedence::Lit | + ExprPrecedence::Path | + ExprPrecedence::Paren | + ExprPrecedence::If | + ExprPrecedence::IfLet | + ExprPrecedence::While | + ExprPrecedence::WhileLet | + ExprPrecedence::ForLoop | + ExprPrecedence::Loop | + ExprPrecedence::Match | + ExprPrecedence::Block | + ExprPrecedence::Catch | + ExprPrecedence::Struct => PREC_PAREN, + } + } +} + impl Expr { /// Wether this expression would be valid somewhere that expects a value, for example, an `if` /// condition. @@ -966,6 +1103,49 @@ impl Expr { Some(P(Ty { node, id: self.id, span: self.span })) } + + pub fn precedence(&self) -> ExprPrecedence { + match self.node { + ExprKind::Box(_) => ExprPrecedence::Box, + ExprKind::InPlace(..) => ExprPrecedence::InPlace, + ExprKind::Array(_) => ExprPrecedence::Array, + ExprKind::Call(..) => ExprPrecedence::Call, + ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, + ExprKind::Tup(_) => ExprPrecedence::Tup, + ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), + ExprKind::Unary(..) => ExprPrecedence::Unary, + ExprKind::Lit(_) => ExprPrecedence::Lit, + ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, + ExprKind::If(..) => ExprPrecedence::If, + ExprKind::IfLet(..) => ExprPrecedence::IfLet, + ExprKind::While(..) => ExprPrecedence::While, + ExprKind::WhileLet(..) => ExprPrecedence::WhileLet, + ExprKind::ForLoop(..) => ExprPrecedence::ForLoop, + ExprKind::Loop(..) => ExprPrecedence::Loop, + ExprKind::Match(..) => ExprPrecedence::Match, + ExprKind::Closure(..) => ExprPrecedence::Closure, + ExprKind::Block(..) => ExprPrecedence::Block, + ExprKind::Catch(..) => ExprPrecedence::Catch, + ExprKind::Assign(..) => ExprPrecedence::Assign, + ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, + ExprKind::Field(..) => ExprPrecedence::Field, + ExprKind::TupField(..) => ExprPrecedence::TupField, + ExprKind::Index(..) => ExprPrecedence::Index, + ExprKind::Range(..) => ExprPrecedence::Range, + ExprKind::Path(..) => ExprPrecedence::Path, + ExprKind::AddrOf(..) => ExprPrecedence::AddrOf, + ExprKind::Break(..) => ExprPrecedence::Break, + ExprKind::Continue(..) => ExprPrecedence::Continue, + ExprKind::Ret(..) => ExprPrecedence::Ret, + ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::Mac(..) => ExprPrecedence::Mac, + ExprKind::Struct(..) => ExprPrecedence::Struct, + ExprKind::Repeat(..) => ExprPrecedence::Repeat, + ExprKind::Paren(..) => ExprPrecedence::Paren, + ExprKind::Try(..) => ExprPrecedence::Try, + ExprKind::Yield(..) => ExprPrecedence::Yield, + } + } } impl fmt::Debug for Expr { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5374bf180f49a..ff065b57b8d0b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1839,7 +1839,7 @@ impl<'a> State<'a> { } pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) -> io::Result<()> { - let needs_par = parser::expr_precedence(expr) < prec; + let needs_par = expr.precedence().order() < prec; if needs_par { self.popen()?; } diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index 6014ec5aa92a5..a95ef17a1d52c 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -9,7 +9,7 @@ // except according to those terms. use parse::token::{Token, BinOpToken}; use symbol::keywords; -use ast::{self, BinOpKind, ExprKind}; +use ast::{self, BinOpKind}; /// Associative operator with precedence. /// @@ -228,66 +228,6 @@ pub const PREC_POSTFIX: i8 = 60; pub const PREC_PAREN: i8 = 99; pub const PREC_FORCE_PAREN: i8 = 100; -pub fn expr_precedence(expr: &ast::Expr) -> i8 { - match expr.node { - ExprKind::Closure(..) => PREC_CLOSURE, - - ExprKind::Break(..) | - ExprKind::Continue(..) | - ExprKind::Ret(..) | - ExprKind::Yield(..) => PREC_JUMP, - - // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to parse, - // instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence ensures that - // `pprust` will add parentheses in the right places to get the desired parse. - ExprKind::Range(..) => PREC_RANGE, - - // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, _, _) => - AssocOp::from_ast_binop(op.node).precedence() as i8, - - ExprKind::InPlace(..) => AssocOp::Inplace.precedence() as i8, - ExprKind::Cast(..) => AssocOp::As.precedence() as i8, - ExprKind::Type(..) => AssocOp::Colon.precedence() as i8, - - ExprKind::Assign(..) | - ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - ExprKind::Box(..) | - ExprKind::AddrOf(..) | - ExprKind::Unary(..) => PREC_PREFIX, - - // Unary, postfix - ExprKind::Call(..) | - ExprKind::MethodCall(..) | - ExprKind::Field(..) | - ExprKind::TupField(..) | - ExprKind::Index(..) | - ExprKind::Try(..) | - ExprKind::InlineAsm(..) | - ExprKind::Mac(..) => PREC_POSTFIX, - - // Never need parens - ExprKind::Array(..) | - ExprKind::Repeat(..) | - ExprKind::Tup(..) | - ExprKind::Lit(..) | - ExprKind::Path(..) | - ExprKind::Paren(..) | - ExprKind::If(..) | - ExprKind::IfLet(..) | - ExprKind::While(..) | - ExprKind::WhileLet(..) | - ExprKind::ForLoop(..) | - ExprKind::Loop(..) | - ExprKind::Match(..) | - ExprKind::Block(..) | - ExprKind::Catch(..) | - ExprKind::Struct(..) => PREC_PAREN, - } -} - /// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any /// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not. From 71c08734a3ef12135ba695964e6fe882bc5e6d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 15 Jan 2018 15:09:39 -0800 Subject: [PATCH 6/6] Move `ExprPrecedence` to `libsyntax/util/parser.rs` --- src/librustc/hir/mod.rs | 2 +- src/libsyntax/ast.rs | 136 +---------------------------------- src/libsyntax/util/parser.rs | 126 ++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 136 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 0ee719d1157c5..3da2855929d3a 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -41,7 +41,7 @@ use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax::tokenstream::TokenStream; use syntax::util::ThinVec; -use syntax::ast::ExprPrecedence; +use syntax::util::parser::ExprPrecedence; use ty::AdtKind; use rustc_data_structures::indexed_vec; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b45de7787a16e..a64f1e9e4002c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,17 +15,7 @@ pub use self::UnsafeSource::*; pub use self::PathParameters::*; pub use symbol::{Ident, Symbol as Name}; pub use util::ThinVec; -pub use util::parser::{ - AssocOp, - PREC_RESET, - PREC_CLOSURE, - PREC_JUMP, - PREC_RANGE, - PREC_PREFIX, - PREC_POSTFIX, - PREC_PAREN, - PREC_FORCE_PAREN, -}; +pub use util::parser::ExprPrecedence; use syntax_pos::{Span, DUMMY_SP}; use codemap::{respan, Spanned}; @@ -39,7 +29,6 @@ use tokenstream::{ThinTokenStream, TokenStream}; use serialize::{self, Encoder, Decoder}; use std::collections::HashSet; -use std::cmp::Ordering; use std::fmt; use std::rc::Rc; use std::u32; @@ -917,129 +906,6 @@ pub struct Expr { pub attrs: ThinVec } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ExprPrecedence { - Closure, - Break, - Continue, - Ret, - Yield, - - Range, - - Binary(BinOpKind), - - InPlace, - Cast, - Type, - - Assign, - AssignOp, - - Box, - AddrOf, - Unary, - - Call, - MethodCall, - Field, - TupField, - Index, - Try, - InlineAsm, - Mac, - - Array, - Repeat, - Tup, - Lit, - Path, - Paren, - If, - IfLet, - While, - WhileLet, - ForLoop, - Loop, - Match, - Block, - Catch, - Struct, -} - -impl PartialOrd for ExprPrecedence { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.order().cmp(&other.order())) - } -} - -impl Ord for ExprPrecedence { - fn cmp(&self, other: &Self) -> Ordering { - self.order().cmp(&other.order()) - } -} - -impl ExprPrecedence { - pub fn order(self) -> i8 { - match self { - ExprPrecedence::Closure => PREC_CLOSURE, - - ExprPrecedence::Break | - ExprPrecedence::Continue | - ExprPrecedence::Ret | - ExprPrecedence::Yield => PREC_JUMP, - - // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to - // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence - // ensures that `pprust` will add parentheses in the right places to get the desired - // parse. - ExprPrecedence::Range => PREC_RANGE, - - // Binop-like expr kinds, handled by `AssocOp`. - ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, - ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8, - ExprPrecedence::Cast => AssocOp::As.precedence() as i8, - ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, - - ExprPrecedence::Assign | - ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - ExprPrecedence::Box | - ExprPrecedence::AddrOf | - ExprPrecedence::Unary => PREC_PREFIX, - - // Unary, postfix - ExprPrecedence::Call | - ExprPrecedence::MethodCall | - ExprPrecedence::Field | - ExprPrecedence::TupField | - ExprPrecedence::Index | - ExprPrecedence::Try | - ExprPrecedence::InlineAsm | - ExprPrecedence::Mac => PREC_POSTFIX, - - // Never need parens - ExprPrecedence::Array | - ExprPrecedence::Repeat | - ExprPrecedence::Tup | - ExprPrecedence::Lit | - ExprPrecedence::Path | - ExprPrecedence::Paren | - ExprPrecedence::If | - ExprPrecedence::IfLet | - ExprPrecedence::While | - ExprPrecedence::WhileLet | - ExprPrecedence::ForLoop | - ExprPrecedence::Loop | - ExprPrecedence::Match | - ExprPrecedence::Block | - ExprPrecedence::Catch | - ExprPrecedence::Struct => PREC_PAREN, - } - } -} - impl Expr { /// Wether this expression would be valid somewhere that expects a value, for example, an `if` /// condition. diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index a95ef17a1d52c..86963c4000bd1 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -11,6 +11,8 @@ use parse::token::{Token, BinOpToken}; use symbol::keywords; use ast::{self, BinOpKind}; +use std::cmp::Ordering; + /// Associative operator with precedence. /// /// This is the enum which specifies operator precedence and fixity to the parser. @@ -228,6 +230,130 @@ pub const PREC_POSTFIX: i8 = 60; pub const PREC_PAREN: i8 = 99; pub const PREC_FORCE_PAREN: i8 = 100; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExprPrecedence { + Closure, + Break, + Continue, + Ret, + Yield, + + Range, + + Binary(BinOpKind), + + InPlace, + Cast, + Type, + + Assign, + AssignOp, + + Box, + AddrOf, + Unary, + + Call, + MethodCall, + Field, + TupField, + Index, + Try, + InlineAsm, + Mac, + + Array, + Repeat, + Tup, + Lit, + Path, + Paren, + If, + IfLet, + While, + WhileLet, + ForLoop, + Loop, + Match, + Block, + Catch, + Struct, +} + +impl PartialOrd for ExprPrecedence { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.order().cmp(&other.order())) + } +} + +impl Ord for ExprPrecedence { + fn cmp(&self, other: &Self) -> Ordering { + self.order().cmp(&other.order()) + } +} + +impl ExprPrecedence { + pub fn order(self) -> i8 { + match self { + ExprPrecedence::Closure => PREC_CLOSURE, + + ExprPrecedence::Break | + ExprPrecedence::Continue | + ExprPrecedence::Ret | + ExprPrecedence::Yield => PREC_JUMP, + + // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to + // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence + // ensures that `pprust` will add parentheses in the right places to get the desired + // parse. + ExprPrecedence::Range => PREC_RANGE, + + // Binop-like expr kinds, handled by `AssocOp`. + ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, + ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8, + ExprPrecedence::Cast => AssocOp::As.precedence() as i8, + ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, + + ExprPrecedence::Assign | + ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, + + // Unary, prefix + ExprPrecedence::Box | + ExprPrecedence::AddrOf | + ExprPrecedence::Unary => PREC_PREFIX, + + // Unary, postfix + ExprPrecedence::Call | + ExprPrecedence::MethodCall | + ExprPrecedence::Field | + ExprPrecedence::TupField | + ExprPrecedence::Index | + ExprPrecedence::Try | + ExprPrecedence::InlineAsm | + ExprPrecedence::Mac => PREC_POSTFIX, + + // Never need parens + ExprPrecedence::Array | + ExprPrecedence::Repeat | + ExprPrecedence::Tup | + ExprPrecedence::Lit | + ExprPrecedence::Path | + ExprPrecedence::Paren | + ExprPrecedence::If | + ExprPrecedence::IfLet | + ExprPrecedence::While | + ExprPrecedence::WhileLet | + ExprPrecedence::ForLoop | + ExprPrecedence::Loop | + ExprPrecedence::Match | + ExprPrecedence::Block | + ExprPrecedence::Catch | + ExprPrecedence::Struct => PREC_PAREN, + } + } +} + + /// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any /// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.