From c027844795e427e63ef917ba40c71d0559d88b79 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Tue, 6 Oct 2020 14:06:25 +0100 Subject: [PATCH 01/10] Fill in things needed to stabilize int_error_matching --- compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_middle/src/middle/limits.rs | 8 +-- library/core/src/num/error.rs | 33 ++++++------ library/core/src/num/mod.rs | 12 ++--- library/core/tests/lib.rs | 1 - library/core/tests/nonzero.rs | 4 +- library/core/tests/num/mod.rs | 63 +++++++++++++--------- library/std/src/lib.rs | 1 - library/std/src/num.rs | 7 +-- 9 files changed, 66 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index fa885ce2e7cdf..37bc1a305b2f8 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -46,7 +46,6 @@ #![feature(crate_visibility_modifier)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] -#![feature(int_error_matching)] #![recursion_limit = "512"] #[macro_use] diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index def9e5ebb527f..6b6df3a303c22 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -48,10 +48,12 @@ fn update_limit( .unwrap_or(attr.span); let error_str = match e.kind() { - IntErrorKind::Overflow => "`limit` is too large", - IntErrorKind::Empty => "`limit` must be a non-negative integer", + IntErrorKind::PosOverflow => "`limit` is too large", + IntErrorKind::Empty | IntErrorKind::OnlySign => { + "`limit` must be a non-negative integer" + } IntErrorKind::InvalidDigit => "not a valid integer", - IntErrorKind::Underflow => bug!("`limit` should never underflow"), + IntErrorKind::NegOverflow => bug!("`limit` should never underflow"), IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index aab1715518611..9705226ba243a 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -77,51 +77,47 @@ pub struct ParseIntError { /// # Example /// /// ``` -/// #![feature(int_error_matching)] -/// /// # fn main() { /// if let Err(e) = i32::from_str_radix("a12", 10) { /// println!("Failed conversion to i32: {:?}", e.kind()); /// } /// # } /// ``` -#[unstable( - feature = "int_error_matching", - reason = "it can be useful to match errors when making error messages \ - for integer parsing", - issue = "22639" -)] +#[stable(feature = "int_error_matching", since = "1.47.0")] #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum IntErrorKind { /// Value being parsed is empty. /// /// Among other causes, this variant will be constructed when parsing an empty string. + #[stable(feature = "int_error_matching", since = "1.47.0")] Empty, /// Contains an invalid digit. /// /// Among other causes, this variant will be constructed when parsing a string that /// contains a letter. + #[stable(feature = "int_error_matching", since = "1.47.0")] InvalidDigit, /// Integer is too large to store in target integer type. - Overflow, + #[stable(feature = "int_error_matching", since = "1.47.0")] + PosOverflow, /// Integer is too small to store in target integer type. - Underflow, + #[stable(feature = "int_error_matching", since = "1.47.0")] + NegOverflow, /// Value was Zero /// /// This variant will be emitted when the parsing string has a value of zero, which /// would be illegal for non-zero types. + #[stable(feature = "int_error_matching", since = "1.47.0")] Zero, + /// The value contains nothing other than signs `+` or `-`. + #[stable(feature = "int_error_matching", since = "1.47.0")] + OnlySign, } impl ParseIntError { /// Outputs the detailed cause of parsing an integer failing. - #[unstable( - feature = "int_error_matching", - reason = "it can be useful to match errors when making error messages \ - for integer parsing", - issue = "22639" - )] + #[stable(feature = "int_error_matching", since = "1.47.0")] pub fn kind(&self) -> &IntErrorKind { &self.kind } @@ -136,9 +132,10 @@ impl ParseIntError { match self.kind { IntErrorKind::Empty => "cannot parse integer from empty string", IntErrorKind::InvalidDigit => "invalid digit found in string", - IntErrorKind::Overflow => "number too large to fit in target type", - IntErrorKind::Underflow => "number too small to fit in target type", + IntErrorKind::PosOverflow => "number too large to fit in target type", + IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", + IntErrorKind::OnlySign => "only signs without digits found in string", } } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 4f64e30ccf84a..67b4b885dd2ec 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -63,7 +63,7 @@ pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, No #[stable(feature = "try_from", since = "1.34.0")] pub use error::TryFromIntError; -#[unstable(feature = "int_error_matching", issue = "22639")] +#[stable(feature = "int_error_matching", since = "1.47.0")] pub use error::IntErrorKind; macro_rules! usize_isize_to_xe_bytes_doc { @@ -836,7 +836,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result(src: &str, radix: u32) -> Result result, - None => return Err(PIE { kind: Overflow }), + None => return Err(PIE { kind: PosOverflow }), }; result = match result.checked_add(x) { Some(result) => result, - None => return Err(PIE { kind: Overflow }), + None => return Err(PIE { kind: PosOverflow }), }; } } else { @@ -865,11 +865,11 @@ fn from_str_radix(src: &str, radix: u32) -> Result result, - None => return Err(PIE { kind: Underflow }), + None => return Err(PIE { kind: NegOverflow }), }; result = match result.checked_sub(x) { Some(result) => result, - None => return Err(PIE { kind: Underflow }), + None => return Err(PIE { kind: NegOverflow }), }; } } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index d8b36beb3e085..c128691fa7525 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -37,7 +37,6 @@ #![feature(try_trait)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] -#![feature(int_error_matching)] #![feature(array_value_iter)] #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index 825e5e63b59bc..fb1293c99bba9 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -135,11 +135,11 @@ fn test_from_str() { ); assert_eq!( "-129".parse::().err().map(|e| e.kind().clone()), - Some(IntErrorKind::Underflow) + Some(IntErrorKind::NegOverflow) ); assert_eq!( "257".parse::().err().map(|e| e.kind().clone()), - Some(IntErrorKind::Overflow) + Some(IntErrorKind::PosOverflow) ); } diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 939f1325c8499..d6f92f25e7846 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -2,10 +2,11 @@ use core::cmp::PartialEq; use core::convert::{TryFrom, TryInto}; use core::fmt::Debug; use core::marker::Copy; -use core::num::TryFromIntError; +use core::num::{IntErrorKind, ParseIntError, TryFromIntError}; use core::ops::{Add, Div, Mul, Rem, Sub}; use core::option::Option; -use core::option::Option::{None, Some}; +use core::option::Option::None; +use core::str::FromStr; #[macro_use] mod int_macros; @@ -65,6 +66,14 @@ where assert_eq!(ten.rem(two), ten % two); } +fn test_parse(num_str: &str, expected: Result) +where + T: FromStr, + Result: PartialEq + Debug, +{ + assert_eq!(num_str.parse::().map_err(|e| e.kind().clone()), expected) +} + #[test] fn from_str_issue7588() { let u: Option = u8::from_str_radix("1000", 10).ok(); @@ -75,49 +84,51 @@ fn from_str_issue7588() { #[test] fn test_int_from_str_overflow() { - assert_eq!("127".parse::().ok(), Some(127i8)); - assert_eq!("128".parse::().ok(), None); + test_parse::("127", Ok(127)); + test_parse::("128", Err(IntErrorKind::PosOverflow)); - assert_eq!("-128".parse::().ok(), Some(-128i8)); - assert_eq!("-129".parse::().ok(), None); + test_parse::("-128", Ok(-128)); + test_parse::("-129", Err(IntErrorKind::NegOverflow)); - assert_eq!("32767".parse::().ok(), Some(32_767i16)); - assert_eq!("32768".parse::().ok(), None); + test_parse::("32767", Ok(32_767)); + test_parse::("32768", Err(IntErrorKind::PosOverflow)); - assert_eq!("-32768".parse::().ok(), Some(-32_768i16)); - assert_eq!("-32769".parse::().ok(), None); + test_parse::("-32768", Ok(-32_768)); + test_parse::("-32769", Err(IntErrorKind::NegOverflow)); - assert_eq!("2147483647".parse::().ok(), Some(2_147_483_647i32)); - assert_eq!("2147483648".parse::().ok(), None); + test_parse::("2147483647", Ok(2_147_483_647)); + test_parse::("2147483648", Err(IntErrorKind::PosOverflow)); - assert_eq!("-2147483648".parse::().ok(), Some(-2_147_483_648i32)); - assert_eq!("-2147483649".parse::().ok(), None); + test_parse::("-2147483648", Ok(-2_147_483_648)); + test_parse::("-2147483649", Err(IntErrorKind::NegOverflow)); - assert_eq!("9223372036854775807".parse::().ok(), Some(9_223_372_036_854_775_807i64)); - assert_eq!("9223372036854775808".parse::().ok(), None); + test_parse::("9223372036854775807", Ok(9_223_372_036_854_775_807)); + test_parse::("9223372036854775808", Err(IntErrorKind::PosOverflow)); - assert_eq!("-9223372036854775808".parse::().ok(), Some(-9_223_372_036_854_775_808i64)); - assert_eq!("-9223372036854775809".parse::().ok(), None); + test_parse::("-9223372036854775808", Ok(-9_223_372_036_854_775_808)); + test_parse::("-9223372036854775809", Err(IntErrorKind::NegOverflow)); } #[test] fn test_leading_plus() { - assert_eq!("+127".parse::().ok(), Some(127)); - assert_eq!("+9223372036854775807".parse::().ok(), Some(9223372036854775807)); + test_parse::("+127", Ok(127)); + test_parse::("+9223372036854775807", Ok(9223372036854775807)); } #[test] fn test_invalid() { - assert_eq!("--129".parse::().ok(), None); - assert_eq!("++129".parse::().ok(), None); - assert_eq!("Съешь".parse::().ok(), None); + test_parse::("--129", Err(IntErrorKind::InvalidDigit)); + test_parse::("++129", Err(IntErrorKind::InvalidDigit)); + test_parse::("Съешь", Err(IntErrorKind::InvalidDigit)); + // is this the correct error here. Maybe need a reapeat sign error here + test_parse::("--", Err(IntErrorKind::InvalidDigit)); } #[test] fn test_empty() { - assert_eq!("-".parse::().ok(), None); - assert_eq!("+".parse::().ok(), None); - assert_eq!("".parse::().ok(), None); + test_parse::("-", Err(IntErrorKind::OnlySign)); + test_parse::("+", Err(IntErrorKind::OnlySign)); + test_parse::("", Err(IntErrorKind::Empty)); } #[test] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ac0075ad129c5..fa23229066cf1 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -264,7 +264,6 @@ #![feature(global_asm)] #![feature(hashmap_internals)] #![feature(int_error_internals)] -#![feature(int_error_matching)] #![feature(integer_atomics)] #![feature(into_future)] #![feature(lang_items)] diff --git a/library/std/src/num.rs b/library/std/src/num.rs index 0f1c596268594..ac3b055cdb050 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -22,12 +22,7 @@ pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, #[stable(feature = "nonzero", since = "1.28.0")] pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; -#[unstable( - feature = "int_error_matching", - reason = "it can be useful to match errors when making error messages \ - for integer parsing", - issue = "22639" -)] +#[stable(feature = "int_error_matching", since = "1.47.0")] pub use core::num::IntErrorKind; #[cfg(test)] From 83d294f06a8f78f4956333a5285bb2c4f7b8a6a9 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Tue, 6 Oct 2020 19:05:25 +0100 Subject: [PATCH 02/10] Bring char along with InvalidDigit --- compiler/rustc_middle/src/middle/limits.rs | 2 +- library/core/src/num/error.rs | 6 +++--- library/core/src/num/mod.rs | 4 ++-- library/core/tests/nonzero.rs | 2 +- library/core/tests/num/mod.rs | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 6b6df3a303c22..f03f439f73b5a 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -52,7 +52,7 @@ fn update_limit( IntErrorKind::Empty | IntErrorKind::OnlySign => { "`limit` must be a non-negative integer" } - IntErrorKind::InvalidDigit => "not a valid integer", + IntErrorKind::InvalidDigit(_) => "not a valid integer", IntErrorKind::NegOverflow => bug!("`limit` should never underflow"), IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 9705226ba243a..ba7c94656ce3f 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -92,12 +92,12 @@ pub enum IntErrorKind { /// Among other causes, this variant will be constructed when parsing an empty string. #[stable(feature = "int_error_matching", since = "1.47.0")] Empty, - /// Contains an invalid digit. + /// Contains an digit invalid in its context. /// /// Among other causes, this variant will be constructed when parsing a string that /// contains a letter. #[stable(feature = "int_error_matching", since = "1.47.0")] - InvalidDigit, + InvalidDigit(#[stable(feature = "int_error_matching", since = "1.47.0")] char), /// Integer is too large to store in target integer type. #[stable(feature = "int_error_matching", since = "1.47.0")] PosOverflow, @@ -131,7 +131,7 @@ impl ParseIntError { pub fn __description(&self) -> &str { match self.kind { IntErrorKind::Empty => "cannot parse integer from empty string", - IntErrorKind::InvalidDigit => "invalid digit found in string", + IntErrorKind::InvalidDigit(_) => "invalid digit found in string", IntErrorKind::PosOverflow => "number too large to fit in target type", IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 67b4b885dd2ec..a438f3161a3af 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -845,7 +845,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result x, - None => return Err(PIE { kind: InvalidDigit }), + None => return Err(PIE { kind: InvalidDigit(c as char) }), }; result = match result.checked_mul(radix) { Some(result) => result, @@ -861,7 +861,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result x, - None => return Err(PIE { kind: InvalidDigit }), + None => return Err(PIE { kind: InvalidDigit(c as char) }), }; result = match result.checked_mul(radix) { Some(result) => result, diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index fb1293c99bba9..949d4ea32f064 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -131,7 +131,7 @@ fn test_from_str() { assert_eq!("0".parse::().err().map(|e| e.kind().clone()), Some(IntErrorKind::Zero)); assert_eq!( "-1".parse::().err().map(|e| e.kind().clone()), - Some(IntErrorKind::InvalidDigit) + Some(IntErrorKind::InvalidDigit('-')) ); assert_eq!( "-129".parse::().err().map(|e| e.kind().clone()), diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index d6f92f25e7846..a93cd38160b58 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -117,11 +117,11 @@ fn test_leading_plus() { #[test] fn test_invalid() { - test_parse::("--129", Err(IntErrorKind::InvalidDigit)); - test_parse::("++129", Err(IntErrorKind::InvalidDigit)); - test_parse::("Съешь", Err(IntErrorKind::InvalidDigit)); - // is this the correct error here. Maybe need a reapeat sign error here - test_parse::("--", Err(IntErrorKind::InvalidDigit)); + test_parse::("--129", Err(IntErrorKind::InvalidDigit('-'))); + test_parse::("++129", Err(IntErrorKind::InvalidDigit('+'))); + test_parse::("Съешь", Err(IntErrorKind::InvalidDigit('Ð'))); + test_parse::("123Hello", Err(IntErrorKind::InvalidDigit('H'))); + test_parse::("--", Err(IntErrorKind::InvalidDigit('-'))); } #[test] From 8eaf0de1f45924a0fdbde00d4c7fe0333b377993 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Tue, 6 Oct 2020 21:03:10 +0100 Subject: [PATCH 03/10] Remove incorrect plural --- library/core/src/num/error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index ba7c94656ce3f..a8f8a7804fd78 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -110,7 +110,7 @@ pub enum IntErrorKind { /// would be illegal for non-zero types. #[stable(feature = "int_error_matching", since = "1.47.0")] Zero, - /// The value contains nothing other than signs `+` or `-`. + /// The value contains nothing other than sign `+` or `-`. #[stable(feature = "int_error_matching", since = "1.47.0")] OnlySign, } @@ -135,7 +135,7 @@ impl ParseIntError { IntErrorKind::PosOverflow => "number too large to fit in target type", IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", - IntErrorKind::OnlySign => "only signs without digits found in string", + IntErrorKind::OnlySign => "only sign without digits found in string", } } } From 1e7e2e40e4992a82b9e5bc7120bd33964bcef355 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Tue, 6 Oct 2020 22:42:33 +0100 Subject: [PATCH 04/10] remove OnlySign in favour of InvalidDigit --- compiler/rustc_middle/src/middle/limits.rs | 4 +--- library/core/src/num/error.rs | 9 ++++----- library/core/src/num/mod.rs | 7 +++---- library/core/tests/num/mod.rs | 5 +++-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index f03f439f73b5a..e0d171fa77125 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -49,9 +49,7 @@ fn update_limit( let error_str = match e.kind() { IntErrorKind::PosOverflow => "`limit` is too large", - IntErrorKind::Empty | IntErrorKind::OnlySign => { - "`limit` must be a non-negative integer" - } + IntErrorKind::Empty => "`limit` must be a non-negative integer", IntErrorKind::InvalidDigit(_) => "not a valid integer", IntErrorKind::NegOverflow => bug!("`limit` should never underflow"), IntErrorKind::Zero => bug!("zero is a valid `limit`"), diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index a8f8a7804fd78..401d52eb08481 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -95,7 +95,10 @@ pub enum IntErrorKind { /// Contains an digit invalid in its context. /// /// Among other causes, this variant will be constructed when parsing a string that - /// contains a letter. + /// contains a non-asci char. + /// + /// This variant is also constructed when a `+` or `-` is misplaced within a sting + /// either on its own or in the middle of a number. #[stable(feature = "int_error_matching", since = "1.47.0")] InvalidDigit(#[stable(feature = "int_error_matching", since = "1.47.0")] char), /// Integer is too large to store in target integer type. @@ -110,9 +113,6 @@ pub enum IntErrorKind { /// would be illegal for non-zero types. #[stable(feature = "int_error_matching", since = "1.47.0")] Zero, - /// The value contains nothing other than sign `+` or `-`. - #[stable(feature = "int_error_matching", since = "1.47.0")] - OnlySign, } impl ParseIntError { @@ -135,7 +135,6 @@ impl ParseIntError { IntErrorKind::PosOverflow => "number too large to fit in target type", IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", - IntErrorKind::OnlySign => "only sign without digits found in string", } } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index a438f3161a3af..fd00a072d896c 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -830,15 +830,14 @@ fn from_str_radix(src: &str, radix: u32) -> Result { + return Err(PIE { kind: InvalidDigit(src[0] as char) }); + } b'+' => (true, &src[1..]), b'-' if is_signed_ty => (false, &src[1..]), _ => (true, src), }; - if digits.is_empty() { - return Err(PIE { kind: OnlySign }); - } - let mut result = T::from_u32(0); if is_positive { // The number is positive diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index a93cd38160b58..4fd9f721b823b 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -122,12 +122,13 @@ fn test_invalid() { test_parse::("Съешь", Err(IntErrorKind::InvalidDigit('Ð'))); test_parse::("123Hello", Err(IntErrorKind::InvalidDigit('H'))); test_parse::("--", Err(IntErrorKind::InvalidDigit('-'))); + test_parse::("-", Err(IntErrorKind::InvalidDigit('-'))); + test_parse::("+", Err(IntErrorKind::InvalidDigit('+'))); + test_parse::("-1", Err(IntErrorKind::InvalidDigit('-'))); } #[test] fn test_empty() { - test_parse::("-", Err(IntErrorKind::OnlySign)); - test_parse::("+", Err(IntErrorKind::OnlySign)); test_parse::("", Err(IntErrorKind::Empty)); } From f233abb9091e3c0999f0cb80ba652d6094e3d5b4 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Wed, 7 Oct 2020 08:02:36 +0100 Subject: [PATCH 05/10] Add comment to helper function --- library/core/tests/num/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 4fd9f721b823b..12e52252278c5 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -66,6 +66,7 @@ where assert_eq!(ten.rem(two), ten % two); } +/// Helper function for asserting number parsing returns a specific error fn test_parse(num_str: &str, expected: Result) where T: FromStr, From 199c36115f1daa71458e94db0f37ab213d01eb8a Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Mon, 26 Oct 2020 05:50:28 -0500 Subject: [PATCH 06/10] Fix spelling eror Co-authored-by: Ashley Mannix --- library/core/src/num/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 401d52eb08481..91a24e7740ad4 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -97,7 +97,7 @@ pub enum IntErrorKind { /// Among other causes, this variant will be constructed when parsing a string that /// contains a non-asci char. /// - /// This variant is also constructed when a `+` or `-` is misplaced within a sting + /// This variant is also constructed when a `+` or `-` is misplaced within a string /// either on its own or in the middle of a number. #[stable(feature = "int_error_matching", since = "1.47.0")] InvalidDigit(#[stable(feature = "int_error_matching", since = "1.47.0")] char), From 69c301f0f36696f93a90bb7a6afe9081b0d04233 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Mon, 26 Oct 2020 05:51:07 -0500 Subject: [PATCH 07/10] Small reword Co-authored-by: Ashley Mannix --- library/core/src/num/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 91a24e7740ad4..d1a65aa35ae25 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -92,7 +92,7 @@ pub enum IntErrorKind { /// Among other causes, this variant will be constructed when parsing an empty string. #[stable(feature = "int_error_matching", since = "1.47.0")] Empty, - /// Contains an digit invalid in its context. + /// Contains an invalid digit in its context. /// /// Among other causes, this variant will be constructed when parsing a string that /// contains a non-asci char. From 75e6deefee8dc68fc35bdfe5effbfdb517b03f9c Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Mon, 26 Oct 2020 05:51:22 -0500 Subject: [PATCH 08/10] asci -> ASCII Co-authored-by: Ashley Mannix --- library/core/src/num/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index d1a65aa35ae25..e1684719ab4ec 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -95,7 +95,7 @@ pub enum IntErrorKind { /// Contains an invalid digit in its context. /// /// Among other causes, this variant will be constructed when parsing a string that - /// contains a non-asci char. + /// contains a non-ASCII char. /// /// This variant is also constructed when a `+` or `-` is misplaced within a string /// either on its own or in the middle of a number. From ad2d93da1f051970555a8be0baa8e6277b3a06c1 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Mon, 26 Oct 2020 18:14:12 +0000 Subject: [PATCH 09/10] Apply suggested changes --- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/middle/limits.rs | 6 ++++-- library/core/src/lib.rs | 1 + library/core/src/num/error.rs | 25 ++++++++++++++-------- library/core/src/num/mod.rs | 13 +++++++---- library/core/tests/lib.rs | 1 + library/core/tests/nonzero.rs | 2 +- library/core/tests/num/mod.rs | 16 +++++++------- library/std/src/lib.rs | 1 + library/std/src/num.rs | 7 +++++- 10 files changed, 48 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 37bc1a305b2f8..fa885ce2e7cdf 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -46,6 +46,7 @@ #![feature(crate_visibility_modifier)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] +#![feature(int_error_matching)] #![recursion_limit = "512"] #[macro_use] diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index e0d171fa77125..9ff2b7f08fe04 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -50,8 +50,10 @@ fn update_limit( let error_str = match e.kind() { IntErrorKind::PosOverflow => "`limit` is too large", IntErrorKind::Empty => "`limit` must be a non-negative integer", - IntErrorKind::InvalidDigit(_) => "not a valid integer", - IntErrorKind::NegOverflow => bug!("`limit` should never underflow"), + IntErrorKind::InvalidDigit => "not a valid integer", + IntErrorKind::NegOverflow => { + bug!("`limit` should never negatively underflow") + } IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind), }; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 63ca6e517d214..d67ad30e123f9 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -151,6 +151,7 @@ #![feature(slice_ptr_get)] #![feature(no_niche)] // rust-lang/rust#68303 #![feature(unsafe_block_in_unsafe_fn)] +#![feature(int_error_matching)] #![deny(unsafe_op_in_unsafe_fn)] #[prelude_import] diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index e1684719ab4ec..9d8c8c862911c 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -77,20 +77,26 @@ pub struct ParseIntError { /// # Example /// /// ``` +/// #![feature(int_error_matching)] +/// /// # fn main() { /// if let Err(e) = i32::from_str_radix("a12", 10) { /// println!("Failed conversion to i32: {:?}", e.kind()); /// } /// # } /// ``` -#[stable(feature = "int_error_matching", since = "1.47.0")] +#[unstable( + feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639" +)] #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum IntErrorKind { /// Value being parsed is empty. /// /// Among other causes, this variant will be constructed when parsing an empty string. - #[stable(feature = "int_error_matching", since = "1.47.0")] Empty, /// Contains an invalid digit in its context. /// @@ -99,25 +105,26 @@ pub enum IntErrorKind { /// /// This variant is also constructed when a `+` or `-` is misplaced within a string /// either on its own or in the middle of a number. - #[stable(feature = "int_error_matching", since = "1.47.0")] - InvalidDigit(#[stable(feature = "int_error_matching", since = "1.47.0")] char), + InvalidDigit, /// Integer is too large to store in target integer type. - #[stable(feature = "int_error_matching", since = "1.47.0")] PosOverflow, /// Integer is too small to store in target integer type. - #[stable(feature = "int_error_matching", since = "1.47.0")] NegOverflow, /// Value was Zero /// /// This variant will be emitted when the parsing string has a value of zero, which /// would be illegal for non-zero types. - #[stable(feature = "int_error_matching", since = "1.47.0")] Zero, } impl ParseIntError { /// Outputs the detailed cause of parsing an integer failing. - #[stable(feature = "int_error_matching", since = "1.47.0")] + #[unstable( + feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639" + )] pub fn kind(&self) -> &IntErrorKind { &self.kind } @@ -131,7 +138,7 @@ impl ParseIntError { pub fn __description(&self) -> &str { match self.kind { IntErrorKind::Empty => "cannot parse integer from empty string", - IntErrorKind::InvalidDigit(_) => "invalid digit found in string", + IntErrorKind::InvalidDigit => "invalid digit found in string", IntErrorKind::PosOverflow => "number too large to fit in target type", IntErrorKind::NegOverflow => "number too small to fit in target type", IntErrorKind::Zero => "number would be zero for non-zero type", diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index fd00a072d896c..71448a622c09e 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -63,7 +63,12 @@ pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, No #[stable(feature = "try_from", since = "1.34.0")] pub use error::TryFromIntError; -#[stable(feature = "int_error_matching", since = "1.47.0")] +#[unstable( + feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639" +)] pub use error::IntErrorKind; macro_rules! usize_isize_to_xe_bytes_doc { @@ -831,7 +836,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result { - return Err(PIE { kind: InvalidDigit(src[0] as char) }); + return Err(PIE { kind: InvalidDigit }); } b'+' => (true, &src[1..]), b'-' if is_signed_ty => (false, &src[1..]), @@ -844,7 +849,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result x, - None => return Err(PIE { kind: InvalidDigit(c as char) }), + None => return Err(PIE { kind: InvalidDigit }), }; result = match result.checked_mul(radix) { Some(result) => result, @@ -860,7 +865,7 @@ fn from_str_radix(src: &str, radix: u32) -> Result x, - None => return Err(PIE { kind: InvalidDigit(c as char) }), + None => return Err(PIE { kind: InvalidDigit }), }; result = match result.checked_mul(radix) { Some(result) => result, diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index c128691fa7525..d8b36beb3e085 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -37,6 +37,7 @@ #![feature(try_trait)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] +#![feature(int_error_matching)] #![feature(array_value_iter)] #![feature(iter_partition_in_place)] #![feature(iter_is_partitioned)] diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index 949d4ea32f064..fb1293c99bba9 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -131,7 +131,7 @@ fn test_from_str() { assert_eq!("0".parse::().err().map(|e| e.kind().clone()), Some(IntErrorKind::Zero)); assert_eq!( "-1".parse::().err().map(|e| e.kind().clone()), - Some(IntErrorKind::InvalidDigit('-')) + Some(IntErrorKind::InvalidDigit) ); assert_eq!( "-129".parse::().err().map(|e| e.kind().clone()), diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs index 12e52252278c5..7c25c32fb40a7 100644 --- a/library/core/tests/num/mod.rs +++ b/library/core/tests/num/mod.rs @@ -118,14 +118,14 @@ fn test_leading_plus() { #[test] fn test_invalid() { - test_parse::("--129", Err(IntErrorKind::InvalidDigit('-'))); - test_parse::("++129", Err(IntErrorKind::InvalidDigit('+'))); - test_parse::("Съешь", Err(IntErrorKind::InvalidDigit('Ð'))); - test_parse::("123Hello", Err(IntErrorKind::InvalidDigit('H'))); - test_parse::("--", Err(IntErrorKind::InvalidDigit('-'))); - test_parse::("-", Err(IntErrorKind::InvalidDigit('-'))); - test_parse::("+", Err(IntErrorKind::InvalidDigit('+'))); - test_parse::("-1", Err(IntErrorKind::InvalidDigit('-'))); + test_parse::("--129", Err(IntErrorKind::InvalidDigit)); + test_parse::("++129", Err(IntErrorKind::InvalidDigit)); + test_parse::("Съешь", Err(IntErrorKind::InvalidDigit)); + test_parse::("123Hello", Err(IntErrorKind::InvalidDigit)); + test_parse::("--", Err(IntErrorKind::InvalidDigit)); + test_parse::("-", Err(IntErrorKind::InvalidDigit)); + test_parse::("+", Err(IntErrorKind::InvalidDigit)); + test_parse::("-1", Err(IntErrorKind::InvalidDigit)); } #[test] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index fa23229066cf1..ac0075ad129c5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -264,6 +264,7 @@ #![feature(global_asm)] #![feature(hashmap_internals)] #![feature(int_error_internals)] +#![feature(int_error_matching)] #![feature(integer_atomics)] #![feature(into_future)] #![feature(lang_items)] diff --git a/library/std/src/num.rs b/library/std/src/num.rs index ac3b055cdb050..0f1c596268594 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -22,7 +22,12 @@ pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, #[stable(feature = "nonzero", since = "1.28.0")] pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; -#[stable(feature = "int_error_matching", since = "1.47.0")] +#[unstable( + feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639" +)] pub use core::num::IntErrorKind; #[cfg(test)] From e750238404f59f3f6d94142f3e12ffc4c5c0b366 Mon Sep 17 00:00:00 2001 From: Ethan Brierley Date: Mon, 26 Oct 2020 18:16:25 +0000 Subject: [PATCH 10/10] Fix typo --- compiler/rustc_middle/src/middle/limits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 9ff2b7f08fe04..41342764ba773 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -52,7 +52,7 @@ fn update_limit( IntErrorKind::Empty => "`limit` must be a non-negative integer", IntErrorKind::InvalidDigit => "not a valid integer", IntErrorKind::NegOverflow => { - bug!("`limit` should never negatively underflow") + bug!("`limit` should never negatively overflow") } IntErrorKind::Zero => bug!("zero is a valid `limit`"), kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),