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 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 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 { 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 { diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 69557fe27896a..9259138bab0a9 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 > len`. /// /// # 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 } 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/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_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 3f0f1a1a4cb58..8a29155d12d5b 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 5429dbccc5899..d9ae776a4d7b2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3802,7 +3802,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/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/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 } + }) } } 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/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 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 + 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 +