From df8dd3fd3ef2080c01360db38de610c13db1766e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 28 Feb 2018 22:27:47 +0200 Subject: [PATCH 01/16] doc: no need for the references Also: - apply some rustfmt love - fix output of one example --- src/libcore/iter/iterator.rs | 53 +++++++++++++++--------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 9d8a71250f88a..722e50fe0f496 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1180,19 +1180,19 @@ pub trait Iterator { /// /// // this iterator sequence is complex. /// let sum = a.iter() - /// .cloned() - /// .filter(|&x| x % 2 == 0) - /// .fold(0, |sum, i| sum + i); + /// .cloned() + /// .filter(|x| x % 2 == 0) + /// .fold(0, |sum, i| sum + i); /// /// println!("{}", sum); /// /// // let's add some inspect() calls to investigate what's happening /// let sum = a.iter() - /// .cloned() - /// .inspect(|x| println!("about to filter: {}", x)) - /// .filter(|&x| x % 2 == 0) - /// .inspect(|x| println!("made it through filter: {}", x)) - /// .fold(0, |sum, i| sum + i); + /// .cloned() + /// .inspect(|x| println!("about to filter: {}", x)) + /// .filter(|x| x % 2 == 0) + /// .inspect(|x| println!("made it through filter: {}", x)) + /// .fold(0, |sum, i| sum + i); /// /// println!("{}", sum); /// ``` @@ -1200,6 +1200,7 @@ pub trait Iterator { /// This will print: /// /// ```text + /// 6 /// about to filter: 1 /// about to filter: 4 /// made it through filter: 4 @@ -1230,8 +1231,7 @@ pub trait Iterator { /// /// let iter = a.into_iter(); /// - /// let sum: i32 = iter.take(5) - /// .fold(0, |acc, &i| acc + i ); + /// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i ); /// /// assert_eq!(sum, 6); /// @@ -1245,9 +1245,7 @@ pub trait Iterator { /// let mut iter = a.into_iter(); /// /// // instead, we add in a .by_ref() - /// let sum: i32 = iter.by_ref() - /// .take(2) - /// .fold(0, |acc, &i| acc + i ); + /// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i ); /// /// assert_eq!(sum, 3); /// @@ -1304,9 +1302,7 @@ pub trait Iterator { /// /// let a = [1, 2, 3]; /// - /// let doubled: VecDeque = a.iter() - /// .map(|&x| x * 2) - /// .collect(); + /// let doubled: VecDeque = a.iter().map(|&x| x * 2).collect(); /// /// assert_eq!(2, doubled[0]); /// assert_eq!(4, doubled[1]); @@ -1318,9 +1314,7 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let doubled = a.iter() - /// .map(|&x| x * 2) - /// .collect::>(); + /// let doubled = a.iter().map(|x| x * 2).collect::>(); /// /// assert_eq!(vec![2, 4, 6], doubled); /// ``` @@ -1331,9 +1325,7 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let doubled = a.iter() - /// .map(|&x| x * 2) - /// .collect::>(); + /// let doubled = a.iter().map(|x| x * 2).collect::>(); /// /// assert_eq!(vec![2, 4, 6], doubled); /// ``` @@ -1344,9 +1336,9 @@ pub trait Iterator { /// let chars = ['g', 'd', 'k', 'k', 'n']; /// /// let hello: String = chars.iter() - /// .map(|&x| x as u8) - /// .map(|x| (x + 1) as char) - /// .collect(); + /// .map(|&x| x as u8) + /// .map(|x| (x + 1) as char) + /// .collect(); /// /// assert_eq!("hello", hello); /// ``` @@ -1393,8 +1385,9 @@ pub trait Iterator { /// ``` /// let a = [1, 2, 3]; /// - /// let (even, odd): (Vec, Vec) = a.into_iter() - /// .partition(|&n| n % 2 == 0); + /// let (even, odd): (Vec, Vec) = a + /// .into_iter() + /// .partition(|&n| n % 2 == 0); /// /// assert_eq!(even, vec![2]); /// assert_eq!(odd, vec![1, 3]); @@ -1457,8 +1450,7 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// /// // the checked sum of all of the elements of the array - /// let sum = a.iter() - /// .try_fold(0i8, |acc, &x| acc.checked_add(x)); + /// let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x)); /// /// assert_eq!(sum, Some(6)); /// ``` @@ -1556,8 +1548,7 @@ pub trait Iterator { /// let a = [1, 2, 3]; /// /// // the sum of all of the elements of the array - /// let sum = a.iter() - /// .fold(0, |acc, &x| acc + x); + /// let sum = a.iter().fold(0, |acc, x| acc + x); /// /// assert_eq!(sum, 6); /// ``` From e822e62ee80a9108bfdb7d0952c85fab2146f569 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 22 Feb 2018 15:53:22 +0100 Subject: [PATCH 02/16] Suggest type for overflowing bin/hex-literals --- src/librustc_lint/types.rs | 194 ++++++++++++++++++++++---- src/test/ui/lint/type-overflow.rs | 35 +++++ src/test/ui/lint/type-overflow.stderr | 70 ++++++++++ 3 files changed, 274 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/lint/type-overflow.rs create mode 100644 src/test/ui/lint/type-overflow.stderr diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index ef9b3d38c637c..4fabb5bafbf89 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -150,11 +150,52 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // Detect literal value out of range [min, max] inclusive // avoiding use of -min to prevent overflow/panic - if (negative && v > max + 1) || - (!negative && v > max) { - cx.span_lint(OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t)); + if (negative && v > max + 1) || (!negative && v > max) { + if let Some(repr_str) = get_bin_hex_repr(cx, lit) { + let bits = int_ty_bits(t, cx.sess().target.isize_ty); + let mut actually = v as i128; + if bits < 128 { + // v & 0b0..01..1, |1| = bits + let trimmed = v & ((1 << bits) - 1); + actually = if v & (1 << (bits - 1)) == 0 { + // positive + trimmed as i128 + } else { + // negative -> two's complement + (((-1 as i128 as u128) << bits) | trimmed) as i128 + }; + } + let mut err = cx.struct_span_lint( + OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t), + ); + err.note(&format!( + "the literal `{}` (decimal `{}`) does not fit into \ + an `{:?}` and will become `{}{:?}`.", + repr_str, v, t, actually, t + )); + let sugg_ty = get_fitting_type( + &cx.tables.node_id_to_type(e.hir_id).sty, + v, + negative, + ).map_or(String::new(), |ty| match ty { + ty::TyUint(t) => format!("Consider using `{:?}`", t), + ty::TyInt(t) => format!("Consider using `{:?}`", t), + _ => String::new(), + }); + if !sugg_ty.is_empty() { + err.help(&sugg_ty); + } + + err.emit(); + return; + } + cx.span_lint( + OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t), + ); return; } } @@ -180,37 +221,77 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { if let hir::ExprCast(..) = parent_expr.node { if let ty::TyChar = cx.tables.expr_ty(parent_expr).sty { let mut err = cx.struct_span_lint( - OVERFLOWING_LITERALS, - parent_expr.span, - "only u8 can be casted into char"); - err.span_suggestion(parent_expr.span, - &"use a char literal instead", - format!("'\\u{{{:X}}}'", lit_val)); + OVERFLOWING_LITERALS, + parent_expr.span, + "only u8 can be casted into char", + ); + err.span_suggestion( + parent_expr.span, + &"use a char literal instead", + format!("'\\u{{{:X}}}'", lit_val), + ); err.emit(); - return + return; } } } - cx.span_lint(OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t)); + if let Some(repr_str) = get_bin_hex_repr(cx, lit) { + let bits = uint_ty_bits(t, cx.sess().target.usize_ty); + // u128 cannot be greater than max -> compiler error + let actually = lit_val & ((1 << bits) - 1); + let mut err = cx.struct_span_lint( + OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t), + ); + err.note(&format!( + "the literal `{}` (decimal `{}`) does not fit into \ + an `{:?}` and will become `{}{:?}`.", + repr_str, lit_val, t, actually, t + )); + let sugg_ty = get_fitting_type( + &cx.tables.node_id_to_type(e.hir_id).sty, + lit_val, + false, + ).map_or( + String::new(), + |ty| { + if let ty::TyUint(t) = ty { + format!("Consider using `{:?}`", t) + } else { + String::new() + } + }, + ); + if !sugg_ty.is_empty() { + err.help(&sugg_ty); + } + + err.emit(); + return; + } + cx.span_lint( + OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t), + ); } } ty::TyFloat(t) => { let is_infinite = match lit.node { - ast::LitKind::Float(v, _) | - ast::LitKind::FloatUnsuffixed(v) => { - match t { - ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), - ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), - } - } + ast::LitKind::Float(v, _) | ast::LitKind::FloatUnsuffixed(v) => match t + { + ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), + ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), + }, _ => bug!(), }; if is_infinite == Ok(true) { - cx.span_lint(OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t)); + cx.span_lint( + OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t), + ); } } _ => (), @@ -338,6 +419,69 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { _ => false, } } + + fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option { + if let Some(src) = cx.sess().codemap().span_to_snippet(lit.span).ok() { + if let Some(firstch) = src.chars().next() { + if let Some(0) = char::to_digit(firstch, 10) { + if let Some(base) = src.chars().nth(1) { + if base == 'x' || base == 'b' { + return Some(src); + } + } + } + } + } + + None + } + + fn get_fitting_type<'a>( + t: &ty::TypeVariants, + val: u128, + negative: bool, + ) -> Option> { + use syntax::ast::IntTy::*; + use syntax::ast::UintTy::*; + macro_rules! find_fit { + ($ty:expr, $val:expr, $negative:expr, + $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => { + { + let _neg = if negative { 1 } else { 0 }; + match $ty { + $($type => { + $(if !negative && val <= uint_ty_range($utypes).1 { + return Some(ty::TyUint($utypes)) + })* + $(if val <= int_ty_range($itypes).1 as u128 + _neg { + return Some(ty::TyInt($itypes)) + })* + None + },)* + _ => None + } + } + } + } + if let &ty::TyInt(i) = t { + return find_fit!(i, val, negative, + I8 => [U8] => [I16, I32, I64, I128], + I16 => [U16] => [I32, I64, I128], + I32 => [U32] => [I64, I128], + I64 => [U64] => [I128], + I128 => [U128] => []); + } + if let &ty::TyUint(u) = t { + return find_fit!(u, val, negative, + U8 => [U8, U16, U32, U64, U128] => [], + U16 => [U16, U32, U64, U128] => [], + U32 => [U32, U64, U128] => [], + U64 => [U64, U128] => [], + U128 => [U128] => []); + } + + None + } } } diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs new file mode 100644 index 0000000000000..e414f43b3ffd7 --- /dev/null +++ b/src/test/ui/lint/type-overflow.rs @@ -0,0 +1,35 @@ +// 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. + +// must-compile-successfully + +#![feature(i128_type)] + +fn main() { + let error = 255i8; //~WARNING literal out of range for i8 + + let ok = 0b1000_0001; // should be ok -> i32 + let ok = 0b0111_1111i8; // should be ok -> 127i8 + + let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 + + let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 + + let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 + + let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; + //~^ WARNING literal out of range for i128 + + let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 + + let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize + + let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 +} diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr new file mode 100644 index 0000000000000..425f76da5cb4e --- /dev/null +++ b/src/test/ui/lint/type-overflow.stderr @@ -0,0 +1,70 @@ +warning: literal out of range for i8 + --> $DIR/type-overflow.rs:16:17 + | +16 | let error = 255i8; //~WARNING literal out of range for i8 + | ^^^^^ + | + = note: #[warn(overflowing_literals)] on by default + +warning: literal out of range for i8 + --> $DIR/type-overflow.rs:21:16 + | +21 | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 + | ^^^^^^^^^^^^^ + | + = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`. + = help: Consider using `u8` + +warning: literal out of range for i64 + --> $DIR/type-overflow.rs:23:16 + | +23 | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`. + = help: Consider using `u64` + +warning: literal out of range for u32 + --> $DIR/type-overflow.rs:25:16 + | +25 | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 + | ^^^^^^^^^^^^^^^^ + | + = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`. + = help: Consider using `u64` + +warning: literal out of range for i128 + --> $DIR/type-overflow.rs:27:22 + | +27 | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`. + = help: Consider using `u128` + +warning: literal out of range for i32 + --> $DIR/type-overflow.rs:30:16 + | +30 | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`. + = help: Consider using `i128` + +warning: literal out of range for isize + --> $DIR/type-overflow.rs:32:23 + | +32 | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`. + +warning: literal out of range for i8 + --> $DIR/type-overflow.rs:34:17 + | +34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 + | ^^^^^^^^^^^^^ + | + = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`. + = help: Consider using `i16` + From 19c4771eeb5fc8fb18bb2e9a3f16ee474d8e67e3 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 22 Feb 2018 20:25:58 +0100 Subject: [PATCH 03/16] Implementing requested changes --- src/librustc_lint/types.rs | 141 +++++++++++++++---------------------- 1 file changed, 56 insertions(+), 85 deletions(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 4fabb5bafbf89..db9dfedc656ba 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -153,18 +153,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { if (negative && v > max + 1) || (!negative && v > max) { if let Some(repr_str) = get_bin_hex_repr(cx, lit) { let bits = int_ty_bits(t, cx.sess().target.isize_ty); - let mut actually = v as i128; - if bits < 128 { - // v & 0b0..01..1, |1| = bits - let trimmed = v & ((1 << bits) - 1); - actually = if v & (1 << (bits - 1)) == 0 { - // positive - trimmed as i128 - } else { - // negative -> two's complement - (((-1 as i128 as u128) << bits) | trimmed) as i128 - }; - } + let actually = + ((v << (128 - bits)) as i128) >> (128 - bits); let mut err = cx.struct_span_lint( OVERFLOWING_LITERALS, e.span, @@ -175,15 +165,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { an `{:?}` and will become `{}{:?}`.", repr_str, v, t, actually, t )); - let sugg_ty = get_fitting_type( + let sugg_ty = get_type_suggestion( &cx.tables.node_id_to_type(e.hir_id).sty, v, negative, - ).map_or(String::new(), |ty| match ty { - ty::TyUint(t) => format!("Consider using `{:?}`", t), - ty::TyInt(t) => format!("Consider using `{:?}`", t), - _ => String::new(), - }); + ); if !sugg_ty.is_empty() { err.help(&sugg_ty); } @@ -221,24 +207,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { if let hir::ExprCast(..) = parent_expr.node { if let ty::TyChar = cx.tables.expr_ty(parent_expr).sty { let mut err = cx.struct_span_lint( - OVERFLOWING_LITERALS, - parent_expr.span, - "only u8 can be casted into char", - ); - err.span_suggestion( - parent_expr.span, - &"use a char literal instead", - format!("'\\u{{{:X}}}'", lit_val), - ); + OVERFLOWING_LITERALS, + parent_expr.span, + "only u8 can be casted into char"); + err.span_suggestion(parent_expr.span, + &"use a char literal instead", + format!("'\\u{{{:X}}}'", lit_val)); err.emit(); - return; + return } } } if let Some(repr_str) = get_bin_hex_repr(cx, lit) { let bits = uint_ty_bits(t, cx.sess().target.usize_ty); - // u128 cannot be greater than max -> compiler error - let actually = lit_val & ((1 << bits) - 1); + let actually = (lit_val << (128 - bits)) >> (128 - bits); let mut err = cx.struct_span_lint( OVERFLOWING_LITERALS, e.span, @@ -249,19 +231,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { an `{:?}` and will become `{}{:?}`.", repr_str, lit_val, t, actually, t )); - let sugg_ty = get_fitting_type( + let sugg_ty = get_type_suggestion( &cx.tables.node_id_to_type(e.hir_id).sty, lit_val, false, - ).map_or( - String::new(), - |ty| { - if let ty::TyUint(t) = ty { - format!("Consider using `{:?}`", t) - } else { - String::new() - } - }, ); if !sugg_ty.is_empty() { err.help(&sugg_ty); @@ -279,19 +252,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } ty::TyFloat(t) => { let is_infinite = match lit.node { - ast::LitKind::Float(v, _) | ast::LitKind::FloatUnsuffixed(v) => match t - { - ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), - ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), - }, + ast::LitKind::Float(v, _) | + ast::LitKind::FloatUnsuffixed(v) => { + match t { + ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite), + ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite), + } + } _ => bug!(), }; if is_infinite == Ok(true) { - cx.span_lint( - OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t), - ); + cx.span_lint(OVERFLOWING_LITERALS, + e.span, + &format!("literal out of range for {:?}", t)); } } _ => (), @@ -421,26 +394,27 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option { - if let Some(src) = cx.sess().codemap().span_to_snippet(lit.span).ok() { - if let Some(firstch) = src.chars().next() { - if let Some(0) = char::to_digit(firstch, 10) { - if let Some(base) = src.chars().nth(1) { - if base == 'x' || base == 'b' { - return Some(src); - } - } - } + let src = cx.sess().codemap().span_to_snippet(lit.span).ok()?; + let firstch = src.chars().next()?; + + if let Some(0) = char::to_digit(firstch, 10) { + match src.chars().nth(1) { + Some('x') | Some('b') => return Some(src), + _ => return None, } } None } - fn get_fitting_type<'a>( - t: &ty::TypeVariants, - val: u128, - negative: bool, - ) -> Option> { + // This function finds the next fitting type and generates a suggestion string. + // It searches for fitting types in the following way (`X < Y`): + // - `iX`: if literal fits in `uX` => `uX`, else => `iY` + // - `-iX` => `iY` + // - `uX` => `uY` + // + // No suggestion for: `isize`, `usize`. + fn get_type_suggestion<'a>(t: &ty::TypeVariants, val: u128, negative: bool) -> String { use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; macro_rules! find_fit { @@ -451,36 +425,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { match $ty { $($type => { $(if !negative && val <= uint_ty_range($utypes).1 { - return Some(ty::TyUint($utypes)) + return format!("Consider using `{:?}`", $utypes) })* $(if val <= int_ty_range($itypes).1 as u128 + _neg { - return Some(ty::TyInt($itypes)) + return format!("Consider using `{:?}`", $itypes) })* - None + String::new() },)* - _ => None + _ => String::new() } } } } - if let &ty::TyInt(i) = t { - return find_fit!(i, val, negative, - I8 => [U8] => [I16, I32, I64, I128], - I16 => [U16] => [I32, I64, I128], - I32 => [U32] => [I64, I128], - I64 => [U64] => [I128], - I128 => [U128] => []); - } - if let &ty::TyUint(u) = t { - return find_fit!(u, val, negative, - U8 => [U8, U16, U32, U64, U128] => [], - U16 => [U16, U32, U64, U128] => [], - U32 => [U32, U64, U128] => [], - U64 => [U64, U128] => [], - U128 => [U128] => []); + match t { + &ty::TyInt(i) => find_fit!(i, val, negative, + I8 => [U8] => [I16, I32, I64, I128], + I16 => [U16] => [I32, I64, I128], + I32 => [U32] => [I64, I128], + I64 => [U64] => [I128], + I128 => [U128] => []), + &ty::TyUint(u) => find_fit!(u, val, negative, + U8 => [U8, U16, U32, U64, U128] => [], + U16 => [U16, U32, U64, U128] => [], + U32 => [U32, U64, U128] => [], + U64 => [U64, U128] => [], + U128 => [U128] => []), + _ => String::new(), } - - None } } } From 5c706196449f679b163a8a5fbfb08d842db07e29 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Sat, 24 Feb 2018 16:40:51 +0100 Subject: [PATCH 04/16] Rewrite error reporting as requested --- src/librustc_lint/types.rs | 114 ++++++++++++++++---------- src/test/ui/lint/type-overflow.stderr | 30 +++---- 2 files changed, 82 insertions(+), 62 deletions(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index db9dfedc656ba..02aef271c37db 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -152,29 +152,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // avoiding use of -min to prevent overflow/panic if (negative && v > max + 1) || (!negative && v > max) { if let Some(repr_str) = get_bin_hex_repr(cx, lit) { - let bits = int_ty_bits(t, cx.sess().target.isize_ty); - let actually = - ((v << (128 - bits)) as i128) >> (128 - bits); - let mut err = cx.struct_span_lint( - OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t), - ); - err.note(&format!( - "the literal `{}` (decimal `{}`) does not fit into \ - an `{:?}` and will become `{}{:?}`.", - repr_str, v, t, actually, t - )); - let sugg_ty = get_type_suggestion( - &cx.tables.node_id_to_type(e.hir_id).sty, + report_bin_hex_error( + cx, + e, + ty::TyInt(t), + repr_str, v, negative, ); - if !sugg_ty.is_empty() { - err.help(&sugg_ty); - } - - err.emit(); return; } cx.span_lint( @@ -219,28 +204,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { } } if let Some(repr_str) = get_bin_hex_repr(cx, lit) { - let bits = uint_ty_bits(t, cx.sess().target.usize_ty); - let actually = (lit_val << (128 - bits)) >> (128 - bits); - let mut err = cx.struct_span_lint( - OVERFLOWING_LITERALS, - e.span, - &format!("literal out of range for {:?}", t), - ); - err.note(&format!( - "the literal `{}` (decimal `{}`) does not fit into \ - an `{:?}` and will become `{}{:?}`.", - repr_str, lit_val, t, actually, t - )); - let sugg_ty = get_type_suggestion( - &cx.tables.node_id_to_type(e.hir_id).sty, + report_bin_hex_error( + cx, + e, + ty::TyUint(t), + repr_str, lit_val, false, ); - if !sugg_ty.is_empty() { - err.help(&sugg_ty); - } - - err.emit(); return; } cx.span_lint( @@ -414,7 +385,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { // - `uX` => `uY` // // No suggestion for: `isize`, `usize`. - fn get_type_suggestion<'a>(t: &ty::TypeVariants, val: u128, negative: bool) -> String { + fn get_type_suggestion<'a>( + t: &ty::TypeVariants, + val: u128, + negative: bool, + ) -> Option { use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; macro_rules! find_fit { @@ -425,14 +400,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { match $ty { $($type => { $(if !negative && val <= uint_ty_range($utypes).1 { - return format!("Consider using `{:?}`", $utypes) + return Some(format!("{:?}", $utypes)) })* $(if val <= int_ty_range($itypes).1 as u128 + _neg { - return format!("Consider using `{:?}`", $itypes) + return Some(format!("{:?}", $itypes)) })* - String::new() + None },)* - _ => String::new() + _ => None } } } @@ -450,8 +425,57 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { U32 => [U32, U64, U128] => [], U64 => [U64, U128] => [], U128 => [U128] => []), - _ => String::new(), + _ => None, + } + } + + fn report_bin_hex_error( + cx: &LateContext, + expr: &hir::Expr, + ty: ty::TypeVariants, + repr_str: String, + val: u128, + negative: bool, + ) { + let (t, actually) = match ty { + ty::TyInt(t) => { + let bits = int_ty_bits(t, cx.sess().target.isize_ty); + let actually = (val << (128 - bits)) as i128 >> (128 - bits); + (format!("{:?}", t), actually.to_string()) + } + ty::TyUint(t) => { + let bits = uint_ty_bits(t, cx.sess().target.usize_ty); + let actually = (val << (128 - bits)) >> (128 - bits); + (format!("{:?}", t), actually.to_string()) + } + _ => bug!(), + }; + let mut err = cx.struct_span_lint( + OVERFLOWING_LITERALS, + expr.span, + &format!("literal out of range for {}", t), + ); + err.note(&format!( + "the literal `{}` (decimal `{}`) does not fit into \ + an `{}` and will become `{}{}`", + repr_str, val, t, actually, t + )); + if let Some(sugg_ty) = + get_type_suggestion(&cx.tables.node_id_to_type(expr.hir_id).sty, val, negative) + { + if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { + let (sans_suffix, _) = repr_str.split_at(pos); + err.span_suggestion( + expr.span, + &format!("consider using `{}` instead", sugg_ty), + format!("{}{}", sans_suffix, sugg_ty), + ); + } else { + err.help(&format!("consider using `{}` instead", sugg_ty)); + } } + + err.emit(); } } } diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 425f76da5cb4e..89718c7696a8d 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -10,28 +10,25 @@ warning: literal out of range for i8 --> $DIR/type-overflow.rs:21:16 | 21 | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8` | - = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`. - = help: Consider using `u8` + = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8` warning: literal out of range for i64 --> $DIR/type-overflow.rs:23:16 | 23 | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64` | - = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`. - = help: Consider using `u64` + = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64` warning: literal out of range for u32 --> $DIR/type-overflow.rs:25:16 | 25 | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64` | - = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`. - = help: Consider using `u64` + = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32` warning: literal out of range for i128 --> $DIR/type-overflow.rs:27:22 @@ -39,8 +36,8 @@ warning: literal out of range for i128 27 | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`. - = help: Consider using `u128` + = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128` + = help: consider using `u128` instead warning: literal out of range for i32 --> $DIR/type-overflow.rs:30:16 @@ -48,8 +45,8 @@ warning: literal out of range for i32 30 | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 | ^^^^^^^^^^^^^^^^^^^^^ | - = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`. - = help: Consider using `i128` + = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32` + = help: consider using `i128` instead warning: literal out of range for isize --> $DIR/type-overflow.rs:32:23 @@ -57,14 +54,13 @@ warning: literal out of range for isize 32 | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize | ^^^^^^^^^^^^^^^^^^^^^ | - = note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`. + = note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize` warning: literal out of range for i8 --> $DIR/type-overflow.rs:34:17 | 34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` | - = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`. - = help: Consider using `i16` + = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8` From f45f760f624b34a7fa70fe925303808d4713641a Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 1 Mar 2018 01:49:36 +0100 Subject: [PATCH 05/16] Adapt stderr of UI test to PR #48449 --- src/test/ui/lint/type-overflow.stderr | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 89718c7696a8d..4ede25b9d03e7 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -1,7 +1,7 @@ warning: literal out of range for i8 --> $DIR/type-overflow.rs:16:17 | -16 | let error = 255i8; //~WARNING literal out of range for i8 +LL | let error = 255i8; //~WARNING literal out of range for i8 | ^^^^^ | = note: #[warn(overflowing_literals)] on by default @@ -9,7 +9,7 @@ warning: literal out of range for i8 warning: literal out of range for i8 --> $DIR/type-overflow.rs:21:16 | -21 | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 +LL | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8` | = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8` @@ -17,7 +17,7 @@ warning: literal out of range for i8 warning: literal out of range for i64 --> $DIR/type-overflow.rs:23:16 | -23 | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 +LL | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64` | = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64` @@ -25,7 +25,7 @@ warning: literal out of range for i64 warning: literal out of range for u32 --> $DIR/type-overflow.rs:25:16 | -25 | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 +LL | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 | ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64` | = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32` @@ -33,7 +33,7 @@ warning: literal out of range for u32 warning: literal out of range for i128 --> $DIR/type-overflow.rs:27:22 | -27 | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; +LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128` @@ -42,7 +42,7 @@ warning: literal out of range for i128 warning: literal out of range for i32 --> $DIR/type-overflow.rs:30:16 | -30 | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 +LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 | ^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32` @@ -51,7 +51,7 @@ warning: literal out of range for i32 warning: literal out of range for isize --> $DIR/type-overflow.rs:32:23 | -32 | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize +LL | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize | ^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize` @@ -59,7 +59,7 @@ warning: literal out of range for isize warning: literal out of range for i8 --> $DIR/type-overflow.rs:34:17 | -34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 +LL | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` | = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8` From f7693c06338c825d0d49eb1373e2039416b38389 Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Wed, 21 Feb 2018 16:12:23 +0100 Subject: [PATCH 06/16] Fix spelling s/casted/cast/ --- src/libcore/char.rs | 4 ++-- src/librustc_lint/types.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/test/run-pass/extern-types-pointer-cast.rs | 2 +- src/test/ui/cast_char.rs | 4 ++-- src/test/ui/cast_char.stderr | 4 ++-- src/test/ui/issue-22644.stderr | 16 ++++++++-------- src/test/ui/issue-42954.stderr | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 7215bd2a47684..55d4b590f9133 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -79,7 +79,7 @@ pub const MAX: char = '\u{10ffff}'; /// Converts a `u32` to a `char`. /// -/// Note that all [`char`]s are valid [`u32`]s, and can be casted to one with +/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with /// [`as`]: /// /// ``` @@ -131,7 +131,7 @@ pub fn from_u32(i: u32) -> Option { /// Converts a `u32` to a `char`, ignoring validity. /// -/// Note that all [`char`]s are valid [`u32`]s, and can be casted to one with +/// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with /// [`as`]: /// /// ``` diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index f734f3182a931..2207bbd1ca05e 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -184,7 +184,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { let mut err = cx.struct_span_lint( OVERFLOWING_LITERALS, parent_expr.span, - "only u8 can be casted into char"); + "only u8 can be cast into char"); err.span_suggestion(parent_expr.span, &"use a char literal instead", format!("'\\u{{{:X}}}'", lit_val)); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7915109ce3af8..fdeed5391f772 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3094,7 +3094,7 @@ impl<'a> Parser<'a> { let expr_str = self.sess.codemap().span_to_snippet(expr.span) .unwrap_or(pprust::expr_to_string(&expr)); err.span_suggestion(expr.span, - &format!("try {} the casted value", op_verb), + &format!("try {} the cast value", op_verb), format!("({})", expr_str)); err.emit(); diff --git a/src/test/run-pass/extern-types-pointer-cast.rs b/src/test/run-pass/extern-types-pointer-cast.rs index 628a570665a33..0dede8eb70de0 100644 --- a/src/test/run-pass/extern-types-pointer-cast.rs +++ b/src/test/run-pass/extern-types-pointer-cast.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that pointers to extern types can be casted from/to usize, +// Test that pointers to extern types can be cast from/to usize, // despite being !Sized. #![feature(extern_types)] diff --git a/src/test/ui/cast_char.rs b/src/test/ui/cast_char.rs index cd8ade5e51a1b..4dfa5037bc555 100644 --- a/src/test/ui/cast_char.rs +++ b/src/test/ui/cast_char.rs @@ -12,9 +12,9 @@ fn main() { const XYZ: char = 0x1F888 as char; - //~^ ERROR only u8 can be casted into char + //~^ ERROR only u8 can be cast into char const XY: char = 129160 as char; - //~^ ERROR only u8 can be casted into char + //~^ ERROR only u8 can be cast into char const ZYX: char = '\u{01F888}'; println!("{}", XYZ); } diff --git a/src/test/ui/cast_char.stderr b/src/test/ui/cast_char.stderr index e42a38dace9d2..5da763992e35b 100644 --- a/src/test/ui/cast_char.stderr +++ b/src/test/ui/cast_char.stderr @@ -1,4 +1,4 @@ -error: only u8 can be casted into char +error: only u8 can be cast into char --> $DIR/cast_char.rs:14:23 | 14 | const XYZ: char = 0x1F888 as char; @@ -10,7 +10,7 @@ note: lint level defined here 11 | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ -error: only u8 can be casted into char +error: only u8 can be cast into char --> $DIR/cast_char.rs:16:22 | 16 | const XY: char = 129160 as char; diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 91107fbe35610..60ad222c7ab12 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -5,7 +5,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | ---------- ^ --------- interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `(a as usize)` + | help: try comparing the cast value: `(a as usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:17:33 @@ -14,7 +14,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | ---------- ^ -------------------- interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `(a as usize)` + | help: try comparing the cast value: `(a as usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:19:31 @@ -23,7 +23,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | ---------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `(a as usize)` + | help: try comparing the cast value: `(a as usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:21:31 @@ -32,7 +32,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | -------- ^ -------------------- interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `(a: usize)` + | help: try comparing the cast value: `(a: usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:23:29 @@ -41,7 +41,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | -------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `(a: usize)` + | help: try comparing the cast value: `(a: usize)` error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison --> $DIR/issue-22644.rs:28:20 @@ -50,7 +50,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | ^ not interpreted as comparison 29 | 4); | - interpreted as generic arguments -help: try comparing the casted value +help: try comparing the cast value | 25 | println!("{}", (a 26 | as @@ -64,7 +64,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com | ^ not interpreted as comparison 38 | 5); | - interpreted as generic arguments -help: try comparing the casted value +help: try comparing the cast value | 30 | println!("{}", (a 31 | @@ -81,7 +81,7 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a shi | ---------- ^^ --------- interpreted as generic arguments | | | | | not interpreted as shift - | help: try shifting the casted value: `(a as usize)` + | help: try shifting the cast value: `(a as usize)` error: expected type, found `4` --> $DIR/issue-22644.rs:42:28 diff --git a/src/test/ui/issue-42954.stderr b/src/test/ui/issue-42954.stderr index d0fc410c474a4..205fa82274a69 100644 --- a/src/test/ui/issue-42954.stderr +++ b/src/test/ui/issue-42954.stderr @@ -5,7 +5,7 @@ error: `<` is interpreted as a start of generic arguments for `u32`, not a compa | --------- ^ - interpreted as generic arguments | | | | | not interpreted as comparison - | help: try comparing the casted value: `($i as u32)` + | help: try comparing the cast value: `($i as u32)` ... 19 | is_plainly_printable!(c); | ------------------------- in this macro invocation From 15ecf0694811cf9ab3273c14a97f6f05b22a9b5b Mon Sep 17 00:00:00 2001 From: flip1995 Date: Fri, 2 Mar 2018 13:33:06 +0100 Subject: [PATCH 07/16] Remove isize test --- src/test/ui/lint/type-overflow.rs | 2 -- src/test/ui/lint/type-overflow.stderr | 10 +--------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index e414f43b3ffd7..495989587e585 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -29,7 +29,5 @@ fn main() { let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 - let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize - let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 } diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 4ede25b9d03e7..d3fcb1335e209 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -48,16 +48,8 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32` = help: consider using `i128` instead -warning: literal out of range for isize - --> $DIR/type-overflow.rs:32:23 - | -LL | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize` - warning: literal out of range for i8 - --> $DIR/type-overflow.rs:34:17 + --> $DIR/type-overflow.rs:32:17 | LL | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` From fc33b2567cac0ae453807f4118872ab81a16ddf7 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Sat, 3 Mar 2018 21:55:04 +0100 Subject: [PATCH 08/16] Improve getting literal representation --- src/librustc_lint/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 02aef271c37db..e778b2d386105 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -368,7 +368,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { let src = cx.sess().codemap().span_to_snippet(lit.span).ok()?; let firstch = src.chars().next()?; - if let Some(0) = char::to_digit(firstch, 10) { + if firstch == '0' { match src.chars().nth(1) { Some('x') | Some('b') => return Some(src), _ => return None, From 04da856c8464e9ed25645f8ef4426a322c168c2e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 1 Mar 2018 14:50:50 -0800 Subject: [PATCH 09/16] Update sccache to its master branch Ideally I'd like to soon enable sccache for rustbuild itself and some of the stage0 tools, but for that to work we'll need some better Rust support than the pretty old version we were previously using! --- .travis.yml | 13 +------------ appveyor.yml | 10 ++-------- src/ci/docker/run.sh | 2 -- src/ci/docker/scripts/sccache.sh | 2 +- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0d8641e45ed15..2d823815a3010 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,6 @@ matrix: SRC=. DEPLOY_ALT=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 - SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 @@ -50,7 +49,6 @@ matrix: RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler" SRC=. RUSTC_RETRY_LINKER_ON_SEGFAULT=1 - SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.8 MACOSX_STD_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 @@ -64,7 +62,6 @@ matrix: RUST_CONFIGURE_ARGS=--build=i686-apple-darwin SRC=. RUSTC_RETRY_LINKER_ON_SEGFAULT=1 - SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.8 MACOSX_STD_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 @@ -85,7 +82,6 @@ matrix: SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 - SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 @@ -99,7 +95,6 @@ matrix: SRC=. DEPLOY=1 RUSTC_RETRY_LINKER_ON_SEGFAULT=1 - SCCACHE_ERROR_LOG=/tmp/sccache.log MACOSX_DEPLOYMENT_TARGET=10.7 NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 @@ -223,7 +218,7 @@ install: travis_retry brew update && travis_retry brew install xz; fi && - travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-apple-darwin && + travis_retry curl -fo /usr/local/bin/sccache https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-03-01-sccache-x86_64-apple-darwin && chmod +x /usr/local/bin/sccache && travis_retry curl -fo /usr/local/bin/stamp https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin && chmod +x /usr/local/bin/stamp @@ -264,12 +259,6 @@ after_failure: df -h; du . | sort -nr | head -n100 - # One of these is the linux sccache log, one is the OSX sccache log. Instead - # of worrying about what system we are just cat both. One of these commands - # will fail but that's ok, they'll both get executed. - - cat obj/tmp/sccache.log - - cat /tmp/sccache.log - # Random attempt at debugging currently. Just poking around in here to see if # anything shows up. - ls -lat $HOME/Library/Logs/DiagnosticReports/ diff --git a/appveyor.yml b/appveyor.yml index 0ea15dd671c8b..9c4d66c7ee33b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -148,8 +148,8 @@ install: - set PATH=C:\Python27;%PATH% # Download and install sccache - - appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-pc-windows-msvc - - mv 2017-05-12-sccache-x86_64-pc-windows-msvc sccache.exe + - appveyor-retry appveyor DownloadFile https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-03-01-sccache-x86_64-pc-windows-msvc + - mv 2018-03-01-sccache-x86_64-pc-windows-msvc sccache.exe - set PATH=%PATH%;%CD% # Download and install ninja @@ -172,9 +172,6 @@ install: - set PATH=%PATH%;%CD%\handle - handle.exe -accepteula -help - # Attempt to debug sccache failures - - set SCCACHE_ERROR_LOG=%CD%/sccache.log - test_script: - if not exist C:\cache\rustsrc\NUL mkdir C:\cache\rustsrc - sh src/ci/init_repo.sh . /c/cache/rustsrc @@ -182,9 +179,6 @@ test_script: - set NO_CCACHE=1 - sh src/ci/run.sh -on_failure: - - cat %CD%\sccache.log || exit 0 - branches: only: - auto diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index f743c976f91a2..83cc95d3c2cd0 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -72,8 +72,6 @@ if [ "$SCCACHE_BUCKET" != "" ]; then args="$args --env SCCACHE_REGION" args="$args --env AWS_ACCESS_KEY_ID" args="$args --env AWS_SECRET_ACCESS_KEY" - args="$args --env SCCACHE_ERROR_LOG=/tmp/sccache/sccache.log" - args="$args --volume $objdir/tmp:/tmp/sccache" else mkdir -p $HOME/.cache/sccache args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache" diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index ce2d45563f7b5..593314b34a518 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -13,6 +13,6 @@ set -ex curl -fo /usr/local/bin/sccache \ - https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl + https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror/2018-03-01-sccache-x86_64-unknown-linux-musl chmod +x /usr/local/bin/sccache From 0b0e1b71d5818438f062b35b5890ce72a38f2678 Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Sun, 4 Mar 2018 08:12:03 -0300 Subject: [PATCH 10/16] Refactor contrived match. --- src/librustc_mir/transform/lower_128bit.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index 981b0b854bdab..83cd7bf549d55 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -77,19 +77,12 @@ impl Lower128Bit { }; let bin_statement = block.statements.pop().unwrap(); - let (source_info, place, lhs, mut rhs) = match bin_statement { - Statement { - source_info, - kind: StatementKind::Assign( - place, - Rvalue::BinaryOp(_, lhs, rhs)) - } => (source_info, place, lhs, rhs), - Statement { - source_info, - kind: StatementKind::Assign( - place, - Rvalue::CheckedBinaryOp(_, lhs, rhs)) - } => (source_info, place, lhs, rhs), + let source_info = bin_statement.source_info; + let (place, lhs, mut rhs) = match bin_statement.kind { + StatementKind::Assign(place, Rvalue::BinaryOp(_, lhs, rhs)) + | StatementKind::Assign(place, Rvalue::CheckedBinaryOp(_, lhs, rhs)) => { + (place, lhs, rhs) + } _ => bug!("Statement doesn't match pattern any more?"), }; From 1c191b209b3af4f23e4bb1c249e0f259f2ee0390 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 26 Feb 2018 15:04:40 +0100 Subject: [PATCH 11/16] Add note for unterminated raw string error --- src/libsyntax/parse/lexer/mod.rs | 33 ++++++++++++++++++++++++-------- src/test/ui/raw_string.rs | 14 ++++++++++++++ src/test/ui/raw_string.stderr | 8 ++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/raw_string.rs create mode 100644 src/test/ui/raw_string.stderr diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b5368b3ecabdd..94195ccc72c49 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -132,6 +132,18 @@ impl<'a> StringReader<'a> { self.advance_token()?; Ok(ret_val) } + + fn fail_unterminated_raw_string(&self, pos: BytePos, hash_count: usize) { + let mut err = self.struct_span_fatal(pos, pos, "unterminated raw string"); + err.span_label(self.mk_sp(pos, pos), "unterminated raw string"); + if hash_count > 0 { + err.note(&format!("this raw string should be terminated with `\"{}`", + "#".repeat(hash_count))); + } + err.emit(); + FatalError.raise(); + } + fn fatal(&self, m: &str) -> FatalError { self.fatal_span(self.peek_span, m) } @@ -269,6 +281,15 @@ impl<'a> StringReader<'a> { Self::push_escaped_char_for_msg(&mut m, c); self.fatal_span_(from_pos, to_pos, &m[..]) } + + fn struct_span_fatal(&self, + from_pos: BytePos, + to_pos: BytePos, + m: &str) + -> DiagnosticBuilder<'a> { + self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), m) + } + fn struct_fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, @@ -1404,8 +1425,7 @@ impl<'a> StringReader<'a> { } if self.is_eof() { - let last_bpos = self.pos; - self.fatal_span_(start_bpos, last_bpos, "unterminated raw string").raise(); + self.fail_unterminated_raw_string(start_bpos, hash_count); } else if !self.ch_is('"') { let last_bpos = self.pos; let curr_char = self.ch.unwrap(); @@ -1421,8 +1441,7 @@ impl<'a> StringReader<'a> { let mut valid = true; 'outer: loop { if self.is_eof() { - let last_bpos = self.pos; - self.fatal_span_(start_bpos, last_bpos, "unterminated raw string").raise(); + self.fail_unterminated_raw_string(start_bpos, hash_count); } // if self.ch_is('"') { // content_end_bpos = self.pos; @@ -1636,8 +1655,7 @@ impl<'a> StringReader<'a> { } if self.is_eof() { - let pos = self.pos; - self.fatal_span_(start_bpos, pos, "unterminated raw string").raise(); + self.fail_unterminated_raw_string(start_bpos, hash_count); } else if !self.ch_is('"') { let pos = self.pos; let ch = self.ch.unwrap(); @@ -1653,8 +1671,7 @@ impl<'a> StringReader<'a> { 'outer: loop { match self.ch { None => { - let pos = self.pos; - self.fatal_span_(start_bpos, pos, "unterminated raw string").raise() + self.fail_unterminated_raw_string(start_bpos, hash_count); } Some('"') => { content_end_bpos = self.pos; diff --git a/src/test/ui/raw_string.rs b/src/test/ui/raw_string.rs new file mode 100644 index 0000000000000..f1eb91d44fda0 --- /dev/null +++ b/src/test/ui/raw_string.rs @@ -0,0 +1,14 @@ +// 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 main() { + let x = r##"lol"#; + //~^ ERROR unterminated raw string +} diff --git a/src/test/ui/raw_string.stderr b/src/test/ui/raw_string.stderr new file mode 100644 index 0000000000000..b8aa596ef953a --- /dev/null +++ b/src/test/ui/raw_string.stderr @@ -0,0 +1,8 @@ +error: unterminated raw string + --> $DIR/raw_string.rs:12:13 + | +LL | let x = r##"lol"#; + | ^ unterminated raw string + | + = note: this raw string should be terminated with `"##` + From 16ac85ce4dce1e185f2e6ce27df3833e07a9e502 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 4 Mar 2018 14:58:10 +0100 Subject: [PATCH 12/16] Remove useless powerpc64 entry from ARCH_TABLE, closes #47737 --- src/test/codegen/abi-main-signature-16bit-c-int.rs | 1 - src/test/codegen/fastcall-inreg.rs | 2 -- src/test/codegen/global_asm.rs | 2 -- src/test/codegen/global_asm_include.rs | 2 -- src/test/codegen/global_asm_x2.rs | 2 -- src/test/codegen/repr-transparent-aggregates-1.rs | 1 - src/tools/compiletest/src/util.rs | 1 - 7 files changed, 11 deletions(-) diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs index fbe2fd10e7a14..1e02fe4befdf5 100644 --- a/src/test/codegen/abi-main-signature-16bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs @@ -18,7 +18,6 @@ // ignore-hexagon // ignore-mips // ignore-powerpc -// ignore-powerpc64 // ignore-s390x // ignore-sparc // ignore-wasm32 diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs index 346c5da8d1b8d..b24899cc363a0 100644 --- a/src/test/codegen/fastcall-inreg.rs +++ b/src/test/codegen/fastcall-inreg.rs @@ -25,8 +25,6 @@ // ignore-mips64 // ignore-mips64el // ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs index 5bd0c1b4076ee..5661592d0c7b2 100644 --- a/src/test/codegen/global_asm.rs +++ b/src/test/codegen/global_asm.rs @@ -21,8 +21,6 @@ // ignore-mips64 // ignore-mips64el // ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs index 401b1fad566d5..d8b5db12404ac 100644 --- a/src/test/codegen/global_asm_include.rs +++ b/src/test/codegen/global_asm_include.rs @@ -21,8 +21,6 @@ // ignore-mips64 // ignore-mips64el // ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs index 8b59165e9e61b..caa0506550dde 100644 --- a/src/test/codegen/global_asm_x2.rs +++ b/src/test/codegen/global_asm_x2.rs @@ -21,8 +21,6 @@ // ignore-mips64 // ignore-mips64el // ignore-msp430 -// ignore-powerpc64 -// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 2eeed2b788ce2..655e67cf7eefe 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -14,7 +14,6 @@ // ignore-mips // ignore-mips64 // ignore-powerpc -// ignore-powerpc64 // See repr-transparent.rs #![crate_type="lib"] diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 3c9dae915b5a2..cf63cb2e5d901 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -43,7 +43,6 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), - ("powerpc64", "powerpc64"), ("s390x", "s390x"), ("sparc", "sparc"), ("x86_64", "x86_64"), From 88f32d15afac7bc5cff5daca7a0ac80fdedb6dce Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 5 Mar 2018 18:37:05 +0100 Subject: [PATCH 13/16] Remove a couple of `isize` references from hashmap docs Also fix a spelling mistake. --- src/libstd/collections/hash/map.rs | 54 +++++++++++++++--------------- src/libstd/collections/hash/set.rs | 4 +-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 4dfdc23ebee53..b023fec810ec3 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -620,7 +620,7 @@ impl HashMap { /// /// ``` /// use std::collections::HashMap; - /// let mut map: HashMap<&str, isize> = HashMap::new(); + /// let mut map: HashMap<&str, i32> = HashMap::new(); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -637,7 +637,7 @@ impl HashMap { /// /// ``` /// use std::collections::HashMap; - /// let mut map: HashMap<&str, isize> = HashMap::with_capacity(10); + /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -724,7 +724,7 @@ impl HashMap /// use std::collections::hash_map::RandomState; /// /// let hasher = RandomState::new(); - /// let map: HashMap = HashMap::with_hasher(hasher); + /// let map: HashMap = HashMap::with_hasher(hasher); /// let hasher: &RandomState = map.hasher(); /// ``` #[stable(feature = "hashmap_public_hasher", since = "1.9.0")] @@ -741,7 +741,7 @@ impl HashMap /// /// ``` /// use std::collections::HashMap; - /// let map: HashMap = HashMap::with_capacity(100); + /// let map: HashMap = HashMap::with_capacity(100); /// assert!(map.capacity() >= 100); /// ``` #[inline] @@ -770,7 +770,7 @@ impl HashMap /// /// ``` /// use std::collections::HashMap; - /// let mut map: HashMap<&str, isize> = HashMap::new(); + /// let mut map: HashMap<&str, i32> = HashMap::new(); /// map.reserve(10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -849,7 +849,7 @@ impl HashMap /// ``` /// use std::collections::HashMap; /// - /// let mut map: HashMap = HashMap::with_capacity(100); + /// let mut map: HashMap = HashMap::with_capacity(100); /// map.insert(1, 2); /// map.insert(3, 4); /// assert!(map.capacity() >= 100); @@ -1306,7 +1306,7 @@ impl HashMap /// ``` /// use std::collections::HashMap; /// - /// let mut map: HashMap = (0..8).map(|x|(x, x*10)).collect(); + /// let mut map: HashMap = (0..8).map(|x|(x, x*10)).collect(); /// map.retain(|&k, _| k % 2 == 0); /// assert_eq!(map.len(), 4); /// ``` @@ -1722,7 +1722,7 @@ impl IntoIterator for HashMap /// map.insert("c", 3); /// /// // Not possible with .iter() - /// let vec: Vec<(&str, isize)> = map.into_iter().collect(); + /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); /// ``` fn into_iter(self) -> IntoIter { IntoIter { inner: self.table.into_iter() } @@ -2786,24 +2786,24 @@ mod test_map { assert_eq!(m2.len(), 2); } - thread_local! { static DROP_VECTOR: RefCell> = RefCell::new(Vec::new()) } + thread_local! { static DROP_VECTOR: RefCell> = RefCell::new(Vec::new()) } #[derive(Hash, PartialEq, Eq)] - struct Dropable { + struct Droppable { k: usize, } - impl Dropable { - fn new(k: usize) -> Dropable { + impl Droppable { + fn new(k: usize) -> Droppable { DROP_VECTOR.with(|slot| { slot.borrow_mut()[k] += 1; }); - Dropable { k: k } + Droppable { k: k } } } - impl Drop for Dropable { + impl Drop for Droppable { fn drop(&mut self) { DROP_VECTOR.with(|slot| { slot.borrow_mut()[self.k] -= 1; @@ -2811,9 +2811,9 @@ mod test_map { } } - impl Clone for Dropable { - fn clone(&self) -> Dropable { - Dropable::new(self.k) + impl Clone for Droppable { + fn clone(&self) -> Droppable { + Droppable::new(self.k) } } @@ -2833,8 +2833,8 @@ mod test_map { }); for i in 0..100 { - let d1 = Dropable::new(i); - let d2 = Dropable::new(i + 100); + let d1 = Droppable::new(i); + let d2 = Droppable::new(i + 100); m.insert(d1, d2); } @@ -2845,7 +2845,7 @@ mod test_map { }); for i in 0..50 { - let k = Dropable::new(i); + let k = Droppable::new(i); let v = m.remove(&k); assert!(v.is_some()); @@ -2892,8 +2892,8 @@ mod test_map { }); for i in 0..100 { - let d1 = Dropable::new(i); - let d2 = Dropable::new(i + 100); + let d1 = Droppable::new(i); + let d2 = Droppable::new(i + 100); hm.insert(d1, d2); } @@ -2943,13 +2943,13 @@ mod test_map { #[test] fn test_empty_remove() { - let mut m: HashMap = HashMap::new(); + let mut m: HashMap = HashMap::new(); assert_eq!(m.remove(&0), None); } #[test] fn test_empty_entry() { - let mut m: HashMap = HashMap::new(); + let mut m: HashMap = HashMap::new(); match m.entry(0) { Occupied(_) => panic!(), Vacant(_) => {} @@ -2960,7 +2960,7 @@ mod test_map { #[test] fn test_empty_iter() { - let mut m: HashMap = HashMap::new(); + let mut m: HashMap = HashMap::new(); assert_eq!(m.drain().next(), None); assert_eq!(m.keys().next(), None); assert_eq!(m.values().next(), None); @@ -3461,7 +3461,7 @@ mod test_map { fn test_entry_take_doesnt_corrupt() { #![allow(deprecated)] //rand // Test for #19292 - fn check(m: &HashMap) { + fn check(m: &HashMap) { for k in m.keys() { assert!(m.contains_key(k), "{} is in keys() but not in the map?", k); @@ -3570,7 +3570,7 @@ mod test_map { #[test] fn test_retain() { - let mut map: HashMap = (0..100).map(|x|(x, x*10)).collect(); + let mut map: HashMap = (0..100).map(|x|(x, x*10)).collect(); map.retain(|&k, _| k % 2 == 0); assert_eq!(map.len(), 50); diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index e9427fb40a016..67d413b5a38c4 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -724,7 +724,7 @@ impl HashSet /// use std::collections::HashSet; /// /// let xs = [1,2,3,4,5,6]; - /// let mut set: HashSet = xs.iter().cloned().collect(); + /// let mut set: HashSet = xs.iter().cloned().collect(); /// set.retain(|&k| k % 2 == 0); /// assert_eq!(set.len(), 3); /// ``` @@ -1745,7 +1745,7 @@ mod test_set { #[test] fn test_retain() { let xs = [1, 2, 3, 4, 5, 6]; - let mut set: HashSet = xs.iter().cloned().collect(); + let mut set: HashSet = xs.iter().cloned().collect(); set.retain(|&k| k % 2 == 0); assert_eq!(set.len(), 3); assert!(set.contains(&2)); From 2e7e68b76223b9f14b54852584a5334f33a8798d Mon Sep 17 00:00:00 2001 From: "leonardo.yvens" Date: Mon, 5 Mar 2018 15:58:54 -0300 Subject: [PATCH 14/16] while let all the things --- src/librustc/hir/print.rs | 9 ++------ src/librustc/middle/reachable.rs | 6 +---- .../obligation_forest/mod.rs | 8 +------ src/libstd/sys_common/wtf8.rs | 23 ++++++++----------- src/libsyntax_ext/format.rs | 17 +++++--------- src/libsyntax_pos/lib.rs | 7 +----- 6 files changed, 20 insertions(+), 50 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index ed8cea3eb6563..d91aa3a385193 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -2208,13 +2208,8 @@ impl<'a> State<'a> { if self.next_comment().is_none() { self.s.hardbreak()?; } - loop { - match self.next_comment() { - Some(ref cmnt) => { - self.print_comment(cmnt)?; - } - _ => break, - } + while let Some(ref cmnt) = self.next_comment() { + self.print_comment(cmnt)? } Ok(()) } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 749685182a8f4..5658b5b683291 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -206,11 +206,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // Step 2: Mark all symbols that the symbols on the worklist touch. fn propagate(&mut self) { let mut scanned = FxHashSet(); - loop { - let search_item = match self.worklist.pop() { - Some(item) => item, - None => break, - }; + while let Some(search_item) = self.worklist.pop() { if !scanned.insert(search_item) { continue } diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 02cae52166ac3..42a17d33fa6f5 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -415,13 +415,7 @@ impl ObligationForest { } } - loop { - // non-standard `while let` to bypass #6393 - let i = match error_stack.pop() { - Some(i) => i, - None => break - }; - + while let Some(i) = error_stack.pop() { let node = &self.nodes[i]; match node.state.get() { diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 46d554d6411be..9fff8b91f96f3 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -428,20 +428,15 @@ impl fmt::Debug for Wtf8 { formatter.write_str("\"")?; let mut pos = 0; - loop { - match self.next_surrogate(pos) { - None => break, - Some((surrogate_pos, surrogate)) => { - write_str_escaped( - formatter, - unsafe { str::from_utf8_unchecked( - &self.bytes[pos .. surrogate_pos] - )}, - )?; - write!(formatter, "\\u{{{:x}}}", surrogate)?; - pos = surrogate_pos + 3; - } - } + while let Some((surrogate_pos, surrogate)) = self.next_surrogate(pos) { + write_str_escaped( + formatter, + unsafe { str::from_utf8_unchecked( + &self.bytes[pos .. surrogate_pos] + )}, + )?; + write!(formatter, "\\u{{{:x}}}", surrogate)?; + pos = surrogate_pos + 3; } write_str_escaped( formatter, diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index a7822414c6959..8fd95aa1ca861 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -732,18 +732,13 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, let mut parser = parse::Parser::new(fmt_str); let mut pieces = vec![]; - loop { - match parser.next() { - Some(mut piece) => { - if !parser.errors.is_empty() { - break; - } - cx.verify_piece(&piece); - cx.resolve_name_inplace(&mut piece); - pieces.push(piece); - } - None => break, + while let Some(mut piece) = parser.next() { + if !parser.errors.is_empty() { + break; } + cx.verify_piece(&piece); + cx.resolve_name_inplace(&mut piece); + pieces.push(piece); } let numbered_position_args = pieces.iter().any(|arg: &parse::Piece| { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 9f746adbe6573..ed9eb5d5c9261 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -322,12 +322,7 @@ impl Span { pub fn macro_backtrace(mut self) -> Vec { let mut prev_span = DUMMY_SP; let mut result = vec![]; - loop { - let info = match self.ctxt().outer().expn_info() { - Some(info) => info, - None => break, - }; - + while let Some(info) = self.ctxt().outer().expn_info() { let (pre, post) = match info.callee.format { ExpnFormat::MacroAttribute(..) => ("#[", "]"), ExpnFormat::MacroBang(..) => ("", "!"), From 831009f035683ac48ad7a92631e3fd7cd9d2f08b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 24 Feb 2018 19:14:36 +0100 Subject: [PATCH 15/16] Add resource-suffix option for rustdoc --- src/librustdoc/html/layout.rs | 27 ++++++++------ src/librustdoc/html/render.rs | 51 +++++++++++++++++++-------- src/librustdoc/html/static/storage.js | 4 ++- src/librustdoc/lib.rs | 9 +++++ 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index fd14513cac48f..0151a8c3ab715 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -28,6 +28,7 @@ pub struct Page<'a> { pub root_path: &'a str, pub description: &'a str, pub keywords: &'a str, + pub resource_suffix: &'a str, } pub fn render( @@ -47,12 +48,13 @@ r##" {title} - - + + {themes} - - - + + + {css_extension} {favicon} @@ -76,11 +78,11 @@ r##"
- +