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 01/15] 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 02/15] 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 03/15] 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 04/15] 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 05/15] 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 090a968fe7680cce0d3aa8fde25a5dc48948e43e Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Wed, 10 Jan 2018 20:13:03 +1100 Subject: [PATCH 06/15] Only link res_init() on GNU/*nix To workaround a bug in glibc <= 2.26 lookup_host() calls res_init() based on the glibc version detected at runtime. While this avoids calling res_init() on platforms where it's not required we will still end up linking against the symbol. This causes an issue on macOS where res_init() is implemented in a separate library (libresolv.9.dylib) from the main libc. While this is harmless for standalone programs it becomes a problem if Rust code is statically linked against another program. If the linked program doesn't already specify -lresolv it will cause the link to fail. This is captured in issue #46797 Fix this by hooking in to the glibc workaround in `cvt_gai` and only activating it for the "gnu" environment on Unix This should include all glibc platforms while excluding musl, windows-gnu, macOS, FreeBSD, etc. This has the side benefit of removing the #[cfg] in sys_common; only unix.rs has code related to the workaround now. --- src/libstd/sys/unix/l4re.rs | 4 ---- src/libstd/sys/unix/net.rs | 20 +++++++++++++------- src/libstd/sys_common/net.rs | 24 +++--------------------- 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs index c3e8d0b7d95a8..2121848967939 100644 --- a/src/libstd/sys/unix/l4re.rs +++ b/src/libstd/sys/unix/l4re.rs @@ -437,9 +437,5 @@ pub mod net { pub fn lookup_host(_: &str) -> io::Result { unimpl!(); } - - pub fn res_init_if_glibc_before_2_26() -> io::Result<()> { - unimpl!(); - } } diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index e775f857f2b40..3f65975e60880 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -51,6 +51,10 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } + + // We may need to trigger a glibc workaround. See on_resolver_failure() for details. + on_resolver_failure(); + if err == EAI_SYSTEM { return Err(io::Error::last_os_error()) } @@ -377,21 +381,22 @@ impl IntoInner for Socket { // res_init unconditionally, we call it only when we detect we're linking // against glibc version < 2.26. (That is, when we both know its needed and // believe it's thread-safe). -pub fn res_init_if_glibc_before_2_26() -> io::Result<()> { +#[cfg(target_env = "gnu")] +fn on_resolver_failure() { // If the version fails to parse, we treat it the same as "not glibc". if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { if let Some(version) = parse_glibc_version(version_str) { if version < (2, 26) { - let ret = unsafe { libc::res_init() }; - if ret != 0 { - return Err(io::Error::last_os_error()); - } + unsafe { libc::res_init() }; } } } - Ok(()) } +#[cfg(not(target_env = "gnu"))] +fn on_resolver_failure() {} + +#[cfg(target_env = "gnu")] fn glibc_version_cstr() -> Option<&'static CStr> { weak! { fn gnu_get_libc_version() -> *const libc::c_char @@ -405,6 +410,7 @@ fn glibc_version_cstr() -> Option<&'static CStr> { // Returns Some((major, minor)) if the string is a valid "x.y" version, // ignoring any extra dot-separated parts. Otherwise return None. +#[cfg(target_env = "gnu")] fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { let mut parsed_ints = version.split(".").map(str::parse::).fuse(); match (parsed_ints.next(), parsed_ints.next()) { @@ -413,7 +419,7 @@ fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { } } -#[cfg(test)] +#[cfg(all(test, taget_env = "gnu"))] mod test { use super::*; diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index c70b39995ebb0..b841afe1a5141 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -166,27 +166,9 @@ pub fn lookup_host(host: &str) -> io::Result { hints.ai_socktype = c::SOCK_STREAM; let mut res = ptr::null_mut(); unsafe { - match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) { - Ok(_) => { - Ok(LookupHost { original: res, cur: res }) - }, - #[cfg(unix)] - Err(e) => { - // If we're running glibc prior to version 2.26, the lookup - // failure could be caused by caching a stale /etc/resolv.conf. - // We need to call libc::res_init() to clear the cache. But we - // shouldn't call it in on any other platform, because other - // res_init implementations aren't thread-safe. See - // https://github.com/rust-lang/rust/issues/41570 and - // https://github.com/rust-lang/rust/issues/43592. - use sys::net::res_init_if_glibc_before_2_26; - let _ = res_init_if_glibc_before_2_26(); - Err(e) - }, - // the cfg is needed here to avoid an "unreachable pattern" warning - #[cfg(not(unix))] - Err(e) => Err(e), - } + cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| { + LookupHost { original: res, cur: res } + }) } } 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 07/15] 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. From f66e711f8b7a62ff76bbf29df0dc21eac8000501 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 Jan 2018 00:00:17 +0100 Subject: [PATCH 08/15] Add E0659 for ambiguous names --- src/librustc_resolve/diagnostics.rs | 53 +++++++++++++++++++ src/librustc_resolve/lib.rs | 2 +- src/test/compile-fail/E0659.rs | 26 +++++++++ src/test/ui/imports/duplicate.stderr | 8 +-- src/test/ui/imports/macro-paths.stderr | 4 +- src/test/ui/imports/macros.stderr | 4 +- .../ui/imports/shadow_builtin_macros.stderr | 6 +-- 7 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/E0659.rs diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 564626ac39885..b181a2568b48e 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1621,6 +1621,59 @@ println!("const value: {}", SomeModule::PRIVATE); // ok! ``` "##, +E0659: r##" +An item usage is ambiguous. + +Erroneous code example: + +```compile_fail,E0659 +pub mod moon { + pub fn foo() {} +} + +pub mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon::*; + pub use earth::*; +} + +fn main() { + collider::foo(); // ERROR: `foo` is ambiguous +} +``` + +This error generally appears when two items with the same name are imported into +a module. Here, the `foo` functions are imported and reexported from the +`collider` module and therefore, when we're using `collider::foo()`, both +functions collide. + +To solve this error, the best solution is generally to keep the path before the +item when using it. Example: + +``` +pub mod moon { + pub fn foo() {} +} + +pub mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon; + pub use earth; +} + +fn main() { + collider::moon::foo(); // ok! + collider::earth::foo(); // ok! +} +``` +"##, + } register_diagnostics! { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0a29441cef7ef..aaddd3f5c7223 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3783,7 +3783,7 @@ impl<'a> Resolver<'a> { self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg); } else { let mut err = - self.session.struct_span_err(span, &format!("`{}` is ambiguous", name)); + struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name); err.span_note(b1.span, &msg1); match b2.def() { Def::Macro(..) if b2.span == DUMMY_SP => diff --git a/src/test/compile-fail/E0659.rs b/src/test/compile-fail/E0659.rs new file mode 100644 index 0000000000000..4bd452b0aac3d --- /dev/null +++ b/src/test/compile-fail/E0659.rs @@ -0,0 +1,26 @@ +// 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. + +mod moon { + pub fn foo() {} +} + +mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon::*; + pub use earth::*; +} + +fn main() { + collider::foo(); //~ ERROR E0659 +} diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index 30f2f517115f4..a74401314a18c 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -12,7 +12,7 @@ help: You can use `as` to change the binding name of the import 25 | use a::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times | ^^^^^^^^^^^^^^^^^^ -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:56:9 | 56 | use self::foo::bar; //~ ERROR `foo` is ambiguous @@ -30,7 +30,7 @@ note: `foo` could also refer to the name imported here | ^^^^^^^^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:45:5 | 45 | f::foo(); //~ ERROR `foo` is ambiguous @@ -48,7 +48,7 @@ note: `foo` could also refer to the name imported here | ^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:46:5 | 46 | g::foo(); //~ ERROR `foo` is ambiguous @@ -66,7 +66,7 @@ note: `foo` could also refer to the name imported here | ^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:59:9 | 59 | foo::bar(); //~ ERROR `foo` is ambiguous diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 91b0b9756dad9..32d78666004c4 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -1,4 +1,4 @@ -error: `bar` is ambiguous +error[E0659]: `bar` is ambiguous --> $DIR/macro-paths.rs:25:5 | 25 | bar::m! { //~ ERROR ambiguous @@ -16,7 +16,7 @@ note: `bar` could also refer to the name imported here | ^^^^^^ = note: macro-expanded items do not shadow when used in a macro invocation path -error: `baz` is ambiguous +error[E0659]: `baz` is ambiguous --> $DIR/macro-paths.rs:35:5 | 35 | baz::m! { //~ ERROR ambiguous diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index 0b67613eb14b6..75294f7bf1256 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -15,7 +15,7 @@ note: `m` could also refer to the macro imported here 49 | use two_macros::m; | ^^^^^^^^^^^^^ -error: `m` is ambiguous +error[E0659]: `m` is ambiguous --> $DIR/macros.rs:28:5 | 28 | m! { //~ ERROR ambiguous @@ -33,7 +33,7 @@ note: `m` could also refer to the name imported here | ^^^^^^^^^^^^^ = note: macro-expanded macro imports do not shadow -error: `m` is ambiguous +error[E0659]: `m` is ambiguous --> $DIR/macros.rs:41:9 | 41 | m! { //~ ERROR ambiguous diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 853ed98c30d4d..8f4325fa12c72 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -9,7 +9,7 @@ error: `panic` is already in scope | = note: macro-expanded `macro_rules!`s may not shadow existing macros (see RFC 1560) -error: `panic` is ambiguous +error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:27:14 | 27 | fn f() { panic!(); } //~ ERROR ambiguous @@ -23,7 +23,7 @@ note: `panic` could refer to the name imported here = note: `panic` is also a builtin macro = note: consider adding an explicit import of `panic` to disambiguate -error: `panic` is ambiguous +error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:32:14 | 32 | fn f() { panic!(); } //~ ERROR ambiguous @@ -37,7 +37,7 @@ note: `panic` could refer to the name imported here = note: `panic` is also a builtin macro = note: macro-expanded macro imports do not shadow -error: `n` is ambiguous +error[E0659]: `n` is ambiguous --> $DIR/shadow_builtin_macros.rs:61:5 | 61 | n!(); //~ ERROR ambiguous From 81e6840ff445f5eb9c99ba506aa89b8fc2a1a4c7 Mon Sep 17 00:00:00 2001 From: Pieter Penninckx Date: Fri, 19 Jan 2018 16:51:46 +0100 Subject: [PATCH 09/15] Small improvements to the documentation of VecDeque. --- src/liballoc/vec_deque.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index f56aa23a4eb2f..7d15b790b24ad 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -906,7 +906,7 @@ impl VecDeque { } } - /// Clears the buffer, removing all values. + /// Clears the `VecDeque`, removing all values. /// /// # Examples /// @@ -1624,10 +1624,10 @@ impl VecDeque { return elem; } - /// Splits the collection into two at the given index. + /// Splits the `VecDeque` into two at the given index. /// - /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`, - /// and the returned `Self` contains elements `[at, len)`. + /// Returns a newly allocated `VecDeque`. `self` contains elements `[0, at)`, + /// and the returned `VecDeque` contains elements `[at, len)`. /// /// Note that the capacity of `self` does not change. /// @@ -1635,7 +1635,7 @@ impl VecDeque { /// /// # Panics /// - /// Panics if `at > len` + /// Panics if `at` is out of bounds. /// /// # Examples /// @@ -1815,7 +1815,8 @@ impl VecDeque { impl VecDeque { /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len, - /// either by removing excess elements or by appending clones of `value` to the back. + /// either by removing excess elements from the back or by appending clones of `value` + /// to the back. /// /// # Examples /// @@ -2390,7 +2391,7 @@ impl IntoIterator for VecDeque { type Item = T; type IntoIter = IntoIter; - /// Consumes the list into a front-to-back iterator yielding elements by + /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by /// value. fn into_iter(self) -> IntoIter { IntoIter { inner: self } From 06913a5b1d19284ae2c2ff6cfac130842334e886 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 12 Jan 2018 12:53:51 -0800 Subject: [PATCH 10/15] Automaticaly calculate beta prerelease numbers This is a forward-port of: * 9426dda83d7a928d6ced377345e14b84b0f11c21 * cbfb9858951da7aee22d82178405306fca9decb1 from the beta branch which is used to automatically calculate the beta number based on the number of merges to the beta branch so far. --- src/bootstrap/channel.rs | 5 ---- src/bootstrap/dist.rs | 1 - src/bootstrap/lib.rs | 53 ++++++++++++++++++++++++++++++++++++++-- src/ci/init_repo.sh | 6 +++++ 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 4e3f3a00b15ee..e412dd9e3e670 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -26,11 +26,6 @@ use config::Config; // The version number pub const CFG_RELEASE_NUM: &str = "1.25.0"; -// An optional number to put after the label, e.g. '.2' -> '-beta.2' -// Be sure to make this starts with a dot to conform to semver pre-release -// versions (section 9) -pub const CFG_PRERELEASE_VERSION: &str = ".1"; - pub struct GitInfo { inner: Option, } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 7f0613aabe658..224b31ef26872 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1652,7 +1652,6 @@ fn add_env(build: &Build, cmd: &mut Command, target: Interned) { cmd.env("CFG_RELEASE_INFO", build.rust_version()) .env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM) .env("CFG_RELEASE", build.rust_release()) - .env("CFG_PRERELEASE_VERSION", channel::CFG_PRERELEASE_VERSION) .env("CFG_VER_MAJOR", parts.next().unwrap()) .env("CFG_VER_MINOR", parts.next().unwrap()) .env("CFG_VER_PATCH", parts.next().unwrap()) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 948bf29bbacc3..3738828a4baed 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -134,7 +134,7 @@ extern crate toml; #[cfg(unix)] extern crate libc; -use std::cell::RefCell; +use std::cell::{RefCell, Cell}; use std::collections::{HashSet, HashMap}; use std::env; use std::fs::{self, File}; @@ -250,6 +250,7 @@ pub struct Build { is_sudo: bool, ci_env: CiEnv, delayed_failures: RefCell>, + prerelease_version: Cell>, } #[derive(Debug)] @@ -335,6 +336,7 @@ impl Build { is_sudo, ci_env: CiEnv::current(), delayed_failures: RefCell::new(Vec::new()), + prerelease_version: Cell::new(None), } } @@ -774,12 +776,59 @@ impl Build { fn release(&self, num: &str) -> String { match &self.config.channel[..] { "stable" => num.to_string(), - "beta" => format!("{}-beta{}", num, channel::CFG_PRERELEASE_VERSION), + "beta" => format!("{}-beta.{}", num, self.beta_prerelease_version()), "nightly" => format!("{}-nightly", num), _ => format!("{}-dev", num), } } + fn beta_prerelease_version(&self) -> u32 { + if let Some(s) = self.prerelease_version.get() { + return s + } + + let beta = output( + Command::new("git") + .arg("ls-remote") + .arg("origin") + .arg("beta") + .current_dir(&self.src) + ); + let beta = beta.trim().split_whitespace().next().unwrap(); + let master = output( + Command::new("git") + .arg("ls-remote") + .arg("origin") + .arg("master") + .current_dir(&self.src) + ); + let master = master.trim().split_whitespace().next().unwrap(); + + // Figure out where the current beta branch started. + let base = output( + Command::new("git") + .arg("merge-base") + .arg(beta) + .arg(master) + .current_dir(&self.src), + ); + let base = base.trim(); + + // Next figure out how many merge commits happened since we branched off + // beta. That's our beta number! + let count = output( + Command::new("git") + .arg("rev-list") + .arg("--count") + .arg("--merges") + .arg(format!("{}...HEAD", base)) + .current_dir(&self.src), + ); + let n = count.trim().parse().unwrap(); + self.prerelease_version.set(Some(n)); + n + } + /// Returns the value of `release` above for Rust itself. fn rust_release(&self) -> String { self.release(channel::CFG_RELEASE_NUM) diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index e073a3d99c157..14a1906ff421d 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -36,6 +36,12 @@ fi rm -rf "$CACHE_DIR" mkdir "$CACHE_DIR" +# On the beta channel we'll be automatically calculating the prerelease version +# via the git history, so unshallow our shallow clone from CI. +if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then + git fetch origin --unshallow beta master +fi + travis_fold start update_cache travis_time_start From 4d08d054c7107eaf22e320f60487a616337d34a6 Mon Sep 17 00:00:00 2001 From: Andrew Straw Date: Sat, 20 Jan 2018 23:23:44 +0100 Subject: [PATCH 11/15] fix doctests for BTreeSet to use BTreeSet (not BTreeMap) This fixes #47624 --- src/liballoc/btree/set.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index e094070fc3dd1..327eaaf465130 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -658,26 +658,26 @@ impl BTreeSet { /// Basic usage: /// /// ``` - /// use std::collections::BTreeMap; + /// use std::collections::BTreeSet; /// - /// let mut a = BTreeMap::new(); - /// a.insert(1, "a"); - /// a.insert(2, "b"); - /// a.insert(3, "c"); - /// a.insert(17, "d"); - /// a.insert(41, "e"); + /// let mut a = BTreeSet::new(); + /// a.insert(1); + /// a.insert(2); + /// a.insert(3); + /// a.insert(17); + /// a.insert(41); /// /// let b = a.split_off(&3); /// /// assert_eq!(a.len(), 2); /// assert_eq!(b.len(), 3); /// - /// assert_eq!(a[&1], "a"); - /// assert_eq!(a[&2], "b"); + /// assert!(a.contains(&1)); + /// assert!(a.contains(&2)); /// - /// assert_eq!(b[&3], "c"); - /// assert_eq!(b[&17], "d"); - /// assert_eq!(b[&41], "e"); + /// assert!(b.contains(&3)); + /// assert!(b.contains(&17)); + /// assert!(b.contains(&41)); /// ``` #[stable(feature = "btree_split_off", since = "1.11.0")] pub fn split_off(&mut self, key: &Q) -> Self where T: Borrow { From 1756f680b0c313a3dbfb40070c0160da2ed0576f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 21 Jan 2018 11:20:19 +0200 Subject: [PATCH 12/15] Fix broken links to other slice functions in chunks/chunks_mut/exact_chunk/exact_chunks_mut docs See https://github.com/rust-lang/rust/pull/47126#discussion_r162780492 --- src/liballoc/slice.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 861f72bcf88ee..028983de556f2 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -630,6 +630,8 @@ impl [T] { /// assert_eq!(iter.next().unwrap(), &['m']); /// assert!(iter.next().is_none()); /// ``` + /// + /// [`exact_chunks`]: #method.exact_chunks #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks(&self, chunk_size: usize) -> Chunks { @@ -660,6 +662,8 @@ impl [T] { /// assert_eq!(iter.next().unwrap(), &['r', 'e']); /// assert!(iter.next().is_none()); /// ``` + /// + /// [`chunks`]: #method.chunks #[unstable(feature = "exact_chunks", issue = "47115")] #[inline] pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks { @@ -692,6 +696,8 @@ impl [T] { /// } /// assert_eq!(v, &[1, 1, 2, 2, 3]); /// ``` + /// + /// [`exact_chunks_mut`]: #method.exact_chunks_mut #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut { @@ -728,6 +734,8 @@ impl [T] { /// } /// assert_eq!(v, &[1, 1, 2, 2, 0]); /// ``` + /// + /// [`chunks_mut`]: #method.chunks_mut #[unstable(feature = "exact_chunks", issue = "47115")] #[inline] pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut { From e9d0141fa9d55cfafbcdfe81acec94b974c7d487 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Sun, 21 Jan 2018 12:26:01 +0100 Subject: [PATCH 13/15] Fix ICE with `use self;` --- src/librustc/hir/lowering.rs | 3 ++- src/test/ui/issue-47623.rs | 13 +++++++++++++ src/test/ui/issue-47623.stderr | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issue-47623.rs create mode 100644 src/test/ui/issue-47623.stderr diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 238145a061f55..32b55a05124ac 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2046,7 +2046,8 @@ impl<'a> LoweringContext<'a> { }; // Correctly resolve `self` imports - if path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() { + if path.segments.len() > 1 && + path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() { let _ = path.segments.pop(); if ident.name == keywords::SelfValue.name() { *name = path.segments.last().unwrap().identifier.name; diff --git a/src/test/ui/issue-47623.rs b/src/test/ui/issue-47623.rs new file mode 100644 index 0000000000000..0c886fdb52faa --- /dev/null +++ b/src/test/ui/issue-47623.rs @@ -0,0 +1,13 @@ +// 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. + +use self; //~ERROR `self` imports are only allowed within a { } list + +fn main() {} diff --git a/src/test/ui/issue-47623.stderr b/src/test/ui/issue-47623.stderr new file mode 100644 index 0000000000000..c5a42d4d846e8 --- /dev/null +++ b/src/test/ui/issue-47623.stderr @@ -0,0 +1,8 @@ +error[E0429]: `self` imports are only allowed within a { } list + --> $DIR/issue-47623.rs:11:5 + | +11 | use self; //~ERROR `self` imports are only allowed within a { } list + | ^^^^ + +error: aborting due to previous error + From ea814b84630ee878c18ad1abff47a0e5236a2ad5 Mon Sep 17 00:00:00 2001 From: Pieter Penninckx Date: Sun, 21 Jan 2018 15:05:53 +0100 Subject: [PATCH 14/15] Revert change to docs in panic section of VecDeque::split_off --- src/liballoc/vec_deque.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 7d15b790b24ad..4b167bd20bfbe 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -1635,7 +1635,7 @@ impl VecDeque { /// /// # Panics /// - /// Panics if `at` is out of bounds. + /// Panics if `at > len`. /// /// # Examples /// From 9a562866b30bfc06c2fce8bb90e9798019be6eb0 Mon Sep 17 00:00:00 2001 From: Russell Mackenzie Date: Sun, 21 Jan 2018 15:21:36 +0000 Subject: [PATCH 15/15] Fix mailmap duplicates, Carol and Brian. --- .mailmap | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index c2d3b28602bcc..9034aae171417 100644 --- a/.mailmap +++ b/.mailmap @@ -41,11 +41,12 @@ Boris Egorov Brandon Sanderson Brandon Sanderson Brett Cannon Brett Cannon Brian Anderson +Brian Anderson Brian Dawn Brian Leibig Brian Leibig Carl-Anton Ingmarsson -Carol (Nichols || Goulding) -Carol (Nichols || Goulding) +Carol (Nichols || Goulding) +Carol (Nichols || Goulding) Carol Nichols Carol Willing Chris C Cerami Chris C Cerami Chris Pressey