diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 8d43b9b4aa739..3da2855929d3a 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::util::parser::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 6703bbba86b1c..b6b863cfea6e6 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::AssocOp; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::print; @@ -137,7 +138,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 +288,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 +303,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { format!("*{}", code))); } } - }, + } } } None @@ -311,4 +311,240 @@ 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"; + + // 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. + // + // For now, don't suggest casting with `as`. + let can_cast = false; + + 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); + 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 => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + } + (None, _) | (_, None) => { + 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), + into_suggestion); + } + } + true + } + (&ty::TyUint(ref exp), &ty::TyUint(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + } + (None, _) | (_, None) => { + 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), + into_suggestion); + } + } + true + } + (&ty::TyInt(ref exp), &ty::TyUint(ref found)) => { + 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)) => { + 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() { + 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), + 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)"); + } + true + } + (&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, rounding the float towards zero", + msg), + 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::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", + 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(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", + 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, + } + } else { + false + } + } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9c0622e7bef97..a64f1e9e4002c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,6 +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::ExprPrecedence; use syntax_pos::{Span, DUMMY_SP}; use codemap::{respan, Spanned}; @@ -730,6 +731,7 @@ impl BinOpKind { _ => false } } + pub fn is_comparison(&self) -> bool { use self::BinOpKind::*; match *self { @@ -740,6 +742,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() @@ -966,6 +969,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..86963c4000bd1 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -9,7 +9,9 @@ // except according to those terms. use parse::token::{Token, BinOpToken}; use symbol::keywords; -use ast::{self, BinOpKind, ExprKind}; +use ast::{self, BinOpKind}; + +use std::cmp::Ordering; /// Associative operator with precedence. /// @@ -228,66 +230,130 @@ 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, +#[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. 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..2092b6bce37c1 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.rs @@ -0,0 +1,21 @@ +// 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: 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 new file mode 100644 index 0000000000000..90086d247d6e9 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:15:18 + | +15 | let x: u16 = foo(); + | ^^^^^ expected u16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:17:18 + | +17 | let y: i64 = x + x; + | ^^^^^ expected i64, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:19:18 + | +19 | let z: i32 = x + x; + | ^^^^^ expected i32, found u16 + +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 new file mode 100644 index 0000000000000..6e144037ec220 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.rs @@ -0,0 +1,315 @@ +// 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 + 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); + 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 + foo::(x_f32); + //~^ ERROR mismatched types + + 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 + 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); + foo::(x_i32); + //~^ ERROR mismatched types + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + foo::(x_f32); + //~^ ERROR mismatched types + + 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 + 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); + foo::(x_i16); + //~^ ERROR mismatched types + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + 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); + 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 + 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); + foo::(x_i8); + //~^ ERROR mismatched types + foo::(x_f64); + //~^ ERROR mismatched types + 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); + 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 + 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); + foo::(x_f64); + //~^ ERROR mismatched types + 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); + 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 + 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..0ce3d087f3509 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -0,0 +1,886 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:29:18 + | +29 | foo::(x_u64); + | ^^^^^ expected usize, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:31:18 + | +31 | foo::(x_u32); + | ^^^^^ expected usize, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:33:18 + | +33 | foo::(x_u16); + | ^^^^^ expected usize, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:35:18 + | +35 | foo::(x_u8); + | ^^^^ expected usize, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:37:18 + | +37 | foo::(x_isize); + | ^^^^^^^ expected usize, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:39:18 + | +39 | foo::(x_i64); + | ^^^^^ expected usize, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:41:18 + | +41 | foo::(x_i32); + | ^^^^^ expected usize, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:43:18 + | +43 | foo::(x_i16); + | ^^^^^ expected usize, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:45:18 + | +45 | foo::(x_i8); + | ^^^^ expected usize, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:47:18 + | +47 | foo::(x_f64); + | ^^^^^ expected usize, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:49:18 + | +49 | foo::(x_f32); + | ^^^^^ expected usize, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:52:18 + | +52 | foo::(x_usize); + | ^^^^^^^ expected isize, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:54:18 + | +54 | foo::(x_u64); + | ^^^^^ expected isize, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:56:18 + | +56 | foo::(x_u32); + | ^^^^^ expected isize, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:58:18 + | +58 | foo::(x_u16); + | ^^^^^ expected isize, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:60:18 + | +60 | foo::(x_u8); + | ^^^^ expected isize, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:63:18 + | +63 | foo::(x_i64); + | ^^^^^ expected isize, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:65:18 + | +65 | foo::(x_i32); + | ^^^^^ expected isize, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:67:18 + | +67 | foo::(x_i16); + | ^^^^^ expected isize, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:69:18 + | +69 | foo::(x_i8); + | ^^^^ expected isize, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:71:18 + | +71 | foo::(x_f64); + | ^^^^^ expected isize, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:73:18 + | +73 | foo::(x_f32); + | ^^^^^ expected isize, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:76:16 + | +76 | foo::(x_usize); + | ^^^^^^^ expected u64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:79:16 + | +79 | foo::(x_u32); + | ^^^^^ expected u64, found u32 +help: you can cast an `u32` to `u64`, which will zero-extend the source value + | +79 | foo::(x_u32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:81:16 + | +81 | foo::(x_u16); + | ^^^^^ expected u64, found u16 +help: you can cast an `u16` to `u64`, which will zero-extend the source value + | +81 | foo::(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:83:16 + | +83 | foo::(x_u8); + | ^^^^ expected u64, found u8 +help: you can cast an `u8` to `u64`, which will zero-extend the source value + | +83 | foo::(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:85:16 + | +85 | foo::(x_isize); + | ^^^^^^^ expected u64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:87:16 + | +87 | foo::(x_i64); + | ^^^^^ expected u64, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:89:16 + | +89 | foo::(x_i32); + | ^^^^^ expected u64, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:91:16 + | +91 | foo::(x_i16); + | ^^^^^ expected u64, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:93:16 + | +93 | foo::(x_i8); + | ^^^^ expected u64, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:95:16 + | +95 | foo::(x_f64); + | ^^^^^ expected u64, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:97:16 + | +97 | foo::(x_f32); + | ^^^^^ expected u64, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:100:16 + | +100 | foo::(x_usize); + | ^^^^^^^ expected i64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:102:16 + | +102 | foo::(x_u64); + | ^^^^^ expected i64, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:104:16 + | +104 | foo::(x_u32); + | ^^^^^ expected i64, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:106:16 + | +106 | foo::(x_u16); + | ^^^^^ expected i64, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:108:16 + | +108 | foo::(x_u8); + | ^^^^ expected i64, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:110:16 + | +110 | foo::(x_isize); + | ^^^^^^^ expected i64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:113:16 + | +113 | foo::(x_i32); + | ^^^^^ expected i64, found i32 +help: you can cast an `i32` to `i64`, which will sign-extend the source value + | +113 | foo::(x_i32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:115:16 + | +115 | foo::(x_i16); + | ^^^^^ expected i64, found i16 +help: you can cast an `i16` to `i64`, which will sign-extend the source value + | +115 | foo::(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:117:16 + | +117 | foo::(x_i8); + | ^^^^ expected i64, found i8 +help: you can cast an `i8` to `i64`, which will sign-extend the source value + | +117 | foo::(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:119:16 + | +119 | foo::(x_f64); + | ^^^^^ expected i64, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:121:16 + | +121 | foo::(x_f32); + | ^^^^^ expected i64, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:124:16 + | +124 | foo::(x_usize); + | ^^^^^^^ expected u32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:126:16 + | +126 | foo::(x_u64); + | ^^^^^ expected u32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:129:16 + | +129 | foo::(x_u16); + | ^^^^^ expected u32, found u16 +help: you can cast an `u16` to `u32`, which will zero-extend the source value + | +129 | foo::(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:131:16 + | +131 | foo::(x_u8); + | ^^^^ expected u32, found u8 +help: you can cast an `u8` to `u32`, which will zero-extend the source value + | +131 | foo::(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:133:16 + | +133 | foo::(x_isize); + | ^^^^^^^ expected u32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:135:16 + | +135 | foo::(x_i64); + | ^^^^^ expected u32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:137:16 + | +137 | foo::(x_i32); + | ^^^^^ expected u32, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:139:16 + | +139 | foo::(x_i16); + | ^^^^^ expected u32, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:141:16 + | +141 | foo::(x_i8); + | ^^^^ expected u32, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:143:16 + | +143 | foo::(x_f64); + | ^^^^^ expected u32, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:145:16 + | +145 | foo::(x_f32); + | ^^^^^ expected u32, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:148:16 + | +148 | foo::(x_usize); + | ^^^^^^^ expected i32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:150:16 + | +150 | foo::(x_u64); + | ^^^^^ expected i32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:152:16 + | +152 | foo::(x_u32); + | ^^^^^ expected i32, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:154:16 + | +154 | foo::(x_u16); + | ^^^^^ expected i32, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:156:16 + | +156 | foo::(x_u8); + | ^^^^ expected i32, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:158:16 + | +158 | foo::(x_isize); + | ^^^^^^^ expected i32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:160:16 + | +160 | foo::(x_i64); + | ^^^^^ expected i32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:163:16 + | +163 | foo::(x_i16); + | ^^^^^ expected i32, found i16 +help: you can cast an `i16` to `i32`, which will sign-extend the source value + | +163 | foo::(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:165:16 + | +165 | foo::(x_i8); + | ^^^^ expected i32, found i8 +help: you can cast an `i8` to `i32`, which will sign-extend the source value + | +165 | foo::(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:167:16 + | +167 | foo::(x_f64); + | ^^^^^ expected i32, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:169:16 + | +169 | foo::(x_f32); + | ^^^^^ expected i32, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:172:16 + | +172 | foo::(x_usize); + | ^^^^^^^ expected u16, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:174:16 + | +174 | foo::(x_u64); + | ^^^^^ expected u16, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:176:16 + | +176 | foo::(x_u32); + | ^^^^^ expected u16, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:179:16 + | +179 | foo::(x_u8); + | ^^^^ expected u16, found u8 +help: you can cast an `u8` to `u16`, which will zero-extend the source value + | +179 | foo::(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:181:16 + | +181 | foo::(x_isize); + | ^^^^^^^ expected u16, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:183:16 + | +183 | foo::(x_i64); + | ^^^^^ expected u16, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:185:16 + | +185 | foo::(x_i32); + | ^^^^^ expected u16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:187:16 + | +187 | foo::(x_i16); + | ^^^^^ expected u16, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:189:16 + | +189 | foo::(x_i8); + | ^^^^ expected u16, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:191:16 + | +191 | foo::(x_f64); + | ^^^^^ expected u16, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:193:16 + | +193 | foo::(x_f32); + | ^^^^^ expected u16, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:196:16 + | +196 | foo::(x_usize); + | ^^^^^^^ expected i16, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:198:16 + | +198 | foo::(x_u64); + | ^^^^^ expected i16, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:200:16 + | +200 | foo::(x_u32); + | ^^^^^ expected i16, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:202:16 + | +202 | foo::(x_u16); + | ^^^^^ expected i16, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:204:16 + | +204 | foo::(x_u8); + | ^^^^ expected i16, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:206:16 + | +206 | foo::(x_isize); + | ^^^^^^^ expected i16, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:208:16 + | +208 | foo::(x_i64); + | ^^^^^ expected i16, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:210:16 + | +210 | foo::(x_i32); + | ^^^^^ expected i16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:213:16 + | +213 | foo::(x_i8); + | ^^^^ expected i16, found i8 +help: you can cast an `i8` to `i16`, which will sign-extend the source value + | +213 | foo::(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:215:16 + | +215 | foo::(x_f64); + | ^^^^^ expected i16, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:217:16 + | +217 | foo::(x_f32); + | ^^^^^ expected i16, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:220:15 + | +220 | foo::(x_usize); + | ^^^^^^^ expected u8, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:222:15 + | +222 | foo::(x_u64); + | ^^^^^ expected u8, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:224:15 + | +224 | foo::(x_u32); + | ^^^^^ expected u8, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:226:15 + | +226 | foo::(x_u16); + | ^^^^^ expected u8, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:229:15 + | +229 | foo::(x_isize); + | ^^^^^^^ expected u8, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:231:15 + | +231 | foo::(x_i64); + | ^^^^^ expected u8, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:233:15 + | +233 | foo::(x_i32); + | ^^^^^ expected u8, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:235:15 + | +235 | foo::(x_i16); + | ^^^^^ expected u8, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:237:15 + | +237 | foo::(x_i8); + | ^^^^ expected u8, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:239:15 + | +239 | foo::(x_f64); + | ^^^^^ expected u8, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:241:15 + | +241 | foo::(x_f32); + | ^^^^^ expected u8, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:244:15 + | +244 | foo::(x_usize); + | ^^^^^^^ expected i8, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:246:15 + | +246 | foo::(x_u64); + | ^^^^^ expected i8, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:248:15 + | +248 | foo::(x_u32); + | ^^^^^ expected i8, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:250:15 + | +250 | foo::(x_u16); + | ^^^^^ expected i8, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:252:15 + | +252 | foo::(x_u8); + | ^^^^ expected i8, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:254:15 + | +254 | foo::(x_isize); + | ^^^^^^^ expected i8, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:256:15 + | +256 | foo::(x_i64); + | ^^^^^ expected i8, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:258:15 + | +258 | foo::(x_i32); + | ^^^^^ expected i8, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:260:15 + | +260 | foo::(x_i16); + | ^^^^^ expected i8, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:263:15 + | +263 | foo::(x_f64); + | ^^^^^ expected i8, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:265:15 + | +265 | foo::(x_f32); + | ^^^^^ expected i8, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:268:16 + | +268 | foo::(x_usize); + | ^^^^^^^ expected f64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:270:16 + | +270 | foo::(x_u64); + | ^^^^^ expected f64, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:272:16 + | +272 | foo::(x_u32); + | ^^^^^ expected f64, found u32 +help: you can cast an `u32` to `f64`, producing the floating point representation of the integer + | +272 | foo::(x_u32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:274:16 + | +274 | foo::(x_u16); + | ^^^^^ expected f64, found u16 +help: you can cast an `u16` to `f64`, producing the floating point representation of the integer + | +274 | foo::(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:276:16 + | +276 | foo::(x_u8); + | ^^^^ expected f64, found u8 +help: you can cast an `u8` to `f64`, producing the floating point representation of the integer + | +276 | foo::(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:278:16 + | +278 | foo::(x_isize); + | ^^^^^^^ expected f64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:280:16 + | +280 | foo::(x_i64); + | ^^^^^ expected f64, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:282:16 + | +282 | foo::(x_i32); + | ^^^^^ expected f64, found i32 +help: you can cast an `i32` to `f64`, producing the floating point representation of the integer + | +282 | foo::(x_i32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:284:16 + | +284 | foo::(x_i16); + | ^^^^^ expected f64, found i16 +help: you can cast an `i16` to `f64`, producing the floating point representation of the integer + | +284 | foo::(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:286:16 + | +286 | foo::(x_i8); + | ^^^^ expected f64, found i8 +help: you can cast an `i8` to `f64`, producing the floating point representation of the integer + | +286 | foo::(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:289:16 + | +289 | foo::(x_f32); + | ^^^^^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +289 | foo::(x_f32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:292:16 + | +292 | foo::(x_usize); + | ^^^^^^^ expected f32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:294:16 + | +294 | foo::(x_u64); + | ^^^^^ expected f32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:296:16 + | +296 | foo::(x_u32); + | ^^^^^ expected f32, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:298:16 + | +298 | foo::(x_u16); + | ^^^^^ expected f32, found u16 +help: you can cast an `u16` to `f32`, producing the floating point representation of the integer + | +298 | foo::(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:300:16 + | +300 | foo::(x_u8); + | ^^^^ expected f32, found u8 +help: you can cast an `u8` to `f32`, producing the floating point representation of the integer + | +300 | foo::(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:302:16 + | +302 | foo::(x_isize); + | ^^^^^^^ expected f32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:304:16 + | +304 | foo::(x_i64); + | ^^^^^ expected f32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:306:16 + | +306 | foo::(x_i32); + | ^^^^^ expected f32, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:308:16 + | +308 | foo::(x_i16); + | ^^^^^ expected f32, found i16 +help: you can cast an `i16` to `f32`, producing the floating point representation of the integer + | +308 | foo::(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:310:16 + | +310 | foo::(x_i8); + | ^^^^ expected f32, found i8 +help: you can cast an `i8` to `f32`, producing the floating point representation of the integer + | +310 | foo::(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:312:16 + | +312 | foo::(x_f64); + | ^^^^^ expected f32, found f64 + +error: aborting due to 132 previous errors +