Change:
The only way to introspect reason of failure is to compare to error messages returned by description or use the following code snippet:
Note that this was purposefully done to avoid adding extra surface for now. It should be able to expose this information through an in the future, for example.
Triage: no change here. is the intention still to change this to an enum of some kind in the future?
Any reason to postpone this further?
I don't think it's postponed. I think someone just needs to propose an API?
Hey, we already have an enum , just want to check if anything still need to be done to make it
I just brushed up against this issue while demoing the guessing game example from the Rust Book - seemed like an easy thing to show off matching on the error kind, but turned out not so much!
I also wanted to match in the number game to abort on EOF, turned out to be impossible.
you can just check if the string's empty before parsing, right?
I guess, but it was a fun exercise in pattern matching.
I see that checking for empty has come up in the context of the guessing game tutorial. Could somebody make a list of use cases from real code that needs to be able to distinguish between the following other ParseIntError cases? invalid digit number too large to fit in target type number too small to fit in target type In the event that empty is the only one we ever need to introspect for, I would prefer to close this and instead recommend to check before parsing.
It can be convenient to distinguish too large/too small numbers when accepting configuration parameters that the code will later sanitize by clamping to a valid range. Specifically, they make it possible to perform saturation of the parsed value before it is passed on. Example: the valid range of offsets is -10..+10, therefore the application stores it in an . When the value it outside of the -10..+10 range the app would like to warn the user and proceed with the nearest legitimate value. Without the ability to discriminate if the number is too big/small, it is not possible to determine what is the nearest legitimate value.
do you think that use case would be solved by
Yes, that use case would be covered if Rust had the ability to parse a (and in a convenient way, too!)
The only way I found around this problem was to do something ugly like this: What is so annoying is that shows me , but is private so we can't access it. Either should be made public or a function should be implemented to access to.
I'm doing custom type parsing (something like this: ), and I'd actually like to map the errors into my own custom error type. Yes, I could implement my own integer parsing, but that would defeat the purpose of having a built-in integer parser. My map would be something like this: -(because the whole thing isn't empty, just one of the number portions) / -/ (although I'd be fine with just overflow, a la ) - I can't do that at the moment without resorting to 's trick. It also makes testing very difficult, because I can't tell what error I got back (except by checking the string).
Hello everyone. My fixes this issue and has been merged. Use the feature flag in nightly to try it out.
If this is to be stabilized, I think that the terminology has to be improved: uses to refer to negative overflow, but underflow usually means when the absolute value of a floating-point number is so small it becomes 0 (or a subnormal).
Maybe and ?
This will also solve my use case described in .
What is missing to make it stable?
I would find this useful for to distinguish between "0" and an invalid number.
Before stabilizing, would it be very complicated to additionally add the byte index where parsing failed? I can imagine that information being useful to an introspector (for example, to print a verbose rust-like arrow pointing to the exact location of the parse failure).
Should be easy to do. I will probably open a PR with that soon so people discuss it.
It has been over half a year since , and the indexing question is rejected in , so I guess we can submit another stabilization attempt?
It seems has been stabilized, but what about float error matching? Maybe there are reasons for not to stabilize it?
There's currently no feature but I don't think there's anything blocking someone from making one. Someone would need to propose an API and leave it as an unstable feature for some time before stabilizing

Discussion:
#![feature(crate_visibility_modifier)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] <del> #![feature(int_error_matching)] </del> #![feature(half_open_range_patterns)] #![feature(exclusive_range_pattern)] #![feature(control_flow_enum)]

#![feature(slice_ptr_get)] #![feature(no_niche)] // rust-lang/rust#68303 #![feature(no_coverage)] // rust-lang/rust#84605 <del> #![feature(int_error_matching)] </del> #![cfg_attr(bootstrap, feature(target_feature_11))] #![deny(unsafe_op_in_unsafe_fn)] #![deny(or_patterns_back_compat)]

/// # Example /// /// ``` <del> /// #![feature(int_error_matching)] /// </del> /// # fn main() { /// if let Err(e) = i32::from_str_radix("a12", 10) { ///     println!("Failed conversion to i32: {:?}", e.kind()); /// } /// # } /// ``` <del> #[unstable( feature = "int_error_matching", reason = "it can be useful to match errors when making error messages  for integer parsing", issue = "22639" )] </del> <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] pub enum IntErrorKind { /// Value being parsed is empty. /// <del> /// Among other causes, this variant will be constructed when parsing an empty string. </del> <ins> /// This variant will be constructed when parsing an empty string. #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> Empty, /// Contains an invalid digit in its context. ///

/// /// This variant is also constructed when a `+` or `-` is misplaced within a string /// either on its own or in the middle of a number. <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> InvalidDigit, /// Integer is too large to store in target integer type. <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> PosOverflow, /// Integer is too small to store in target integer type. <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> 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. <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> Zero, } impl ParseIntError { /// Outputs the detailed cause of parsing an integer failing. <del> #[unstable( feature = "int_error_matching", reason = "it can be useful to match errors when making error messages  for integer parsing", issue = "22639" )] </del> <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> pub fn kind(&self) -> &IntErrorKind { &self.kind }

#[stable(feature = "try_from", since = "1.34.0")] pub use error::TryFromIntError; <del> #[unstable( feature = "int_error_matching", reason = "it can be useful to match errors when making error messages  for integer parsing", issue = "22639" )] </del> <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> pub use error::IntErrorKind; macro_rules! usize_isize_to_xe_bytes_doc {

#![feature(try_trait_v2)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] <del> #![feature(int_error_matching)] </del> #![feature(iter_advance_by)] #![feature(iter_partition_in_place)] #![feature(iter_intersperse)]

#![feature(global_asm)] #![feature(hashmap_internals)] #![feature(int_error_internals)] <del> #![feature(int_error_matching)] </del> #![feature(integer_atomics)] #![feature(into_future)] #![feature(intra_doc_pointers)]

#[stable(feature = "nonzero", since = "1.28.0")] pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; <del> #[unstable( feature = "int_error_matching", reason = "it can be useful to match errors when making error messages  for integer parsing", issue = "22639" )] </del> <ins> #[stable(feature = "int_error_matching", since = "1.55.0")] </ins> pub use core::num::IntErrorKind; #[cfg(test)]