diff --git a/src/Cargo.lock b/Cargo.lock similarity index 100% rename from src/Cargo.lock rename to Cargo.lock diff --git a/src/Cargo.toml b/Cargo.toml similarity index 52% rename from src/Cargo.toml rename to Cargo.toml index c03301852cd3b..69655f8cdc24a 100644 --- a/src/Cargo.toml +++ b/Cargo.toml @@ -1,43 +1,43 @@ [workspace] members = [ - "bootstrap", - "rustc", - "libstd", - "libtest", - "librustc_trans", - "tools/cargotest", - "tools/clippy", - "tools/compiletest", - "tools/error_index_generator", - "tools/linkchecker", - "tools/rustbook", - "tools/unstable-book-gen", - "tools/tidy", - "tools/build-manifest", - "tools/remote-test-client", - "tools/remote-test-server", - "tools/rust-installer", - "tools/cargo", - "tools/rustdoc", - "tools/rls", - "tools/rustfmt", - "tools/miri", - "tools/rustdoc-themes", + "src/bootstrap", + "src/rustc", + "src/libstd", + "src/libtest", + "src/librustc_trans", + "src/tools/cargotest", + "src/tools/clippy", + "src/tools/compiletest", + "src/tools/error_index_generator", + "src/tools/linkchecker", + "src/tools/rustbook", + "src/tools/unstable-book-gen", + "src/tools/tidy", + "src/tools/build-manifest", + "src/tools/remote-test-client", + "src/tools/remote-test-server", + "src/tools/rust-installer", + "src/tools/cargo", + "src/tools/rustdoc", + "src/tools/rls", + "src/tools/rustfmt", + "src/tools/miri", + "src/tools/rustdoc-themes", # FIXME(https://github.com/rust-lang/cargo/issues/4089): move these to exclude - "tools/rls/test_data/bin_lib", - "tools/rls/test_data/borrow_error", - "tools/rls/test_data/common", - "tools/rls/test_data/deglob", - "tools/rls/test_data/features", - "tools/rls/test_data/find_all_refs_no_cfg_test", - "tools/rls/test_data/find_impls", - "tools/rls/test_data/infer_bin", - "tools/rls/test_data/infer_custom_bin", - "tools/rls/test_data/infer_lib", - "tools/rls/test_data/multiple_bins", - "tools/rls/test_data/reformat", - "tools/rls/test_data/reformat_with_range", - "tools/rls/test_data/workspace_symbol", + "src/tools/rls/test_data/bin_lib", + "src/tools/rls/test_data/borrow_error", + "src/tools/rls/test_data/common", + "src/tools/rls/test_data/deglob", + "src/tools/rls/test_data/features", + "src/tools/rls/test_data/find_all_refs_no_cfg_test", + "src/tools/rls/test_data/find_impls", + "src/tools/rls/test_data/infer_bin", + "src/tools/rls/test_data/infer_custom_bin", + "src/tools/rls/test_data/infer_lib", + "src/tools/rls/test_data/multiple_bins", + "src/tools/rls/test_data/reformat", + "src/tools/rls/test_data/reformat_with_range", + "src/tools/rls/test_data/workspace_symbol", ] # Curiously, compiletest will segfault if compiled with opt-level=3 on 64-bit @@ -63,7 +63,7 @@ debug-assertions = false # so we use a `[patch]` here to override the github repository with our local # vendored copy. [patch."https://github.com/rust-lang/cargo"] -cargo = { path = "tools/cargo" } +cargo = { path = "src/tools/cargo" } [patch.crates-io] # Similar to Cargo above we want the RLS to use a vendored version of `rustfmt` @@ -71,4 +71,4 @@ cargo = { path = "tools/cargo" } # `rustfmt` executable are the same exact vesion). Unlike Cargo, however, the # RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section # for crates.io -rustfmt-nightly = { path = "tools/rustfmt" } +rustfmt-nightly = { path = "src/tools/rustfmt" } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 21d4a486b9833..418f9c29140d0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -96,132 +96,156 @@ pub mod dec2flt; pub mod bignum; pub mod diy_float; +macro_rules! doc_comment { + ($x:expr, $($tt:tt)*) => { + #[doc = $x] + $($tt)* + }; +} + // `Int` + `SignedInt` implemented for signed integers macro_rules! int_impl { - ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr) => { - /// Returns the smallest value that can be represented by this integer type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(i8::min_value(), -128); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub const fn min_value() -> Self { - !0 ^ ((!0 as $UnsignedT) >> 1) as Self + ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr, + $EndFeature:expr) => { + doc_comment! { + concat!("Returns the smallest value that can be represented by this integer type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), ", stringify!($Min), ");", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn min_value() -> Self { + !0 ^ ((!0 as $UnsignedT) >> 1) as Self + } } - /// Returns the largest value that can be represented by this integer type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(i8::max_value(), 127); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub const fn max_value() -> Self { - !Self::min_value() + doc_comment! { + concat!("Returns the largest value that can be represented by this integer type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ", stringify!($Max), ");", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn max_value() -> Self { + !Self::min_value() + } } - /// Converts a string slice in a given base to an integer. - /// - /// The string is expected to be an optional `+` or `-` sign - /// followed by digits. - /// Leading and trailing whitespace represent an error. - /// Digits are a subset of these characters, depending on `radix`: - /// - /// * `0-9` - /// * `a-z` - /// * `A-Z` - /// - /// # Panics - /// - /// This function panics if `radix` is not in the range from 2 to 36. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(i32::from_str_radix("A", 16), Ok(10)); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_str_radix(src: &str, radix: u32) -> Result { - from_str_radix(src, radix) + doc_comment! { + concat!("Converts a string slice in a given base to an integer. + +The string is expected to be an optional `+` or `-` sign followed by digits. +Leading and trailing whitespace represent an error. Digits are a subset of these characters, +depending on `radix`: + + * `0-9` + * `a-z` + * `a-z` + +# Panics + +This function panics if `radix` is not in the range from 2 to 36. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + pub fn from_str_radix(src: &str, radix: u32) -> Result { + from_str_radix(src, radix) + } } - /// Returns the number of ones in the binary representation of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = -0b1000_0000i8; - /// - /// assert_eq!(n.count_ones(), 1); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } + doc_comment! { + concat!("Returns the number of ones in the binary representation of `self`. - /// Returns the number of zeros in the binary representation of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = -0b1000_0000i8; - /// - /// assert_eq!(n.count_zeros(), 7); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn count_zeros(self) -> u32 { - (!self).count_ones() +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0b100_0000", stringify!($SelfT), "; + +assert_eq!(n.count_ones(), 1);", +$EndFeature, " +``` +"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } } - /// Returns the number of leading zeros in the binary representation - /// of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = -1i16; - /// - /// assert_eq!(n.leading_zeros(), 0); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn leading_zeros(self) -> u32 { - (self as $UnsignedT).leading_zeros() + doc_comment! { + concat!("Returns the number of zeros in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } } - /// Returns the number of trailing zeros in the binary representation - /// of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = -4i8; - /// - /// assert_eq!(n.trailing_zeros(), 2); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn trailing_zeros(self) -> u32 { - (self as $UnsignedT).trailing_zeros() + doc_comment! { + concat!("Returns the number of leading zeros in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = -1", stringify!($SelfT), "; + +assert_eq!(n.leading_zeros(), 0);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn leading_zeros(self) -> u32 { + (self as $UnsignedT).leading_zeros() + } + } + + doc_comment! { + concat!("Returns the number of trailing zeros in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = -4", stringify!($SelfT), "; + +assert_eq!(n.trailing_zeros(), 2);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn trailing_zeros(self) -> u32 { + (self as $UnsignedT).trailing_zeros() + } } /// Shifts the bits to the left by a specified amount, `n`, @@ -231,6 +255,9 @@ macro_rules! int_impl { /// /// # Examples /// + /// Please note that this example is shared between integer types. + /// Which explains why `i64` is used here. + /// /// Basic usage: /// /// ``` @@ -253,6 +280,9 @@ macro_rules! int_impl { /// /// # Examples /// + /// Please note that this example is shared between integer types. + /// Which explains why `i64` is used here. + /// /// Basic usage: /// /// ``` @@ -271,6 +301,9 @@ macro_rules! int_impl { /// /// # Examples /// + /// Please note that this example is shared between integer types. + /// Which explains why `i16` is used here. + /// /// Basic usage: /// /// ``` @@ -288,1515 +321,1679 @@ macro_rules! int_impl { (self as $UnsignedT).swap_bytes() as Self } - /// Converts an integer from big endian to the target's endianness. - /// - /// On big endian this is a no-op. On little endian the bytes are - /// swapped. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFi64; - /// - /// if cfg!(target_endian = "big") { - /// assert_eq!(i64::from_be(n), n) - /// } else { - /// assert_eq!(i64::from_be(n), n.swap_bytes()) - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn from_be(x: Self) -> Self { - if cfg!(target_endian = "big") { x } else { x.swap_bytes() } - } + doc_comment! { + concat!("Converts an integer from big endian to the target's endianness. - /// Converts an integer from little endian to the target's endianness. - /// - /// On little endian this is a no-op. On big endian the bytes are - /// swapped. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFi64; - /// - /// if cfg!(target_endian = "little") { - /// assert_eq!(i64::from_le(n), n) - /// } else { - /// assert_eq!(i64::from_le(n), n.swap_bytes()) - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn from_le(x: Self) -> Self { - if cfg!(target_endian = "little") { x } else { x.swap_bytes() } - } +On big endian this is a no-op. On little endian the bytes are swapped. - /// Converts `self` to big endian from the target's endianness. - /// - /// On big endian this is a no-op. On little endian the bytes are - /// swapped. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFi64; - /// - /// if cfg!(target_endian = "big") { - /// assert_eq!(n.to_be(), n) - /// } else { - /// assert_eq!(n.to_be(), n.swap_bytes()) - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn to_be(self) -> Self { // or not to be? - if cfg!(target_endian = "big") { self } else { self.swap_bytes() } +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"big\") { + assert_eq!(", stringify!($SelfT), "::from_be(n), n) +} else { + assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes()) +}", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_be(x: Self) -> Self { + if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + } } - /// Converts `self` to little endian from the target's endianness. - /// - /// On little endian this is a no-op. On big endian the bytes are - /// swapped. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFi64; - /// - /// if cfg!(target_endian = "little") { - /// assert_eq!(n.to_le(), n) - /// } else { - /// assert_eq!(n.to_le(), n.swap_bytes()) - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn to_le(self) -> Self { - if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + doc_comment! { + concat!("Converts an integer from little endian to the target's endianness. + +On little endian this is a no-op. On big endian the bytes are swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"little\") { + assert_eq!(", stringify!($SelfT), "::from_le(n), n) +} else { + assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes()) +}", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } } - /// Checked integer addition. Computes `self + rhs`, returning `None` - /// if overflow occurred. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(7i16.checked_add(32760), Some(32767)); - /// assert_eq!(8i16.checked_add(32760), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_add(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_add(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Converts `self` to big endian from the target's endianness. + +On big endian this is a no-op. On little endian the bytes are swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"big\") { + assert_eq!(n.to_be(), n) +} else { + assert_eq!(n.to_be(), n.swap_bytes()) +}", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + } } - /// Checked integer subtraction. Computes `self - rhs`, returning - /// `None` if overflow occurred. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!((-127i8).checked_sub(1), Some(-128)); - /// assert_eq!((-128i8).checked_sub(1), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_sub(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Converts `self` to little endian from the target's endianness. + +On little endian this is a no-op. On big endian the bytes are swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"little\") { + assert_eq!(n.to_le(), n) +} else { + assert_eq!(n.to_le(), n.swap_bytes()) +}", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + } } - /// Checked integer multiplication. Computes `self * rhs`, returning - /// `None` if overflow occurred. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(6i8.checked_mul(21), Some(126)); - /// assert_eq!(6i8.checked_mul(22), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_mul(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Checked integer addition. Computes `self + rhs`, returning `None` +if overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((", stringify!($SelfT), +"::max_value() - 2).checked_add(1), Some(", stringify!($SelfT), "::max_value() - 1)); +assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_add(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_add(rhs); + if b {None} else {Some(a)} + } } - /// Checked integer division. Computes `self / rhs`, returning `None` - /// if `rhs == 0` or the division results in overflow. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!((-127i8).checked_div(-1), Some(127)); - /// assert_eq!((-128i8).checked_div(-1), None); - /// assert_eq!((1i8).checked_div(0), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_div(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { - None - } else { - Some(unsafe { intrinsics::unchecked_div(self, rhs) }) + doc_comment! { + concat!("Checked integer subtraction. Computes `self - rhs`, returning `None` if +overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((", stringify!($SelfT), +"::min_value() + 2).checked_sub(1), Some(", stringify!($SelfT), "::min_value() + 1)); +assert_eq!((", stringify!($SelfT), "::min_value() + 2).checked_sub(3), None);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_sub(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_sub(rhs); + if b {None} else {Some(a)} } } - /// Checked integer remainder. Computes `self % rhs`, returning `None` - /// if `rhs == 0` or the division results in overflow. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.checked_rem(2), Some(1)); - /// assert_eq!(5i32.checked_rem(0), None); - /// assert_eq!(i32::MIN.checked_rem(-1), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_rem(self, rhs: Self) -> Option { - if rhs == 0 || (self == Self::min_value() && rhs == -1) { - None - } else { - Some(unsafe { intrinsics::unchecked_rem(self, rhs) }) + doc_comment! { + concat!("Checked integer multiplication. Computes `self * rhs`, returning `None` if +overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), +"::max_value().checked_mul(1), Some(", stringify!($SelfT), "::max_value())); +assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_mul(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_mul(rhs); + if b {None} else {Some(a)} } } - /// Checked negation. Computes `-self`, returning `None` if `self == - /// MIN`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.checked_neg(), Some(-5)); - /// assert_eq!(i32::MIN.checked_neg(), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_neg(self) -> Option { - let (a, b) = self.overflowing_neg(); - if b {None} else {Some(a)} - } + doc_comment! { + concat!("Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0` +or the division results in overflow. - /// Checked shift left. Computes `self << rhs`, returning `None` - /// if `rhs` is larger than or equal to the number of bits in `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0x10i32.checked_shl(4), Some(0x100)); - /// assert_eq!(0x10i32.checked_shl(33), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { - let (a, b) = self.overflowing_shl(rhs); - if b {None} else {Some(a)} +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((", stringify!($SelfT), +"::min_value() + 1).checked_div(-1), Some(", stringify!($Max), ")); +assert_eq!(", stringify!($SelfT), "::min_value().checked_div(-1), None); +assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_div(self, rhs: Self) -> Option { + if rhs == 0 || (self == Self::min_value() && rhs == -1) { + None + } else { + Some(unsafe { intrinsics::unchecked_div(self, rhs) }) + } + } } - /// Checked shift right. Computes `self >> rhs`, returning `None` - /// if `rhs` is larger than or equal to the number of bits in `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0x10i32.checked_shr(4), Some(0x1)); - /// assert_eq!(0x10i32.checked_shr(33), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { - let (a, b) = self.overflowing_shr(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if +`rhs == 0` or the division results in overflow. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1)); +assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None); +assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);", +$EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_rem(self, rhs: Self) -> Option { + if rhs == 0 || (self == Self::min_value() && rhs == -1) { + None + } else { + Some(unsafe { intrinsics::unchecked_rem(self, rhs) }) + } + } } - /// Checked absolute value. Computes `self.abs()`, returning `None` if - /// `self == MIN`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!((-5i32).checked_abs(), Some(5)); - /// assert_eq!(i32::MIN.checked_abs(), None); - /// ``` - #[stable(feature = "no_panic_abs", since = "1.13.0")] - #[inline] - pub fn checked_abs(self) -> Option { - if self.is_negative() { - self.checked_neg() - } else { - Some(self) + doc_comment! { + concat!("Checked negation. Computes `-self`, returning `None` if `self == MIN`. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".checked_neg(), Some(-5)); +assert_eq!(", stringify!($SelfT), "::MIN.checked_neg(), None);", +$EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_neg(self) -> Option { + let (a, b) = self.overflowing_neg(); + if b {None} else {Some(a)} } } - /// Saturating integer addition. Computes `self + rhs`, saturating at - /// the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.saturating_add(1), 101); - /// assert_eq!(100i8.saturating_add(127), 127); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn saturating_add(self, rhs: Self) -> Self { - match self.checked_add(rhs) { - Some(x) => x, - None if rhs >= 0 => Self::max_value(), - None => Self::min_value(), + doc_comment! { + concat!("Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger +than or equal to the number of bits in `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10)); +assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);", +$EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} } } - /// Saturating integer subtraction. Computes `self - rhs`, saturating - /// at the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.saturating_sub(127), -27); - /// assert_eq!((-100i8).saturating_sub(127), -128); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn saturating_sub(self, rhs: Self) -> Self { - match self.checked_sub(rhs) { - Some(x) => x, - None if rhs >= 0 => Self::min_value(), - None => Self::max_value(), + doc_comment! { + concat!("Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is +larger than or equal to the number of bits in `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1)); +assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);", +$EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} } } - /// Saturating integer multiplication. Computes `self * rhs`, - /// saturating at the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(100i32.saturating_mul(127), 12700); - /// assert_eq!((1i32 << 23).saturating_mul(1 << 23), i32::MAX); - /// assert_eq!((-1i32 << 23).saturating_mul(1 << 23), i32::MIN); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(rhs).unwrap_or_else(|| { - if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) { - Self::max_value() + doc_comment! { + concat!("Checked absolute value. Computes `self.abs()`, returning `None` if +`self == MIN`. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!((-5", stringify!($SelfT), ").checked_abs(), Some(5)); +assert_eq!(", stringify!($SelfT), "::MIN.checked_abs(), None);", +$EndFeature, " +```"), + #[stable(feature = "no_panic_abs", since = "1.13.0")] + #[inline] + pub fn checked_abs(self) -> Option { + if self.is_negative() { + self.checked_neg() } else { - Self::min_value() + Some(self) } - }) + } } - /// Wrapping (modular) addition. Computes `self + rhs`, - /// wrapping around at the boundary of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.wrapping_add(27), 127); - /// assert_eq!(100i8.wrapping_add(127), -29); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn wrapping_add(self, rhs: Self) -> Self { - unsafe { - intrinsics::overflowing_add(self, rhs) + doc_comment! { + concat!("Saturating integer addition. Computes `self + rhs`, saturating at the numeric +bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); +assert_eq!(", stringify!($SelfT), "::max_value().saturating_add(100), ", stringify!($SelfT), +"::max_value());", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_add(self, rhs: Self) -> Self { + match self.checked_add(rhs) { + Some(x) => x, + None if rhs >= 0 => Self::max_value(), + None => Self::min_value(), + } } } - /// Wrapping (modular) subtraction. Computes `self - rhs`, - /// wrapping around at the boundary of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0i8.wrapping_sub(127), -127); - /// assert_eq!((-2i8).wrapping_sub(127), 127); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn wrapping_sub(self, rhs: Self) -> Self { - unsafe { - intrinsics::overflowing_sub(self, rhs) + doc_comment! { + concat!("Saturating integer subtraction. Computes `self - rhs`, saturating at the +numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(127), -27); +assert_eq!(", stringify!($SelfT), "::min_value().saturating_sub(100), ", stringify!($SelfT), +"::min_value());", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_sub(self, rhs: Self) -> Self { + match self.checked_sub(rhs) { + Some(x) => x, + None if rhs >= 0 => Self::min_value(), + None => Self::max_value(), + } } } - /// Wrapping (modular) multiplication. Computes `self * - /// rhs`, wrapping around at the boundary of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(10i8.wrapping_mul(12), 120); - /// assert_eq!(11i8.wrapping_mul(12), -124); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn wrapping_mul(self, rhs: Self) -> Self { - unsafe { - intrinsics::overflowing_mul(self, rhs) + doc_comment! { + concat!("Saturating integer multiplication. Computes `self * rhs`, saturating at the +numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(10", stringify!($SelfT), ".saturating_mul(12), 120); +assert_eq!(", stringify!($SelfT), "::MAX.saturating_mul(10), ", stringify!($SelfT), "::MAX); +assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($SelfT), "::MIN);", +$EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn saturating_mul(self, rhs: Self) -> Self { + self.checked_mul(rhs).unwrap_or_else(|| { + if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) { + Self::max_value() + } else { + Self::min_value() + } + }) } } - /// Wrapping (modular) division. Computes `self / rhs`, - /// wrapping around at the boundary of the type. - /// - /// The only case where such wrapping can occur is when one - /// divides `MIN / -1` on a signed type (where `MIN` is the - /// negative minimal value for the type); this is equivalent - /// to `-MIN`, a positive value that is too large to represent - /// in the type. In such a case, this function returns `MIN` - /// itself. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.wrapping_div(10), 10); - /// assert_eq!((-128i8).wrapping_div(-1), -128); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { - self.overflowing_div(rhs).0 + doc_comment! { + concat!("Wrapping (modular) addition. Computes `self + rhs`, wrapping around at the +boundary of the type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_add(27), 127); +assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!($SelfT), +"::min_value() + 1);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_add(self, rhs) + } + } } - /// Wrapping (modular) remainder. Computes `self % rhs`, - /// wrapping around at the boundary of the type. - /// - /// Such wrap-around never actually occurs mathematically; - /// implementation artifacts make `x % y` invalid for `MIN / - /// -1` on a signed type (where `MIN` is the negative - /// minimal value). In such a case, this function returns `0`. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.wrapping_rem(10), 0); - /// assert_eq!((-128i8).wrapping_rem(-1), 0); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { - self.overflowing_rem(rhs).0 + doc_comment! { + concat!("Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the +boundary of the type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0", stringify!($SelfT), ".wrapping_sub(127), -127); +assert_eq!((-2", stringify!($SelfT), ").wrapping_sub(", stringify!($SelfT), "::max_value()), ", +stringify!($SelfT), "::max_value());", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_sub(self, rhs) + } + } } - /// Wrapping (modular) negation. Computes `-self`, - /// wrapping around at the boundary of the type. - /// - /// The only case where such wrapping can occur is when one - /// negates `MIN` on a signed type (where `MIN` is the - /// negative minimal value for the type); this is a positive - /// value that is too large to represent in the type. In such - /// a case, this function returns `MIN` itself. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.wrapping_neg(), -100); - /// assert_eq!((-128i8).wrapping_neg(), -128); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_neg(self) -> Self { - self.overflowing_neg().0 + doc_comment! { + concat!("Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at +the boundary of the type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(10", stringify!($SelfT), ".wrapping_mul(12), 120); +assert_eq!(11i8.wrapping_mul(12), -124);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_mul(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_mul(self, rhs) + } + } } - /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, - /// where `mask` removes any high-order bits of `rhs` that - /// would cause the shift to exceed the bitwidth of the type. - /// - /// Note that this is *not* the same as a rotate-left; the - /// RHS of a wrapping shift-left is restricted to the range - /// of the type, rather than the bits shifted out of the LHS - /// being returned to the other end. The primitive integer - /// types all implement a `rotate_left` function, which may - /// be what you want instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!((-1i8).wrapping_shl(7), -128); - /// assert_eq!((-1i8).wrapping_shl(8), -1); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_shl(self, rhs: u32) -> Self { - unsafe { - intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + doc_comment! { + concat!("Wrapping (modular) division. Computes `self / rhs`, wrapping around at the +boundary of the type. + +The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where +`MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value +that is too large to represent in the type. In such a case, this function returns `MIN` itself. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10); +assert_eq!((-128i8).wrapping_div(-1), -128);", +$EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_div(self, rhs: Self) -> Self { + self.overflowing_div(rhs).0 } } - /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, - /// where `mask` removes any high-order bits of `rhs` that - /// would cause the shift to exceed the bitwidth of the type. - /// - /// Note that this is *not* the same as a rotate-right; the - /// RHS of a wrapping shift-right is restricted to the range - /// of the type, rather than the bits shifted out of the LHS - /// being returned to the other end. The primitive integer - /// types all implement a `rotate_right` function, which may - /// be what you want instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!((-128i8).wrapping_shr(7), -1); - /// assert_eq!((-128i8).wrapping_shr(8), -128); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_shr(self, rhs: u32) -> Self { - unsafe { - intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + doc_comment! { + concat!("Wrapping (modular) remainder. Computes `self % rhs`, wrapping around at the +boundary of the type. + +Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y` +invalid for `MIN / -1` on a signed type (where `MIN` is the negative minimal value). In such a case, +this function returns `0`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0); +assert_eq!((-128i8).wrapping_rem(-1), 0);", +$EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_rem(self, rhs: Self) -> Self { + self.overflowing_rem(rhs).0 } } - /// Wrapping (modular) absolute value. Computes `self.abs()`, - /// wrapping around at the boundary of the type. - /// - /// The only case where such wrapping can occur is when one takes - /// the absolute value of the negative minimal value for the type - /// this is a positive value that is too large to represent in the - /// type. In such a case, this function returns `MIN` itself. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100i8.wrapping_abs(), 100); - /// assert_eq!((-100i8).wrapping_abs(), 100); - /// assert_eq!((-128i8).wrapping_abs(), -128); - /// assert_eq!((-128i8).wrapping_abs() as u8, 128); - /// ``` - #[stable(feature = "no_panic_abs", since = "1.13.0")] - #[inline] - pub fn wrapping_abs(self) -> Self { - if self.is_negative() { - self.wrapping_neg() - } else { - self + doc_comment! { + concat!("Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary +of the type. + +The only case where such wrapping can occur is when one negates `MIN` on a signed type (where `MIN` +is the negative minimal value for the type); this is a positive value that is too large to represent +in the type. In such a case, this function returns `MIN` itself. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100); +assert_eq!(", stringify!($SelfT), "::min_value().wrapping_neg(), ", stringify!($SelfT), +"::min_value());", +$EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_neg(self) -> Self { + self.overflowing_neg().0 } } - /// Calculates `self` + `rhs` - /// - /// Returns a tuple of the addition along with a boolean indicating - /// whether an arithmetic overflow would occur. If an overflow would - /// have occurred then the wrapped value is returned. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.overflowing_add(2), (7, false)); - /// assert_eq!(i32::MAX.overflowing_add(1), (i32::MIN, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { - intrinsics::add_with_overflow(self as $ActualT, - rhs as $ActualT) - }; - (a as Self, b) + doc_comment! { + concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`, where `mask` removes +any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type. + +Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to +the range of the type, rather than the bits shifted out of the LHS being returned to the other end. +The primitive integer types all implement a `rotate_left` function, which may be what you want +instead. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(7), -128); +assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);", +$EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_shl(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + } + } } - /// Calculates `self` - `rhs` - /// - /// Returns a tuple of the subtraction along with a boolean indicating - /// whether an arithmetic overflow would occur. If an overflow would - /// have occurred then the wrapped value is returned. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.overflowing_sub(2), (3, false)); - /// assert_eq!(i32::MIN.overflowing_sub(1), (i32::MAX, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { - intrinsics::sub_with_overflow(self as $ActualT, - rhs as $ActualT) - }; - (a as Self, b) + doc_comment! { + concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`, where `mask` +removes any high-order bits of `rhs` that would cause the shift to exceed the bitwidth of the type. + +Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted +to the range of the type, rather than the bits shifted out of the LHS being returned to the other +end. The primitive integer types all implement a `rotate_right` function, which may be what you want +instead. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((-128", stringify!($SelfT), ").wrapping_shr(7), -1); +assert_eq!((-128i16).wrapping_shr(64), -128);", +$EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_shr(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + } + } } - /// Calculates the multiplication of `self` and `rhs`. - /// - /// Returns a tuple of the multiplication along with a boolean - /// indicating whether an arithmetic overflow would occur. If an - /// overflow would have occurred then the wrapped value is returned. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(5i32.overflowing_mul(2), (10, false)); - /// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { - intrinsics::mul_with_overflow(self as $ActualT, - rhs as $ActualT) - }; - (a as Self, b) + doc_comment! { + concat!("Wrapping (modular) absolute value. Computes `self.abs()`, wrapping around at +the boundary of the type. + +The only case where such wrapping can occur is when one takes the absolute value of the negative +minimal value for the type this is a positive value that is too large to represent in the type. In +such a case, this function returns `MIN` itself. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_abs(), 100); +assert_eq!((-100", stringify!($SelfT), ").wrapping_abs(), 100); +assert_eq!(", stringify!($SelfT), "::min_value().wrapping_abs(), ", stringify!($SelfT), +"::min_value()); +assert_eq!((-128i8).wrapping_abs() as u8, 128);", +$EndFeature, " +```"), + #[stable(feature = "no_panic_abs", since = "1.13.0")] + #[inline] + pub fn wrapping_abs(self) -> Self { + if self.is_negative() { + self.wrapping_neg() + } else { + self + } + } } - /// Calculates the divisor when `self` is divided by `rhs`. - /// - /// Returns a tuple of the divisor along with a boolean indicating - /// whether an arithmetic overflow would occur. If an overflow would - /// occur then self is returned. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.overflowing_div(2), (2, false)); - /// assert_eq!(i32::MIN.overflowing_div(-1), (i32::MIN, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { - (self, true) - } else { - (self / rhs, false) + doc_comment! { + concat!("Calculates `self` + `rhs` + +Returns a tuple of the addition along with a boolean indicating whether an arithmetic overflow would +occur. If an overflow would have occurred then the wrapped value is returned. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false)); +assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($SelfT), +"::MIN, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { + intrinsics::add_with_overflow(self as $ActualT, + rhs as $ActualT) + }; + (a as Self, b) } } - /// Calculates the remainder when `self` is divided by `rhs`. - /// - /// Returns a tuple of the remainder after dividing along with a boolean - /// indicating whether an arithmetic overflow would occur. If an - /// overflow would occur then 0 is returned. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(5i32.overflowing_rem(2), (1, false)); - /// assert_eq!(i32::MIN.overflowing_rem(-1), (0, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { - if self == Self::min_value() && rhs == -1 { - (0, true) - } else { - (self % rhs, false) + doc_comment! { + concat!("Calculates `self` - `rhs` + +Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow +would occur. If an overflow would have occurred then the wrapped value is returned. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($SelfT), +"::MAX, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { + intrinsics::sub_with_overflow(self as $ActualT, + rhs as $ActualT) + }; + (a as Self, b) } } - /// Negates self, overflowing if this is equal to the minimum value. - /// - /// Returns a tuple of the negated version of self along with a boolean - /// indicating whether an overflow happened. If `self` is the minimum - /// value (e.g. `i32::MIN` for values of type `i32`), then the minimum - /// value will be returned again and `true` will be returned for an - /// overflow happening. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::i32; - /// - /// assert_eq!(2i32.overflowing_neg(), (-2, false)); - /// assert_eq!(i32::MIN.overflowing_neg(), (i32::MIN, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { - if self == Self::min_value() { - (Self::min_value(), true) - } else { - (-self, false) + doc_comment! { + concat!("Calculates the multiplication of `self` and `rhs`. + +Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic overflow +would occur. If an overflow would have occurred then the wrapped value is returned. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_mul(2), (10, false)); +assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { + intrinsics::mul_with_overflow(self as $ActualT, + rhs as $ActualT) + }; + (a as Self, b) } } - /// Shifts self left by `rhs` bits. - /// - /// Returns a tuple of the shifted version of self along with a boolean - /// indicating whether the shift value was larger than or equal to the - /// number of bits. If the shift value is too large, then value is - /// masked (N-1) where N is the number of bits, and this value is then - /// used to perform the shift. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(0x10i32.overflowing_shl(4), (0x100, false)); - /// assert_eq!(0x10i32.overflowing_shl(36), (0x100, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { - (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + doc_comment! { + concat!("Calculates the divisor when `self` is divided by `rhs`. + +Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would +occur. If an overflow would occur then self is returned. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div(-1), (", stringify!($SelfT), +"::MIN, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (self, true) + } else { + (self / rhs, false) + } + } } - /// Shifts self right by `rhs` bits. - /// - /// Returns a tuple of the shifted version of self along with a boolean - /// indicating whether the shift value was larger than or equal to the - /// number of bits. If the shift value is too large, then value is - /// masked (N-1) where N is the number of bits, and this value is then - /// used to perform the shift. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(0x10i32.overflowing_shr(4), (0x1, false)); - /// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { - (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + doc_comment! { + concat!("Calculates the remainder when `self` is divided by `rhs`. + +Returns a tuple of the remainder after dividing along with a boolean indicating whether an +arithmetic overflow would occur. If an overflow would occur then 0 is returned. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem(-1), (0, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (0, true) + } else { + (self % rhs, false) + } + } } - /// Computes the absolute value of `self`. - /// - /// Returns a tuple of the absolute version of self along with a - /// boolean indicating whether an overflow happened. If self is the - /// minimum value (e.g. i32::MIN for values of type i32), then the - /// minimum value will be returned again and true will be returned for - /// an overflow happening. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(10i8.overflowing_abs(), (10,false)); - /// assert_eq!((-10i8).overflowing_abs(), (10,false)); - /// assert_eq!((-128i8).overflowing_abs(), (-128,true)); - /// ``` - #[stable(feature = "no_panic_abs", since = "1.13.0")] - #[inline] - pub fn overflowing_abs(self) -> (Self, bool) { - if self.is_negative() { - self.overflowing_neg() - } else { - (self, false) + doc_comment! { + concat!("Negates self, overflowing if this is equal to the minimum value. + +Returns a tuple of the negated version of self along with a boolean indicating whether an overflow +happened. If `self` is the minimum value (e.g. `i32::MIN` for values of type `i32`), then the +minimum value will be returned again and `true` will be returned for an overflow happening. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2, false)); +assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($SelfT), +"::MIN, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_neg(self) -> (Self, bool) { + if self == Self::min_value() { + (Self::min_value(), true) + } else { + (-self, false) + } } } - /// Raises self to the power of `exp`, using exponentiation by squaring. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x: i32 = 2; // or any other integer type - /// - /// assert_eq!(x.pow(4), 16); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - #[rustc_inherit_overflow_checks] - pub fn pow(self, mut exp: u32) -> Self { - let mut base = self; - let mut acc = 1; + doc_comment! { + concat!("Shifts self left by `rhs` bits. + +Returns a tuple of the shifted version of self along with a boolean indicating whether the shift +value was larger than or equal to the number of bits. If the shift value is too large, then value is +masked (N-1) where N is the number of bits, and this value is then used to perform the shift. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x1", stringify!($SelfT),".overflowing_shl(4), (0x10, false)); +assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + } + } + + doc_comment! { + concat!("Shifts self right by `rhs` bits. + +Returns a tuple of the shifted version of self along with a boolean indicating whether the shift +value was larger than or equal to the number of bits. If the shift value is too large, then value is +masked (N-1) where N is the number of bits, and this value is then used to perform the shift. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false)); +assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + } + } + + doc_comment! { + concat!("Computes the absolute value of `self`. + +Returns a tuple of the absolute version of self along with a boolean indicating whether an overflow +happened. If self is the minimum value (e.g. ", stringify!($SelfT), "::MIN for values of type + ", stringify!($SelfT), "), then the minimum value will be returned again and true will be returned +for an overflow happening. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(10", stringify!($SelfT), ".overflowing_abs(), (10, false)); +assert_eq!((-10", stringify!($SelfT), ").overflowing_abs(), (10, false)); +assert_eq!((", stringify!($SelfT), "::min_value()).overflowing_abs(), (", stringify!($SelfT), +"::min_value(), true));", +$EndFeature, " +```"), + #[stable(feature = "no_panic_abs", since = "1.13.0")] + #[inline] + pub fn overflowing_abs(self) -> (Self, bool) { + if self.is_negative() { + self.overflowing_neg() + } else { + (self, false) + } + } + } + + doc_comment! { + concat!("Raises self to the power of `exp`, using exponentiation by squaring. + +# Examples + +Basic usage: + +``` +", $Feature, "let x: ", stringify!($SelfT), " = 2; // or any other integer type + +assert_eq!(x.pow(4), 16);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn pow(self, mut exp: u32) -> Self { + let mut base = self; + let mut acc = 1; + + while exp > 1 { + if (exp & 1) == 1 { + acc = acc * base; + } + exp /= 2; + base = base * base; + } + + // Deal with the final bit of the exponent separately, since + // squaring the base afterwards is not necessary and may cause a + // needless overflow. + if exp == 1 { + acc = acc * base; + } + + acc + } + } + + doc_comment! { + concat!("Computes the absolute value of `self`. - while exp > 1 { - if (exp & 1) == 1 { - acc = acc * base; +# Overflow behavior + +The absolute value of `", stringify!($SelfT), "::min_value()` cannot be represented as an +`", stringify!($SelfT), "`, and attempting to calculate it will cause an overflow. This means that +code in debug mode will trigger a panic on this case and optimized code will return `", +stringify!($SelfT), "::min_value()` without a panic. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(10", stringify!($SelfT), ".abs(), 10); +assert_eq!((-10", stringify!($SelfT), ").abs(), 10);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + #[rustc_inherit_overflow_checks] + pub fn abs(self) -> Self { + if self.is_negative() { + // Note that the #[inline] above means that the overflow + // semantics of this negation depend on the crate we're being + // inlined into. + -self + } else { + self } - exp /= 2; - base = base * base; } + } - // Deal with the final bit of the exponent separately, since - // squaring the base afterwards is not necessary and may cause a - // needless overflow. - if exp == 1 { - acc = acc * base; - } + doc_comment! { + concat!("Returns a number representing sign of `self`. - acc - } + - `0` if the number is zero + - `1` if the number is positive + - `-1` if the number is negative - /// Computes the absolute value of `self`. - /// - /// # Overflow behavior - /// - /// The absolute value of `i32::min_value()` cannot be represented as an - /// `i32`, and attempting to calculate it will cause an overflow. This - /// means that code in debug mode will trigger a panic on this case and - /// optimized code will return `i32::min_value()` without a panic. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(10i8.abs(), 10); - /// assert_eq!((-10i8).abs(), 10); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - #[rustc_inherit_overflow_checks] - pub fn abs(self) -> Self { - if self.is_negative() { - // Note that the #[inline] above means that the overflow - // semantics of this negation depend on the crate we're being - // inlined into. - -self - } else { - self +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(10", stringify!($SelfT), ".signum(), 1); +assert_eq!(0", stringify!($SelfT), ".signum(), 0); +assert_eq!((-10", stringify!($SelfT), ").signum(), -1);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn signum(self) -> Self { + match self { + n if n > 0 => 1, + 0 => 0, + _ => -1, + } } } - /// Returns a number representing sign of `self`. - /// - /// - `0` if the number is zero - /// - `1` if the number is positive - /// - `-1` if the number is negative - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(10i8.signum(), 1); - /// assert_eq!(0i8.signum(), 0); - /// assert_eq!((-10i8).signum(), -1); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn signum(self) -> Self { - match self { - n if n > 0 => 1, - 0 => 0, - _ => -1, - } + doc_comment! { + concat!("Returns `true` if `self` is positive and `false` if the number is zero or +negative. + +# Examples + +Basic usage: + +``` +", $Feature, "assert!(10", stringify!($SelfT), ".is_positive()); +assert!(!(-10", stringify!($SelfT), ").is_positive());", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_positive(self) -> bool { self > 0 } } - /// Returns `true` if `self` is positive and `false` if the number - /// is zero or negative. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert!(10i8.is_positive()); - /// assert!(!(-10i8).is_positive()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn is_positive(self) -> bool { self > 0 } + doc_comment! { + concat!("Returns `true` if `self` is negative and `false` if the number is zero or +positive. - /// Returns `true` if `self` is negative and `false` if the number - /// is zero or positive. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert!((-10i8).is_negative()); - /// assert!(!10i8.is_negative()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn is_negative(self) -> bool { self < 0 } +# Examples + +Basic usage: + +``` +", $Feature, "assert!((-10", stringify!($SelfT), ").is_negative()); +assert!(!10", stringify!($SelfT), ".is_negative());", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_negative(self) -> bool { self < 0 } + } } } #[lang = "i8"] impl i8 { - int_impl! { i8, i8, u8, 8 } + int_impl! { i8, i8, u8, 8, -128, 127, "", "" } } #[lang = "i16"] impl i16 { - int_impl! { i16, i16, u16, 16 } + int_impl! { i16, i16, u16, 16, -32768, 32767, "", "" } } #[lang = "i32"] impl i32 { - int_impl! { i32, i32, u32, 32 } + int_impl! { i32, i32, u32, 32, -2147483648, 2147483647, "", "" } } #[lang = "i64"] impl i64 { - int_impl! { i64, i64, u64, 64 } + int_impl! { i64, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" } } #[lang = "i128"] impl i128 { - int_impl! { i128, i128, u128, 128 } + int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728, + 170141183460469231731687303715884105727, "#![feature(i128_type)] +#![feature(i128)] +# fn main() { +", " +# }" } } #[cfg(target_pointer_width = "16")] #[lang = "isize"] impl isize { - int_impl! { isize, i16, u16, 16 } + int_impl! { isize, i16, u16, 16, "", "" } } #[cfg(target_pointer_width = "32")] #[lang = "isize"] impl isize { - int_impl! { isize, i32, u32, 32 } + int_impl! { isize, i32, u32, 32, "", "" } } #[cfg(target_pointer_width = "64")] #[lang = "isize"] impl isize { - int_impl! { isize, i64, u64, 64 } + int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" } } // `Int` + `UnsignedInt` implemented for unsigned integers macro_rules! uint_impl { - ($SelfT:ty, $ActualT:ty, $BITS:expr) => { - /// Returns the smallest value that can be represented by this integer type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(u8::min_value(), 0); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub const fn min_value() -> Self { 0 } + ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr) => { + doc_comment! { + concat!("Returns the smallest value that can be represented by this integer type. - /// Returns the largest value that can be represented by this integer type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(u8::max_value(), 255); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub const fn max_value() -> Self { !0 } +# Examples - /// Converts a string slice in a given base to an integer. - /// - /// The string is expected to be an optional `+` sign - /// followed by digits. - /// Leading and trailing whitespace represent an error. - /// Digits are a subset of these characters, depending on `radix`: - /// - /// * `0-9` - /// * `a-z` - /// * `A-Z` - /// - /// # Panics - /// - /// This function panics if `radix` is not in the range from 2 to 36. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(u32::from_str_radix("A", 16), Ok(10)); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_str_radix(src: &str, radix: u32) -> Result { - from_str_radix(src, radix) - } +Basic usage: - /// Returns the number of ones in the binary representation of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0b01001100u8; - /// - /// assert_eq!(n.count_ones(), 3); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn count_ones(self) -> u32 { - unsafe { intrinsics::ctpop(self as $ActualT) as u32 } +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), 0);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn min_value() -> Self { 0 } } - /// Returns the number of zeros in the binary representation of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0b01001100u8; - /// - /// assert_eq!(n.count_zeros(), 5); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn count_zeros(self) -> u32 { - (!self).count_ones() - } + doc_comment! { + concat!("Returns the largest value that can be represented by this integer type. - /// Returns the number of leading zeros in the binary representation - /// of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0b0101000u16; - /// - /// assert_eq!(n.leading_zeros(), 10); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn leading_zeros(self) -> u32 { - unsafe { intrinsics::ctlz(self as $ActualT) as u32 } +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value(), ", +stringify!($MaxV), ");", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub const fn max_value() -> Self { !0 } } - /// Returns the number of trailing zeros in the binary representation - /// of `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0b0101000u16; - /// - /// assert_eq!(n.trailing_zeros(), 3); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn trailing_zeros(self) -> u32 { - // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic - // emits two conditional moves on x86_64. By promoting the value to - // u16 and setting bit 8, we get better code without any conditional - // operations. - // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284) - // pending, remove this workaround once LLVM generates better code - // for cttz8. - unsafe { - if $BITS == 8 { - intrinsics::cttz(self as u16 | 0x100) as u32 - } else { - intrinsics::cttz(self) as u32 - } + doc_comment! { + concat!("Converts a string slice in a given base to an integer. + +The string is expected to be an optional `+` sign +followed by digits. +Leading and trailing whitespace represent an error. +Digits are a subset of these characters, depending on `radix`: + +* `0-9` +* `a-z` +* `A-Z` + +# Panics + +This function panics if `radix` is not in the range from 2 to 36. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + pub fn from_str_radix(src: &str, radix: u32) -> Result { + from_str_radix(src, radix) } } - /// Shifts the bits to the left by a specified amount, `n`, - /// wrapping the truncated bits to the end of the resulting integer. - /// - /// Please note this isn't the same operation as `<<`! - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// let m = 0x3456789ABCDEF012u64; - /// - /// assert_eq!(n.rotate_left(12), m); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn rotate_left(self, n: u32) -> Self { - // Protect against undefined behaviour for over-long bit shifts - let n = n % $BITS; - (self << n) | (self >> (($BITS - n) % $BITS)) + doc_comment! { + concat!("Returns the number of ones in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0b01001100", stringify!($SelfT), "; + +assert_eq!(n.count_ones(), 3);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_ones(self) -> u32 { + unsafe { intrinsics::ctpop(self as $ActualT) as u32 } + } } - /// Shifts the bits to the right by a specified amount, `n`, - /// wrapping the truncated bits to the beginning of the resulting - /// integer. - /// - /// Please note this isn't the same operation as `>>`! - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// let m = 0xDEF0123456789ABCu64; - /// - /// assert_eq!(n.rotate_right(12), m); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn rotate_right(self, n: u32) -> Self { - // Protect against undefined behaviour for over-long bit shifts - let n = n % $BITS; - (self >> n) | (self << (($BITS - n) % $BITS)) + doc_comment! { + concat!("Returns the number of zeros in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } } - /// Reverses the byte order of the integer. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n: u16 = 0b0000000_01010101; - /// assert_eq!(n, 85); - /// - /// let m = n.swap_bytes(); - /// - /// assert_eq!(m, 0b01010101_00000000); - /// assert_eq!(m, 21760); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn swap_bytes(self) -> Self { - unsafe { intrinsics::bswap(self as $ActualT) as Self } + doc_comment! { + concat!("Returns the number of leading zeros in the binary representation of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = ", stringify!($SelfT), "::max_value() >> 2; + +assert_eq!(n.leading_zeros(), 2);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn leading_zeros(self) -> u32 { + unsafe { intrinsics::ctlz(self as $ActualT) as u32 } + } } - /// Converts an integer from big endian to the target's endianness. - /// - /// On big endian this is a no-op. On little endian the bytes are - /// swapped. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let n = 0x0123456789ABCDEFu64; - /// - /// if cfg!(target_endian = "big") { - /// assert_eq!(u64::from_be(n), n) - /// } else { - /// assert_eq!(u64::from_be(n), n.swap_bytes()) - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn from_be(x: Self) -> Self { - if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + doc_comment! { + concat!("Returns the number of trailing zeros in the binary representation +of `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0b0101000", stringify!($SelfT), "; + +assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn trailing_zeros(self) -> u32 { + // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic + // emits two conditional moves on x86_64. By promoting the value to + // u16 and setting bit 8, we get better code without any conditional + // operations. + // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284) + // pending, remove this workaround once LLVM generates better code + // for cttz8. + unsafe { + if $BITS == 8 { + intrinsics::cttz(self as u16 | 0x100) as u32 + } else { + intrinsics::cttz(self) as u32 + } + } + } } - /// Converts an integer from little endian to the target's endianness. + /// Shifts the bits to the left by a specified amount, `n`, + /// wrapping the truncated bits to the end of the resulting integer. /// - /// On little endian this is a no-op. On big endian the bytes are - /// swapped. + /// Please note this isn't the same operation as `<<`! /// /// # Examples /// /// Basic usage: /// + /// Please note that this example is shared between integer types. + /// Which explains why `u64` is used here. + /// /// ``` /// let n = 0x0123456789ABCDEFu64; + /// let m = 0x3456789ABCDEF012u64; /// - /// if cfg!(target_endian = "little") { - /// assert_eq!(u64::from_le(n), n) - /// } else { - /// assert_eq!(u64::from_le(n), n.swap_bytes()) - /// } + /// assert_eq!(n.rotate_left(12), m); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn from_le(x: Self) -> Self { - if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + pub fn rotate_left(self, n: u32) -> Self { + // Protect against undefined behaviour for over-long bit shifts + let n = n % $BITS; + (self << n) | (self >> (($BITS - n) % $BITS)) } - /// Converts `self` to big endian from the target's endianness. + /// Shifts the bits to the right by a specified amount, `n`, + /// wrapping the truncated bits to the beginning of the resulting + /// integer. /// - /// On big endian this is a no-op. On little endian the bytes are - /// swapped. + /// Please note this isn't the same operation as `>>`! /// /// # Examples /// /// Basic usage: /// + /// Please note that this example is shared between integer types. + /// Which explains why `u64` is used here. + /// /// ``` /// let n = 0x0123456789ABCDEFu64; + /// let m = 0xDEF0123456789ABCu64; /// - /// if cfg!(target_endian = "big") { - /// assert_eq!(n.to_be(), n) - /// } else { - /// assert_eq!(n.to_be(), n.swap_bytes()) - /// } + /// assert_eq!(n.rotate_right(12), m); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn to_be(self) -> Self { // or not to be? - if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + pub fn rotate_right(self, n: u32) -> Self { + // Protect against undefined behaviour for over-long bit shifts + let n = n % $BITS; + (self >> n) | (self << (($BITS - n) % $BITS)) } - /// Converts `self` to little endian from the target's endianness. - /// - /// On little endian this is a no-op. On big endian the bytes are - /// swapped. + /// Reverses the byte order of the integer. /// /// # Examples /// /// Basic usage: /// - /// ``` - /// let n = 0x0123456789ABCDEFu64; + /// Please note that this example is shared between integer types. + /// Which explains why `u16` is used here. /// - /// if cfg!(target_endian = "little") { - /// assert_eq!(n.to_le(), n) - /// } else { - /// assert_eq!(n.to_le(), n.swap_bytes()) - /// } /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn to_le(self) -> Self { - if cfg!(target_endian = "little") { self } else { self.swap_bytes() } - } - - /// Checked integer addition. Computes `self + rhs`, returning `None` - /// if overflow occurred. - /// - /// # Examples + /// let n: u16 = 0b0000000_01010101; + /// assert_eq!(n, 85); /// - /// Basic usage: + /// let m = n.swap_bytes(); /// - /// ``` - /// assert_eq!(5u16.checked_add(65530), Some(65535)); - /// assert_eq!(6u16.checked_add(65530), None); + /// assert_eq!(m, 0b01010101_00000000); + /// assert_eq!(m, 21760); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn checked_add(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_add(rhs); - if b {None} else {Some(a)} + pub fn swap_bytes(self) -> Self { + unsafe { intrinsics::bswap(self as $ActualT) as Self } } - /// Checked integer subtraction. Computes `self - rhs`, returning - /// `None` if overflow occurred. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(1u8.checked_sub(1), Some(0)); - /// assert_eq!(0u8.checked_sub(1), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_sub(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Converts an integer from big endian to the target's endianness. + +On big endian this is a no-op. On little endian the bytes are +swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"big\") { + assert_eq!(", stringify!($SelfT), "::from_be(n), n) +} else { + assert_eq!(", stringify!($SelfT), "::from_be(n), n.swap_bytes()) +}", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_be(x: Self) -> Self { + if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + } } - /// Checked integer multiplication. Computes `self * rhs`, returning - /// `None` if overflow occurred. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(5u8.checked_mul(51), Some(255)); - /// assert_eq!(5u8.checked_mul(52), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { - let (a, b) = self.overflowing_mul(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Converts an integer from little endian to the target's endianness. + +On little endian this is a no-op. On big endian the bytes are +swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"little\") { + assert_eq!(", stringify!($SelfT), "::from_le(n), n) +} else { + assert_eq!(", stringify!($SelfT), "::from_le(n), n.swap_bytes()) +}", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } } - /// Checked integer division. Computes `self / rhs`, returning `None` - /// if `rhs == 0`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(128u8.checked_div(2), Some(64)); - /// assert_eq!(1u8.checked_div(0), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn checked_div(self, rhs: Self) -> Option { - match rhs { - 0 => None, - rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }), + doc_comment! { + concat!("Converts `self` to big endian from the target's endianness. + +On big endian this is a no-op. On little endian the bytes are +swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"big\") { + assert_eq!(n.to_be(), n) +} else { + assert_eq!(n.to_be(), n.swap_bytes()) +}", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } } } - /// Checked integer remainder. Computes `self % rhs`, returning `None` - /// if `rhs == 0`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(5u32.checked_rem(2), Some(1)); - /// assert_eq!(5u32.checked_rem(0), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_rem(self, rhs: Self) -> Option { - if rhs == 0 { - None - } else { - Some(unsafe { intrinsics::unchecked_rem(self, rhs) }) + doc_comment! { + concat!("Converts `self` to little endian from the target's endianness. + +On little endian this is a no-op. On big endian the bytes are +swapped. + +# Examples + +Basic usage: + +``` +", $Feature, "let n = 0x1A", stringify!($SelfT), "; + +if cfg!(target_endian = \"little\") { + assert_eq!(n.to_le(), n) +} else { + assert_eq!(n.to_le(), n.swap_bytes()) +}", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } } } - /// Checked negation. Computes `-self`, returning `None` unless `self == - /// 0`. - /// - /// Note that negating any positive integer will overflow. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0u32.checked_neg(), Some(0)); - /// assert_eq!(1u32.checked_neg(), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_neg(self) -> Option { - let (a, b) = self.overflowing_neg(); - if b {None} else {Some(a)} + doc_comment! { + concat!("Checked integer addition. Computes `self + rhs`, returning `None` +if overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(1), ", +"Some(", stringify!($SelfT), "::max_value() - 1)); +assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3),None);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_add(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_add(rhs); + if b {None} else {Some(a)} + } } - /// Checked shift left. Computes `self << rhs`, returning `None` - /// if `rhs` is larger than or equal to the number of bits in `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0x10u32.checked_shl(4), Some(0x100)); - /// assert_eq!(0x10u32.checked_shl(33), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { - let (a, b) = self.overflowing_shl(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Checked integer subtraction. Computes `self - rhs`, returning +`None` if overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(1", stringify!($SelfT), ".checked_sub(1), Some(0)); +assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_sub(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_sub(rhs); + if b {None} else {Some(a)} + } } - /// Checked shift right. Computes `self >> rhs`, returning `None` - /// if `rhs` is larger than or equal to the number of bits in `self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(0x10u32.checked_shr(4), Some(0x1)); - /// assert_eq!(0x10u32.checked_shr(33), None); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { - let (a, b) = self.overflowing_shr(rhs); - if b {None} else {Some(a)} + doc_comment! { + concat!("Checked integer multiplication. Computes `self * rhs`, returning +`None` if overflow occurred. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_mul(1), Some(5)); +assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_mul(self, rhs: Self) -> Option { + let (a, b) = self.overflowing_mul(rhs); + if b {None} else {Some(a)} + } } - /// Saturating integer addition. Computes `self + rhs`, saturating at - /// the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.saturating_add(1), 101); - /// assert_eq!(200u8.saturating_add(127), 255); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn saturating_add(self, rhs: Self) -> Self { - match self.checked_add(rhs) { - Some(x) => x, - None => Self::max_value(), + doc_comment! { + concat!("Checked integer division. Computes `self / rhs`, returning `None` +if `rhs == 0`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64)); +assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn checked_div(self, rhs: Self) -> Option { + match rhs { + 0 => None, + rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }), + } } } - /// Saturating integer subtraction. Computes `self - rhs`, saturating - /// at the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.saturating_sub(27), 73); - /// assert_eq!(13u8.saturating_sub(127), 0); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn saturating_sub(self, rhs: Self) -> Self { - match self.checked_sub(rhs) { - Some(x) => x, - None => Self::min_value(), + doc_comment! { + concat!("Checked integer remainder. Computes `self % rhs`, returning `None` +if `rhs == 0`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".checked_rem(2), Some(1)); +assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_rem(self, rhs: Self) -> Option { + if rhs == 0 { + None + } else { + Some(unsafe { intrinsics::unchecked_rem(self, rhs) }) + } } } - /// Saturating integer multiplication. Computes `self * rhs`, - /// saturating at the numeric bounds instead of overflowing. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::u32; - /// - /// assert_eq!(100u32.saturating_mul(127), 12700); - /// assert_eq!((1u32 << 23).saturating_mul(1 << 23), u32::MAX); - /// ``` - #[stable(feature = "wrapping", since = "1.7.0")] - #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(rhs).unwrap_or(Self::max_value()) + doc_comment! { + concat!("Checked negation. Computes `-self`, returning `None` unless `self == +0`. + +Note that negating any positive integer will overflow. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0", stringify!($SelfT), ".checked_neg(), Some(0)); +assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_neg(self) -> Option { + let (a, b) = self.overflowing_neg(); + if b {None} else {Some(a)} + } } - /// Wrapping (modular) addition. Computes `self + rhs`, - /// wrapping around at the boundary of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(200u8.wrapping_add(55), 255); - /// assert_eq!(200u8.wrapping_add(155), 99); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn wrapping_add(self, rhs: Self) -> Self { - unsafe { - intrinsics::overflowing_add(self, rhs) + doc_comment! { + concat!("Checked shift left. Computes `self << rhs`, returning `None` +if `rhs` is larger than or equal to the number of bits in `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".checked_shl(4), Some(0x10)); +assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} } } - /// Wrapping (modular) subtraction. Computes `self - rhs`, - /// wrapping around at the boundary of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.wrapping_sub(100), 0); - /// assert_eq!(100u8.wrapping_sub(155), 201); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn wrapping_sub(self, rhs: Self) -> Self { - unsafe { - intrinsics::overflowing_sub(self, rhs) + doc_comment! { + concat!("Checked shift right. Computes `self >> rhs`, returning `None` +if `rhs` is larger than or equal to the number of bits in `self`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".checked_shr(4), Some(0x1)); +assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} + } + } + + doc_comment! { + concat!("Saturating integer addition. Computes `self + rhs`, saturating at +the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_add(1), 101); +assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_add(self, rhs: Self) -> Self { + match self.checked_add(rhs) { + Some(x) => x, + None => Self::max_value(), + } + } + } + + doc_comment! { + concat!("Saturating integer subtraction. Computes `self - rhs`, saturating +at the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".saturating_sub(27), 73); +assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn saturating_sub(self, rhs: Self) -> Self { + match self.checked_sub(rhs) { + Some(x) => x, + None => Self::min_value(), + } + } + } + + doc_comment! { + concat!("Saturating integer multiplication. Computes `self * rhs`, +saturating at the numeric bounds instead of overflowing. + +# Examples + +Basic usage: + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(2", stringify!($SelfT), ".saturating_mul(10), 20); +assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($SelfT), +"::MAX);", $EndFeature, " +```"), + #[stable(feature = "wrapping", since = "1.7.0")] + #[inline] + pub fn saturating_mul(self, rhs: Self) -> Self { + self.checked_mul(rhs).unwrap_or(Self::max_value()) + } + } + + doc_comment! { + concat!("Wrapping (modular) addition. Computes `self + rhs`, +wrapping around at the boundary of the type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(200", stringify!($SelfT), ".wrapping_add(55), 255); +assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::max_value()), 199);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_add(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_add(self, rhs) + } + } + } + + doc_comment! { + concat!("Wrapping (modular) subtraction. Computes `self - rhs`, +wrapping around at the boundary of the type. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_sub(100), 0); +assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::max_value()), 101);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn wrapping_sub(self, rhs: Self) -> Self { + unsafe { + intrinsics::overflowing_sub(self, rhs) + } } } @@ -1807,6 +2004,9 @@ macro_rules! uint_impl { /// /// Basic usage: /// + /// Please note that this example is shared between integer types. + /// Which explains why `u8` is used here. + /// /// ``` /// assert_eq!(10u8.wrapping_mul(12), 120); /// assert_eq!(25u8.wrapping_mul(12), 44); @@ -1819,43 +2019,47 @@ macro_rules! uint_impl { } } - /// Wrapping (modular) division. Computes `self / rhs`. - /// Wrapped division on unsigned types is just normal division. - /// There's no way wrapping could ever happen. - /// This function exists, so that all operations - /// are accounted for in the wrapping operations. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.wrapping_div(10), 10); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { - self / rhs + doc_comment! { + concat!("Wrapping (modular) division. Computes `self / rhs`. +Wrapped division on unsigned types is just normal division. +There's no way wrapping could ever happen. +This function exists, so that all operations +are accounted for in the wrapping operations. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_div(self, rhs: Self) -> Self { + self / rhs + } } - /// Wrapping (modular) remainder. Computes `self % rhs`. - /// Wrapped remainder calculation on unsigned types is - /// just the regular remainder calculation. - /// There's no way wrapping could ever happen. - /// This function exists, so that all operations - /// are accounted for in the wrapping operations. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(100u8.wrapping_rem(10), 0); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { - self % rhs + doc_comment! { + concat!("Wrapping (modular) remainder. Computes `self % rhs`. +Wrapped remainder calculation on unsigned types is +just the regular remainder calculation. +There's no way wrapping could ever happen. +This function exists, so that all operations +are accounted for in the wrapping operations. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_rem(self, rhs: Self) -> Self { + self % rhs + } } /// Wrapping (modular) negation. Computes `-self`, @@ -1872,11 +2076,12 @@ macro_rules! uint_impl { /// /// Basic usage: /// + /// Please note that this example is shared between integer types. + /// Which explains why `i8` is used here. + /// /// ``` - /// assert_eq!(100u8.wrapping_neg(), 156); - /// assert_eq!(0u8.wrapping_neg(), 0); - /// assert_eq!(180u8.wrapping_neg(), 76); - /// assert_eq!(180u8.wrapping_neg(), (127 + 1) - (180u8 - (127 + 1))); + /// assert_eq!(100i8.wrapping_neg(), -100); + /// assert_eq!((-128i8).wrapping_neg(), -128); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline] @@ -1884,110 +2089,119 @@ macro_rules! uint_impl { self.overflowing_neg().0 } - /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, - /// where `mask` removes any high-order bits of `rhs` that - /// would cause the shift to exceed the bitwidth of the type. - /// - /// Note that this is *not* the same as a rotate-left; the - /// RHS of a wrapping shift-left is restricted to the range - /// of the type, rather than the bits shifted out of the LHS - /// being returned to the other end. The primitive integer - /// types all implement a `rotate_left` function, which may - /// be what you want instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(1u8.wrapping_shl(7), 128); - /// assert_eq!(1u8.wrapping_shl(8), 1); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_shl(self, rhs: u32) -> Self { - unsafe { - intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + doc_comment! { + concat!("Panic-free bitwise shift-left; yields `self << mask(rhs)`, +where `mask` removes any high-order bits of `rhs` that +would cause the shift to exceed the bitwidth of the type. + +Note that this is *not* the same as a rotate-left; the +RHS of a wrapping shift-left is restricted to the range +of the type, rather than the bits shifted out of the LHS +being returned to the other end. The primitive integer +types all implement a `rotate_left` function, which may +be what you want instead. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(1", stringify!($SelfT), ".wrapping_shl(7), 128); +assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_shl(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT) + } } } - /// Panic-free bitwise shift-right; yields `self >> mask(rhs)`, - /// where `mask` removes any high-order bits of `rhs` that - /// would cause the shift to exceed the bitwidth of the type. - /// - /// Note that this is *not* the same as a rotate-right; the - /// RHS of a wrapping shift-right is restricted to the range - /// of the type, rather than the bits shifted out of the LHS - /// being returned to the other end. The primitive integer - /// types all implement a `rotate_right` function, which may - /// be what you want instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(128u8.wrapping_shr(7), 1); - /// assert_eq!(128u8.wrapping_shr(8), 128); - /// ``` - #[stable(feature = "num_wrapping", since = "1.2.0")] - #[inline] - pub fn wrapping_shr(self, rhs: u32) -> Self { - unsafe { - intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + doc_comment! { + concat!("Panic-free bitwise shift-right; yields `self >> mask(rhs)`, +where `mask` removes any high-order bits of `rhs` that +would cause the shift to exceed the bitwidth of the type. + +Note that this is *not* the same as a rotate-right; the +RHS of a wrapping shift-right is restricted to the range +of the type, rather than the bits shifted out of the LHS +being returned to the other end. The primitive integer +types all implement a `rotate_right` function, which may +be what you want instead. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(128", stringify!($SelfT), ".wrapping_shr(7), 1); +assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, " +```"), + #[stable(feature = "num_wrapping", since = "1.2.0")] + #[inline] + pub fn wrapping_shr(self, rhs: u32) -> Self { + unsafe { + intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT) + } } } - /// Calculates `self` + `rhs` - /// - /// Returns a tuple of the addition along with a boolean indicating - /// whether an arithmetic overflow would occur. If an overflow would - /// have occurred then the wrapped value is returned. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::u32; - /// - /// assert_eq!(5u32.overflowing_add(2), (7, false)); - /// assert_eq!(u32::MAX.overflowing_add(1), (0, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { - intrinsics::add_with_overflow(self as $ActualT, - rhs as $ActualT) - }; - (a as Self, b) + doc_comment! { + concat!("Calculates `self` + `rhs` + +Returns a tuple of the addition along with a boolean indicating +whether an arithmetic overflow would occur. If an overflow would +have occurred then the wrapped value is returned. + +# Examples + +Basic usage + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false)); +assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { + intrinsics::add_with_overflow(self as $ActualT, + rhs as $ActualT) + }; + (a as Self, b) + } } - /// Calculates `self` - `rhs` - /// - /// Returns a tuple of the subtraction along with a boolean indicating - /// whether an arithmetic overflow would occur. If an overflow would - /// have occurred then the wrapped value is returned. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// use std::u32; - /// - /// assert_eq!(5u32.overflowing_sub(2), (3, false)); - /// assert_eq!(0u32.overflowing_sub(1), (u32::MAX, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { - let (a, b) = unsafe { - intrinsics::sub_with_overflow(self as $ActualT, - rhs as $ActualT) - }; - (a as Self, b) + doc_comment! { + concat!("Calculates `self` - `rhs` + +Returns a tuple of the subtraction along with a boolean indicating +whether an arithmetic overflow would occur. If an overflow would +have occurred then the wrapped value is returned. + +# Examples + +Basic usage + +``` +", $Feature, "use std::", stringify!($SelfT), "; + +assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false)); +assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT), "::MAX, true));", +$EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + let (a, b) = unsafe { + intrinsics::sub_with_overflow(self as $ActualT, + rhs as $ActualT) + }; + (a as Self, b) + } } /// Calculates the multiplication of `self` and `rhs`. @@ -1998,7 +2212,10 @@ macro_rules! uint_impl { /// /// # Examples /// - /// Basic usage + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. /// /// ``` /// assert_eq!(5u32.overflowing_mul(2), (10, false)); @@ -2014,129 +2231,141 @@ macro_rules! uint_impl { (a as Self, b) } - /// Calculates the divisor when `self` is divided by `rhs`. - /// - /// Returns a tuple of the divisor along with a boolean indicating - /// whether an arithmetic overflow would occur. Note that for unsigned - /// integers overflow never occurs, so the second value is always - /// `false`. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(5u32.overflowing_div(2), (2, false)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { - (self / rhs, false) + doc_comment! { + concat!("Calculates the divisor when `self` is divided by `rhs`. + +Returns a tuple of the divisor along with a boolean indicating +whether an arithmetic overflow would occur. Note that for unsigned +integers overflow never occurs, so the second value is always +`false`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + (self / rhs, false) + } } - /// Calculates the remainder when `self` is divided by `rhs`. - /// - /// Returns a tuple of the remainder after dividing along with a boolean - /// indicating whether an arithmetic overflow would occur. Note that for - /// unsigned integers overflow never occurs, so the second value is - /// always `false`. - /// - /// # Panics - /// - /// This function will panic if `rhs` is 0. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(5u32.overflowing_rem(2), (1, false)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { - (self % rhs, false) + doc_comment! { + concat!("Calculates the remainder when `self` is divided by `rhs`. + +Returns a tuple of the remainder after dividing along with a boolean +indicating whether an arithmetic overflow would occur. Note that for +unsigned integers overflow never occurs, so the second value is +always `false`. + +# Panics + +This function will panic if `rhs` is 0. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + (self % rhs, false) + } } - /// Negates self in an overflowing fashion. - /// - /// Returns `!self + 1` using wrapping operations to return the value - /// that represents the negation of this unsigned value. Note that for - /// positive unsigned values overflow always occurs, but negating 0 does - /// not overflow. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(0u32.overflowing_neg(), (0, false)); - /// assert_eq!(2u32.overflowing_neg(), (-2i32 as u32, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { - ((!self).wrapping_add(1), self != 0) + doc_comment! { + concat!("Negates self in an overflowing fashion. + +Returns `!self + 1` using wrapping operations to return the value +that represents the negation of this unsigned value. Note that for +positive unsigned values overflow always occurs, but negating 0 does +not overflow. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false)); +assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!($SelfT), +", true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_neg(self) -> (Self, bool) { + ((!self).wrapping_add(1), self != 0) + } } - /// Shifts self left by `rhs` bits. - /// - /// Returns a tuple of the shifted version of self along with a boolean - /// indicating whether the shift value was larger than or equal to the - /// number of bits. If the shift value is too large, then value is - /// masked (N-1) where N is the number of bits, and this value is then - /// used to perform the shift. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(0x10u32.overflowing_shl(4), (0x100, false)); - /// assert_eq!(0x10u32.overflowing_shl(36), (0x100, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { - (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + doc_comment! { + concat!("Shifts self left by `rhs` bits. + +Returns a tuple of the shifted version of self along with a boolean +indicating whether the shift value was larger than or equal to the +number of bits. If the shift value is too large, then value is +masked (N-1) where N is the number of bits, and this value is then +used to perform the shift. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false)); +assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shl(rhs), (rhs > ($BITS - 1))) + } } - /// Shifts self right by `rhs` bits. - /// - /// Returns a tuple of the shifted version of self along with a boolean - /// indicating whether the shift value was larger than or equal to the - /// number of bits. If the shift value is too large, then value is - /// masked (N-1) where N is the number of bits, and this value is then - /// used to perform the shift. - /// - /// # Examples - /// - /// Basic usage - /// - /// ``` - /// assert_eq!(0x10u32.overflowing_shr(4), (0x1, false)); - /// assert_eq!(0x10u32.overflowing_shr(36), (0x1, true)); - /// ``` - #[inline] - #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { - (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + doc_comment! { + concat!("Shifts self right by `rhs` bits. + +Returns a tuple of the shifted version of self along with a boolean +indicating whether the shift value was larger than or equal to the +number of bits. If the shift value is too large, then value is +masked (N-1) where N is the number of bits, and this value is then +used to perform the shift. + +# Examples + +Basic usage + +``` +", $Feature, "assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false)); +assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, " +```"), + #[inline] + #[stable(feature = "wrapping", since = "1.7.0")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self.wrapping_shr(rhs), (rhs > ($BITS - 1))) + } } - /// Raises self to the power of `exp`, using exponentiation by squaring. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(2u32.pow(4), 16); - /// ``` + doc_comment! { + concat!("Raises self to the power of `exp`, using exponentiation by squaring. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(4), 16);", $EndFeature, " +```"), #[stable(feature = "rust1", since = "1.0.0")] #[inline] #[rustc_inherit_overflow_checks] @@ -2161,21 +2390,24 @@ macro_rules! uint_impl { acc } + } - /// Returns `true` if and only if `self == 2^k` for some `k`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert!(16u8.is_power_of_two()); - /// assert!(!10u8.is_power_of_two()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn is_power_of_two(self) -> bool { - (self.wrapping_sub(1)) & self == 0 && !(self == 0) + doc_comment! { + concat!("Returns `true` if and only if `self == 2^k` for some `k`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert!(16", stringify!($SelfT), ".is_power_of_two()); +assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn is_power_of_two(self) -> bool { + (self.wrapping_sub(1)) & self == 0 && !(self == 0) + } } // Returns one less than next power of two. @@ -2200,50 +2432,56 @@ macro_rules! uint_impl { <$SelfT>::max_value() >> z } - /// Returns the smallest power of two greater than or equal to `self`. - /// - /// When return value overflows (i.e. `self > (1 << (N-1))` for type - /// `uN`), it panics in debug mode and return value is wrapped to 0 in - /// release mode (the only situation in which method can return 0). - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(2u8.next_power_of_two(), 2); - /// assert_eq!(3u8.next_power_of_two(), 4); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn next_power_of_two(self) -> Self { - // Call the trait to get overflow checks - ops::Add::add(self.one_less_than_next_power_of_two(), 1) + doc_comment! { + concat!("Returns the smallest power of two greater than or equal to `self`. + +When return value overflows (i.e. `self > (1 << (N-1))` for type +`uN`), it panics in debug mode and return value is wrapped to 0 in +release mode (the only situation in which method can return 0). + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(2", stringify!($SelfT), ".next_power_of_two(), 2); +assert_eq!(3", stringify!($SelfT), ".next_power_of_two(), 4);", $EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn next_power_of_two(self) -> Self { + // Call the trait to get overflow checks + ops::Add::add(self.one_less_than_next_power_of_two(), 1) + } } - /// Returns the smallest power of two greater than or equal to `n`. If - /// the next power of two is greater than the type's maximum value, - /// `None` is returned, otherwise the power of two is wrapped in `Some`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!(2u8.checked_next_power_of_two(), Some(2)); - /// assert_eq!(3u8.checked_next_power_of_two(), Some(4)); - /// assert_eq!(200u8.checked_next_power_of_two(), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn checked_next_power_of_two(self) -> Option { - self.one_less_than_next_power_of_two().checked_add(1) + doc_comment! { + concat!("Returns the smallest power of two greater than or equal to `n`. If +the next power of two is greater than the type's maximum value, +`None` is returned, otherwise the power of two is wrapped in `Some`. + +# Examples + +Basic usage: + +``` +", $Feature, "assert_eq!(2", stringify!($SelfT), +".checked_next_power_of_two(), Some(2)); +assert_eq!(3", stringify!($SelfT), ".checked_next_power_of_two(), Some(4)); +assert_eq!(", stringify!($SelfT), "::max_value().checked_next_power_of_two(), None);", +$EndFeature, " +```"), + #[stable(feature = "rust1", since = "1.0.0")] + pub fn checked_next_power_of_two(self) -> Option { + self.one_less_than_next_power_of_two().checked_add(1) + } } } } #[lang = "u8"] impl u8 { - uint_impl! { u8, u8, 8 } + uint_impl! { u8, u8, 8, 255, "", "" } /// Checks if the value is within the ASCII range. @@ -2789,39 +3027,44 @@ impl u8 { #[lang = "u16"] impl u16 { - uint_impl! { u16, u16, 16 } + uint_impl! { u16, u16, 16, 65535, "", "" } } #[lang = "u32"] impl u32 { - uint_impl! { u32, u32, 32 } + uint_impl! { u32, u32, 32, 4294967295, "", "" } } #[lang = "u64"] impl u64 { - uint_impl! { u64, u64, 64 } + uint_impl! { u64, u64, 64, 18446744073709551615, "", "" } } #[lang = "u128"] impl u128 { - uint_impl! { u128, u128, 128 } + uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128_type)] +#![feature(i128)] + +# fn main() { +", " +# }" } } #[cfg(target_pointer_width = "16")] #[lang = "usize"] impl usize { - uint_impl! { usize, u16, 16 } + uint_impl! { usize, u16, 16, 65536, "", "" } } #[cfg(target_pointer_width = "32")] #[lang = "usize"] impl usize { - uint_impl! { usize, u32, 32 } + uint_impl! { usize, u32, 32, 4294967295, "", "" } } #[cfg(target_pointer_width = "64")] #[lang = "usize"] impl usize { - uint_impl! { usize, u64, 64 } + uint_impl! { usize, u64, 64, 18446744073709551615, "", "" } } /// A classification of floating point numbers. diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 089d691773a1b..95bb8f18947ec 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -324,7 +324,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { // the second byte when searching for the third. // // However, this is totally okay. While we have the invariant that - // self.finger is on a UTF8 boundary, this invariant is not relid upon + // self.finger is on a UTF8 boundary, this invariant is not relied upon // within this method (it is relied upon in CharSearcher::next()). // // We only exit this method when we reach the end of the string, or if we diff --git a/src/liblibc b/src/liblibc index 56444a4545bd7..2b4cd1016bdba 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 56444a4545bd71430d64b86b8a71714cfdbe9f5d +Subproject commit 2b4cd1016bdba92becb4f982a4dcb18fe6653bc4 diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 55dcb16c3c95f..e3af285053805 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3362,10 +3362,10 @@ impl<'a> LoweringContext<'a> { v: &Visibility, explicit_owner: Option) -> hir::Visibility { - match *v { - Visibility::Public => hir::Public, - Visibility::Crate(..) => hir::Visibility::Crate, - Visibility::Restricted { ref path, id } => { + match v.node { + VisibilityKind::Public => hir::Public, + VisibilityKind::Crate(..) => hir::Visibility::Crate, + VisibilityKind::Restricted { ref path, id, .. } => { hir::Visibility::Restricted { path: P(self.lower_path(id, path, ParamMode::Explicit, true)), id: if let Some(owner) = explicit_owner { @@ -3375,7 +3375,7 @@ impl<'a> LoweringContext<'a> { } } } - Visibility::Inherited => hir::Inherited, + VisibilityKind::Inherited => hir::Inherited, } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 214d8ec325f2b..12d8d6f3d7481 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -747,7 +747,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyTuple(ref tys, _) => tys.iter() .map(|t| match t.sty { ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple( - span, + Some(span), tys.iter() .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) .collect::>() @@ -815,7 +815,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec) { + /// Given some node representing a fn-like thing in the HIR map, + /// returns a span and `ArgKind` information that describes the + /// arguments it expects. This can be supplied to + /// `report_arg_count_mismatch`. + pub fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec) { match node { hir::map::NodeExpr(&hir::Expr { node: hir::ExprClosure(_, ref _decl, id, span, _), @@ -829,7 +833,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .. } = arg.pat.clone().into_inner() { ArgKind::Tuple( - span, + Some(span), args.iter().map(|pat| { let snippet = self.tcx.sess.codemap() .span_to_snippet(pat.span).unwrap(); @@ -862,7 +866,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (self.tcx.sess.codemap().def_span(span), decl.inputs.iter() .map(|arg| match arg.clone().into_inner().node { hir::TyTup(ref tys) => ArgKind::Tuple( - arg.span, + Some(arg.span), tys.iter() .map(|_| ("_".to_owned(), "_".to_owned())) .collect::>(), @@ -874,7 +878,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } - fn report_arg_count_mismatch( + /// Reports an error when the number of arguments needed by a + /// trait match doesn't match the number that the expression + /// provides. + pub fn report_arg_count_mismatch( &self, span: Span, found_span: Option, @@ -1385,13 +1392,34 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } -enum ArgKind { +/// Summarizes information +pub enum ArgKind { + /// An argument of non-tuple type. Parameters are (name, ty) Arg(String, String), - Tuple(Span, Vec<(String, String)>), + + /// An argument of tuple type. For a "found" argument, the span is + /// the locationo in the source of the pattern. For a "expected" + /// argument, it will be None. The vector is a list of (name, ty) + /// strings for the components of the tuple. + Tuple(Option, Vec<(String, String)>), } impl ArgKind { fn empty() -> ArgKind { ArgKind::Arg("_".to_owned(), "_".to_owned()) } + + /// Creates an `ArgKind` from the expected type of an + /// argument. This has no name (`_`) and no source spans.. + pub fn from_expected_ty(t: Ty<'_>) -> ArgKind { + match t.sty { + ty::TyTuple(ref tys, _) => ArgKind::Tuple( + None, + tys.iter() + .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) + .collect::>() + ), + _ => ArgKind::Arg("_".to_owned(), format!("{}", t.sty)), + } + } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 80819a86b7c46..a80e91df03de1 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -49,7 +49,7 @@ pub use self::util::SupertraitDefIds; pub use self::util::transitive_bounds; mod coherence; -mod error_reporting; +pub mod error_reporting; mod fulfill; mod project; mod object_safety; diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 352184c1efa76..c088458c3557c 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -13,9 +13,9 @@ use rustc_errors; use syntax::abi::Abi; use syntax::ast::{Crate, Attribute, LitKind, StrStyle, ExprKind}; use syntax::ast::{Unsafety, Constness, Generics, Mutability, Ty, Mac, Arg}; -use syntax::ast::{self, Ident, Item, ItemKind, TyKind, Visibility, Expr}; +use syntax::ast::{self, Ident, Item, ItemKind, TyKind, VisibilityKind, Expr}; use syntax::attr; -use syntax::codemap::dummy_spanned; +use syntax::codemap::{dummy_spanned, respan}; use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute}; use syntax::ext::base::ExtCtxt; use syntax::ext::base::Resolver; @@ -97,7 +97,11 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { ]); let mut items = vec![ f.cx.item_extern_crate(f.span, f.alloc), - f.cx.item_use_simple(f.span, Visibility::Inherited, super_path), + f.cx.item_use_simple( + f.span, + respan(f.span.empty(), VisibilityKind::Inherited), + super_path, + ), ]; for method in ALLOCATOR_METHODS { items.push(f.allocator_fn(method)); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index d73e968a82760..c1340d0a28a44 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -34,6 +34,7 @@ use std::rc::Rc; use syntax::ast; use syntax::attr; +use syntax::codemap; use syntax::ext::base::SyntaxExtension; use syntax::parse::filemap_to_stream; use syntax::symbol::Symbol; @@ -496,7 +497,7 @@ impl CrateStore for cstore::CStore { tokens: body.into(), legacy: def.legacy, }), - vis: ast::Visibility::Inherited, + vis: codemap::respan(local_span.empty(), ast::VisibilityKind::Inherited), tokens: None, }) } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 6971033c8994b..bb6dbe632e316 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -58,14 +58,14 @@ impl<'a> AstValidator<'a> { } } - fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) { - if vis != &Visibility::Inherited { + fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) { + if vis.node != VisibilityKind::Inherited { let mut err = struct_span_err!(self.session, - span, + vis.span, E0449, "unnecessary visibility qualifier"); - if vis == &Visibility::Public { - err.span_label(span, "`pub` not needed here"); + if vis.node == VisibilityKind::Public { + err.span_label(vis.span, "`pub` not needed here"); } if let Some(note) = note { err.note(note); @@ -216,7 +216,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_item(&mut self, item: &'a Item) { match item.node { ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { - self.invalid_visibility(&item.vis, item.span, None); + self.invalid_visibility(&item.vis, None); if ty.node == TyKind::Err { self.err_handler() .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") @@ -226,7 +226,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { span_err!(self.session, item.span, E0198, "negative impls cannot be unsafe"); } for impl_item in impl_items { - self.invalid_visibility(&impl_item.vis, impl_item.span, None); + self.invalid_visibility(&impl_item.vis, None); if let ImplItemKind::Method(ref sig, _) = impl_item.node { self.check_trait_fn_not_const(sig.constness); } @@ -234,7 +234,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => { self.invalid_visibility(&item.vis, - item.span, Some("place qualifiers on individual impl items instead")); if unsafety == Unsafety::Unsafe { span_err!(self.session, item.span, E0197, "inherent impls cannot be unsafe"); @@ -247,16 +246,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } ItemKind::ForeignMod(..) => { - self.invalid_visibility(&item.vis, - item.span, - Some("place qualifiers on individual foreign items \ - instead")); + self.invalid_visibility( + &item.vis, + Some("place qualifiers on individual foreign items instead"), + ); } ItemKind::Enum(ref def, _) => { for variant in &def.variants { self.invalid_non_exhaustive_attribute(variant); for field in variant.node.data.fields() { - self.invalid_visibility(&field.vis, field.span, None); + self.invalid_visibility(&field.vis, None); } } } @@ -359,8 +358,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_vis(&mut self, vis: &'a Visibility) { - match *vis { - Visibility::Restricted { ref path, .. } => { + match vis.node { + VisibilityKind::Restricted { ref path, .. } => { path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| { self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(), "generic arguments in visibility path"); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 5a321053b7ae8..865c6b422f3d4 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -86,7 +86,7 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. if let ast::ItemKind::Use(..) = item.node { - if item.vis == ast::Visibility::Public || item.span.source_equal(&DUMMY_SP) { + if item.vis.node == ast::VisibilityKind::Public || item.span.source_equal(&DUMMY_SP) { return; } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2da4bfedd3a17..facca445b9785 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3796,13 +3796,15 @@ impl<'a> Resolver<'a> { } fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { - match *vis { - ast::Visibility::Public => ty::Visibility::Public, - ast::Visibility::Crate(..) => ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)), - ast::Visibility::Inherited => { + match vis.node { + ast::VisibilityKind::Public => ty::Visibility::Public, + ast::VisibilityKind::Crate(..) => { + ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + } + ast::VisibilityKind::Inherited => { ty::Visibility::Restricted(self.current_module.normal_ancestor_id) } - ast::Visibility::Restricted { ref path, id } => { + ast::VisibilityKind::Restricted { ref path, id, .. } => { let def = self.smart_resolve_path(id, None, path, PathSource::Visibility).base_def(); if def == Def::Err { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 47530c4208520..bf82b0774238b 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -43,7 +43,7 @@ use syntax::print::pprust::{ ty_to_string }; use syntax::ptr::P; -use syntax::codemap::{Spanned, DUMMY_SP}; +use syntax::codemap::{Spanned, DUMMY_SP, respan}; use syntax_pos::*; use {escape, generated_code, lower_attributes, PathCollector, SaveContext}; @@ -65,12 +65,19 @@ macro_rules! down_cast_data { } macro_rules! access_from { + ($save_ctxt:expr, $vis:expr, $id:expr) => { + Access { + public: $vis.node == ast::VisibilityKind::Public, + reachable: $save_ctxt.analysis.access_levels.is_reachable($id), + } + }; + ($save_ctxt:expr, $item:expr) => { Access { - public: $item.vis == ast::Visibility::Public, + public: $item.vis.node == ast::VisibilityKind::Public, reachable: $save_ctxt.analysis.access_levels.is_reachable($item.id), } - } + }; } pub struct DumpVisitor<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> { @@ -405,12 +412,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { method_data.value = sig_str; method_data.sig = sig::method_signature(id, name, generics, sig, &self.save_ctxt); - self.dumper.dump_def( - &Access { - public: vis == ast::Visibility::Public, - reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), - }, - method_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, vis, id), method_data); } // walk arg and return types @@ -543,10 +545,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let span = self.span_from_span(sub_span.expect("No span found for variable")); self.dumper.dump_def( - &Access { - public: vis == ast::Visibility::Public, - reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), - }, + &access_from!(self.save_ctxt, vis, id), Def { kind: DefKind::Const, id: ::id_from_node_id(id, &self.save_ctxt), @@ -597,7 +596,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .iter() .enumerate() .filter_map(|(i, f)| { - if include_priv_fields || f.vis == ast::Visibility::Public { + if include_priv_fields || f.vis.node == ast::VisibilityKind::Public { f.ident .map(|i| i.to_string()) .or_else(|| Some(i.to_string())) @@ -1135,6 +1134,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) { self.process_macro_use(trait_item.span); + let vis_span = trait_item.span.empty(); match trait_item.node { ast::TraitItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( @@ -1144,7 +1144,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { &ty, expr.as_ref().map(|e| &**e), trait_id, - ast::Visibility::Public, + respan(vis_span, ast::VisibilityKind::Public), &trait_item.attrs, ); } @@ -1155,7 +1155,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { trait_item.id, trait_item.ident, &trait_item.generics, - ast::Visibility::Public, + respan(vis_span, ast::VisibilityKind::Public), trait_item.span, ); } @@ -1259,10 +1259,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // The access is calculated using the current tree ID, but with the root tree's visibility // (since nested trees don't have their own visibility). - let access = Access { - public: root_item.vis == ast::Visibility::Public, - reachable: self.save_ctxt.analysis.access_levels.is_reachable(id), - }; + let access = access_from!(self.save_ctxt, root_item.vis, id); // The parent def id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index df15f781ae8c9..794d466ee7cdb 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -17,14 +17,24 @@ use rustc::hir::def_id::DefId; use rustc::infer::{InferOk, InferResult}; use rustc::infer::LateBoundRegionConversionTime; use rustc::infer::type_variable::TypeVariableOrigin; +use rustc::traits::error_reporting::ArgKind; use rustc::ty::{self, ToPolyTraitRef, Ty}; use rustc::ty::subst::Substs; use rustc::ty::TypeFoldable; use std::cmp; use std::iter; use syntax::abi::Abi; +use syntax::codemap::Span; use rustc::hir; +/// What signature do we *expect* the closure to have from context? +#[derive(Debug)] +struct ExpectedSig<'tcx> { + /// Span that gave us this expectation, if we know that. + cause_span: Option, + sig: ty::FnSig<'tcx>, +} + struct ClosureSignatures<'tcx> { bound_sig: ty::PolyFnSig<'tcx>, liberated_sig: ty::FnSig<'tcx>, @@ -42,8 +52,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ) -> Ty<'tcx> { debug!( "check_expr_closure(expr={:?},expected={:?})", - expr, - expected + expr, expected ); // It's always helpful for inference if we know the kind of @@ -64,12 +73,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { decl: &'gcx hir::FnDecl, body: &'gcx hir::Body, gen: Option, - expected_sig: Option>, + expected_sig: Option>, ) -> Ty<'tcx> { debug!( "check_closure(opt_kind={:?}, expected_sig={:?})", - opt_kind, - expected_sig + opt_kind, expected_sig ); let expr_def_id = self.tcx.hir.local_def_id(expr.id); @@ -109,19 +117,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let closure_type = self.tcx.mk_closure(expr_def_id, substs); if let Some(GeneratorTypes { yield_ty, interior }) = generator_types { - self.demand_eqtype(expr.span, - yield_ty, - substs.generator_yield_ty(expr_def_id, self.tcx)); - self.demand_eqtype(expr.span, - liberated_sig.output(), - substs.generator_return_ty(expr_def_id, self.tcx)); + self.demand_eqtype( + expr.span, + yield_ty, + substs.generator_yield_ty(expr_def_id, self.tcx), + ); + self.demand_eqtype( + expr.span, + liberated_sig.output(), + substs.generator_return_ty(expr_def_id, self.tcx), + ); return self.tcx.mk_generator(expr_def_id, substs, interior); } debug!( "check_closure: expr.id={:?} closure_type={:?}", - expr.id, - closure_type + expr.id, closure_type ); // Tuple up the arguments and insert the resulting function type into @@ -138,29 +149,33 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!( "check_closure: expr_def_id={:?}, sig={:?}, opt_kind={:?}", - expr_def_id, - sig, - opt_kind + expr_def_id, sig, opt_kind ); let sig_fn_ptr_ty = self.tcx.mk_fn_ptr(sig); - self.demand_eqtype(expr.span, - sig_fn_ptr_ty, - substs.closure_sig_ty(expr_def_id, self.tcx)); + self.demand_eqtype( + expr.span, + sig_fn_ptr_ty, + substs.closure_sig_ty(expr_def_id, self.tcx), + ); if let Some(kind) = opt_kind { - self.demand_eqtype(expr.span, - kind.to_ty(self.tcx), - substs.closure_kind_ty(expr_def_id, self.tcx)); + self.demand_eqtype( + expr.span, + kind.to_ty(self.tcx), + substs.closure_kind_ty(expr_def_id, self.tcx), + ); } closure_type } + /// Given the expected type, figures out what it can about this closure we + /// are about to type check: fn deduce_expectations_from_expected_type( &self, expected_ty: Ty<'tcx>, - ) -> (Option>, Option) { + ) -> (Option>, Option) { debug!( "deduce_expectations_from_expected_type(expected_ty={:?})", expected_ty @@ -172,7 +187,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .projection_bounds() .filter_map(|pb| { let pb = pb.with_self_ty(self.tcx, self.tcx.types.err); - self.deduce_sig_from_projection(&pb) + self.deduce_sig_from_projection(None, &pb) }) .next(); let kind = object_type @@ -181,7 +196,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (sig, kind) } ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), - ty::TyFnPtr(sig) => (Some(sig.skip_binder().clone()), Some(ty::ClosureKind::Fn)), + ty::TyFnPtr(sig) => { + let expected_sig = ExpectedSig { + cause_span: None, + sig: sig.skip_binder().clone(), + }; + (Some(expected_sig), Some(ty::ClosureKind::Fn)) + } _ => (None, None), } } @@ -189,7 +210,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn deduce_expectations_from_obligations( &self, expected_vid: ty::TyVid, - ) -> (Option>, Option) { + ) -> (Option>, Option) { let fulfillment_cx = self.fulfillment_cx.borrow(); // Here `expected_ty` is known to be a type inference variable. @@ -209,7 +230,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Predicate::Projection(ref proj_predicate) => { let trait_ref = proj_predicate.to_poly_trait_ref(self.tcx); self.self_type_matches_expected_vid(trait_ref, expected_vid) - .and_then(|_| self.deduce_sig_from_projection(proj_predicate)) + .and_then(|_| { + self.deduce_sig_from_projection( + Some(obligation.cause.span), + proj_predicate, + ) + }) } _ => None, } @@ -259,10 +285,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// Given a projection like "::Result == Y", we can deduce /// everything we need to know about a closure. + /// + /// The `cause_span` should be the span that caused us to + /// have this expected signature, or `None` if we can't readily + /// know that. fn deduce_sig_from_projection( &self, + cause_span: Option, projection: &ty::PolyProjectionPredicate<'tcx>, - ) -> Option> { + ) -> Option> { let tcx = self.tcx; debug!("deduce_sig_from_projection({:?})", projection); @@ -294,16 +325,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ret_param_ty ); - let fn_sig = self.tcx.mk_fn_sig( + let sig = self.tcx.mk_fn_sig( input_tys.cloned(), ret_param_ty, false, hir::Unsafety::Normal, Abi::Rust, ); - debug!("deduce_sig_from_projection: fn_sig {:?}", fn_sig); + debug!("deduce_sig_from_projection: sig {:?}", sig); - Some(fn_sig) + Some(ExpectedSig { cause_span, sig }) } fn self_type_matches_expected_vid( @@ -314,8 +345,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let self_ty = self.shallow_resolve(trait_ref.self_ty()); debug!( "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?})", - trait_ref, - self_ty + trait_ref, self_ty ); match self_ty.sty { ty::TyInfer(ty::TyVar(v)) if expected_vid == v => Some(trait_ref), @@ -328,7 +358,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr_def_id: DefId, decl: &hir::FnDecl, body: &hir::Body, - expected_sig: Option>, + expected_sig: Option>, ) -> ClosureSignatures<'tcx> { if let Some(e) = expected_sig { self.sig_of_closure_with_expectation(expr_def_id, decl, body, e) @@ -404,7 +434,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr_def_id: DefId, decl: &hir::FnDecl, body: &hir::Body, - expected_sig: ty::FnSig<'tcx>, + expected_sig: ExpectedSig<'tcx>, ) -> ClosureSignatures<'tcx> { debug!( "sig_of_closure_with_expectation(expected_sig={:?})", @@ -414,20 +444,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Watch out for some surprises and just ignore the // expectation if things don't see to match up with what we // expect. - if expected_sig.variadic != decl.variadic { - return self.sig_of_closure_no_expectation(expr_def_id, decl, body); - } else if expected_sig.inputs_and_output.len() != decl.inputs.len() + 1 { - // we could probably handle this case more gracefully + if expected_sig.sig.variadic != decl.variadic { return self.sig_of_closure_no_expectation(expr_def_id, decl, body); + } else if expected_sig.sig.inputs_and_output.len() != decl.inputs.len() + 1 { + return self.sig_of_closure_with_mismatched_number_of_arguments( + expr_def_id, + decl, + body, + expected_sig, + ); } // Create a `PolyFnSig`. Note the oddity that late bound // regions appearing free in `expected_sig` are now bound up // in this binder we are creating. - assert!(!expected_sig.has_regions_escaping_depth(1)); + assert!(!expected_sig.sig.has_regions_escaping_depth(1)); let bound_sig = ty::Binder(self.tcx.mk_fn_sig( - expected_sig.inputs().iter().cloned(), - expected_sig.output(), + expected_sig.sig.inputs().iter().cloned(), + expected_sig.sig.output(), decl.variadic, hir::Unsafety::Normal, Abi::RustCall, @@ -453,6 +487,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { closure_sigs } + fn sig_of_closure_with_mismatched_number_of_arguments( + &self, + expr_def_id: DefId, + decl: &hir::FnDecl, + body: &hir::Body, + expected_sig: ExpectedSig<'tcx>, + ) -> ClosureSignatures<'tcx> { + let expr_map_node = self.tcx.hir.get_if_local(expr_def_id).unwrap(); + let expected_args: Vec<_> = expected_sig + .sig + .inputs() + .iter() + .map(|ty| ArgKind::from_expected_ty(ty)) + .collect(); + let (closure_span, found_args) = self.get_fn_like_arguments(expr_map_node); + let expected_span = expected_sig.cause_span.unwrap_or(closure_span); + self.report_arg_count_mismatch( + expected_span, + Some(closure_span), + expected_args, + found_args, + true, + ).emit(); + + let error_sig = self.error_sig_of_closure(decl); + + self.closure_sigs(expr_def_id, body, error_sig) + } + /// Enforce the user's types against the expectation. See /// `sig_of_closure_with_expectation` for details on the overall /// strategy. @@ -558,13 +621,46 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { result } + /// Converts the types that the user supplied, in case that doing + /// so should yield an error, but returns back a signature where + /// all parameters are of type `TyErr`. + fn error_sig_of_closure(&self, decl: &hir::FnDecl) -> ty::PolyFnSig<'tcx> { + let astconv: &AstConv = self; + + let supplied_arguments = decl.inputs.iter().map(|a| { + // Convert the types that the user supplied (if any), but ignore them. + astconv.ast_ty_to_ty(a); + self.tcx.types.err + }); + + match decl.output { + hir::Return(ref output) => { + astconv.ast_ty_to_ty(&output); + } + hir::DefaultReturn(_) => {} + } + + let result = ty::Binder(self.tcx.mk_fn_sig( + supplied_arguments, + self.tcx.types.err, + decl.variadic, + hir::Unsafety::Normal, + Abi::RustCall, + )); + + debug!("supplied_sig_of_closure: result={:?}", result); + + result + } + fn closure_sigs( &self, expr_def_id: DefId, body: &hir::Body, bound_sig: ty::PolyFnSig<'tcx>, ) -> ClosureSignatures<'tcx> { - let liberated_sig = self.tcx().liberate_late_bound_regions(expr_def_id, &bound_sig); + let liberated_sig = self.tcx() + .liberate_late_bound_regions(expr_def_id, &bound_sig); let liberated_sig = self.inh.normalize_associated_types_in( body.value.span, body.value.id, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 087d88419bc84..08258489a2ec2 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -345,6 +345,7 @@ pub fn make_test(s: &str, opts: &TestOptions) -> (String, usize) { let (crate_attrs, everything_else) = partition_source(s); + let everything_else = everything_else.trim(); let mut line_offset = 0; let mut prog = String::new(); @@ -392,12 +393,11 @@ pub fn make_test(s: &str, .any(|code| code.contains("fn main")); if dont_insert_main || already_has_main { - prog.push_str(&everything_else); + prog.push_str(everything_else); } else { prog.push_str("fn main() {\n"); line_offset += 1; - prog.push_str(&everything_else); - prog = prog.trim().into(); + prog.push_str(everything_else); prog.push_str("\n}"); } @@ -753,3 +753,217 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { self.visit_testable(macro_def.name.to_string(), ¯o_def.attrs, |_| ()); } } + +#[cfg(test)] +mod tests { + use super::{TestOptions, make_test}; + + #[test] + fn make_test_basic() { + //basic use: wraps with `fn main`, adds `#![allow(unused)]` + let opts = TestOptions::default(); + let input = +"assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, None, false, &opts); + assert_eq!(output, (expected.clone(), 2)); + } + + #[test] + fn make_test_crate_name_no_use() { + //if you give a crate name but *don't* use it within the test, it won't bother inserting + //the `extern crate` statement + let opts = TestOptions::default(); + let input = +"assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 2)); + } + + #[test] + fn make_test_crate_name() { + //if you give a crate name and use it within the test, it will insert an `extern crate` + //statement before `fn main` + let opts = TestOptions::default(); + let input = +"use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +extern crate asdf; +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 3)); + } + + #[test] + fn make_test_no_crate_inject() { + //even if you do use the crate within the test, setting `opts.no_crate_inject` will skip + //adding it anyway + let opts = TestOptions { + no_crate_inject: true, + attrs: vec![], + }; + let input = +"use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 2)); + } + + #[test] + fn make_test_ignore_std() { + //even if you include a crate name, and use it in the doctest, we still won't include an + //`extern crate` statement if the crate is "std" - that's included already by the compiler! + let opts = TestOptions::default(); + let input = +"use std::*; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +use std::*; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("std"), false, &opts); + assert_eq!(output, (expected, 2)); + } + + #[test] + fn make_test_manual_extern_crate() { + //when you manually include an `extern crate` statement in your doctest, make_test assumes + //you've included one for your own crate too + let opts = TestOptions::default(); + let input = +"extern crate asdf; +use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +extern crate asdf; +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 2)); + } + + #[test] + fn make_test_opts_attrs() { + //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those + //instead of the stock #![allow(unused)] + let mut opts = TestOptions::default(); + opts.attrs.push("feature(sick_rad)".to_string()); + let input = +"use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![feature(sick_rad)] +extern crate asdf; +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 3)); + + //adding more will also bump the returned line offset + opts.attrs.push("feature(hella_dope)".to_string()); + let expected = +"#![feature(sick_rad)] +#![feature(hella_dope)] +extern crate asdf; +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 4)); + } + + #[test] + fn make_test_crate_attrs() { + //including inner attributes in your doctest will apply them to the whole "crate", pasting + //them outside the generated main function + let opts = TestOptions::default(); + let input = +"#![feature(sick_rad)] +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +#![feature(sick_rad)] +fn main() { +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, None, false, &opts); + assert_eq!(output, (expected, 2)); + } + + #[test] + fn make_test_with_main() { + //including your own `fn main` wrapper lets the test use it verbatim + let opts = TestOptions::default(); + let input = +"fn main() { + assert_eq!(2+2, 4); +}"; + let expected = +"#![allow(unused)] +fn main() { + assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, None, false, &opts); + assert_eq!(output, (expected, 1)); + } + + #[test] + fn make_test_fake_main() { + //...but putting it in a comment will still provide a wrapper + let opts = TestOptions::default(); + let input = +"//Ceci n'est pas une `fn main` +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +fn main() { +//Ceci n'est pas une `fn main` +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, None, false, &opts); + assert_eq!(output, (expected.clone(), 2)); + } + + #[test] + fn make_test_dont_insert_main() { + //even with that, if you set `dont_insert_main`, it won't create the `fn main` wrapper + let opts = TestOptions::default(); + let input = +"//Ceci n'est pas une `fn main` +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +//Ceci n'est pas une `fn main` +assert_eq!(2+2, 4);".to_string(); + let output = make_test(input, None, true, &opts); + assert_eq!(output, (expected.clone(), 1)); + } +} diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 33d11ebb35022..aa07f64b67859 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1437,8 +1437,6 @@ pub trait BufRead: Read { /// /// If successful, this function will return the total number of bytes read. /// - /// An empty buffer returned indicates that the stream has reached EOF. - /// /// # Errors /// /// This function will ignore all instances of [`ErrorKind::Interrupted`] and diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index a2caf47e8cced..358aa2c37dfb4 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -720,10 +720,6 @@ mod prim_f64 { } /// The 8-bit signed integer type. /// /// *[See also the `std::i8` module](i8/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `i64` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_i8 { } @@ -732,10 +728,6 @@ mod prim_i8 { } /// The 16-bit signed integer type. /// /// *[See also the `std::i16` module](i16/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `i32` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_i16 { } @@ -744,10 +736,6 @@ mod prim_i16 { } /// The 32-bit signed integer type. /// /// *[See also the `std::i32` module](i32/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `i16` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_i32 { } @@ -756,10 +744,6 @@ mod prim_i32 { } /// The 64-bit signed integer type. /// /// *[See also the `std::i64` module](i64/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `i8` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_i64 { } @@ -768,10 +752,6 @@ mod prim_i64 { } /// The 128-bit signed integer type. /// /// *[See also the `std::i128` module](i128/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `i8` in there. -/// #[unstable(feature = "i128", issue="35118")] mod prim_i128 { } @@ -780,10 +760,6 @@ mod prim_i128 { } /// The 8-bit unsigned integer type. /// /// *[See also the `std::u8` module](u8/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `u64` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_u8 { } @@ -792,10 +768,6 @@ mod prim_u8 { } /// The 16-bit unsigned integer type. /// /// *[See also the `std::u16` module](u16/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `u32` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_u16 { } @@ -804,10 +776,6 @@ mod prim_u16 { } /// The 32-bit unsigned integer type. /// /// *[See also the `std::u32` module](u32/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `u16` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_u32 { } @@ -816,10 +784,6 @@ mod prim_u32 { } /// The 64-bit unsigned integer type. /// /// *[See also the `std::u64` module](u64/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `u8` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_u64 { } @@ -828,10 +792,6 @@ mod prim_u64 { } /// The 128-bit unsigned integer type. /// /// *[See also the `std::u128` module](u128/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `u8` in there. -/// #[unstable(feature = "i128", issue="35118")] mod prim_u128 { } @@ -844,10 +804,6 @@ mod prim_u128 { } /// and on a 64 bit target, this is 8 bytes. /// /// *[See also the `std::isize` module](isize/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `usize` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_isize { } @@ -860,10 +816,6 @@ mod prim_isize { } /// and on a 64 bit target, this is 8 bytes. /// /// *[See also the `std::usize` module](usize/index.html).* -/// -/// However, please note that examples are shared between primitive integer -/// types. So it's normal if you see usage of types like `isize` in there. -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_usize { } diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 564021758176b..54bb65136508b 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -47,11 +47,13 @@ impl WaitTimeoutResult { /// /// thread::spawn(move|| { /// let &(ref lock, ref cvar) = &*pair2; + /// + /// // Let's wait 20 milliseconds before notifying the condvar. + /// thread::sleep(Duration::from_millis(20)); + /// /// let mut started = lock.lock().unwrap(); /// // We update the boolean value. /// *started = true; - /// // Let's wait 20 milliseconds before notifying the condvar. - /// thread::sleep(Duration::from_millis(20)); /// cvar.notify_one(); /// }); /// diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c7ab6158256ba..c5a383bfa2ff5 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1937,10 +1937,12 @@ pub enum CrateSugar { JustCrate, } +pub type Visibility = Spanned; + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Visibility { +pub enum VisibilityKind { Public, - Crate(Span, CrateSugar), + Crate(CrateSugar), Restricted { path: P, id: NodeId }, Inherited, } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 5224f52c49629..dd27dea4f0d97 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -14,6 +14,7 @@ use std::env; use ast; use ast::{Ident, Name}; +use codemap; use syntax_pos::Span; use ext::base::{ExtCtxt, MacEager, MacResult}; use ext::build::AstBuilder; @@ -234,7 +235,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, ty, expr, ), - vis: ast::Visibility::Public, + vis: codemap::respan(span.empty(), ast::VisibilityKind::Public), span, tokens: None, }) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 2e6de96d65a6d..7681f55bd8ccb 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -987,7 +987,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attrs, id: ast::DUMMY_NODE_ID, node, - vis: ast::Visibility::Inherited, + vis: respan(span.empty(), ast::VisibilityKind::Inherited), span, tokens: None, }) @@ -1033,7 +1033,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { span: ty.span, ty, ident: None, - vis: ast::Visibility::Inherited, + vis: respan(span.empty(), ast::VisibilityKind::Inherited), attrs: Vec::new(), id: ast::DUMMY_NODE_ID, } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 44a073545a730..d4d9dfb01da2c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -11,7 +11,7 @@ use ast::{self, Block, Ident, NodeId, PatKind, Path}; use ast::{MacStmtStyle, StmtKind, ItemKind}; use attr::{self, HasAttrs}; -use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, dummy_spanned}; +use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, dummy_spanned, respan}; use config::{is_test_or_bench, StripUnconfigured}; use errors::FatalError; use ext::base::*; @@ -238,7 +238,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { node: ast::ItemKind::Mod(krate.module), ident: keywords::Invalid.ident(), id: ast::DUMMY_NODE_ID, - vis: ast::Visibility::Public, + vis: respan(krate.span.empty(), ast::VisibilityKind::Public), tokens: None, }))); @@ -1022,7 +1022,10 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { // Ensure that test functions are accessible from the test harness. ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => { if item.attrs.iter().any(|attr| is_test_or_bench(attr)) { - item = item.map(|mut item| { item.vis = ast::Visibility::Public; item }); + item = item.map(|mut item| { + item.vis = respan(item.vis.span, ast::VisibilityKind::Public); + item + }); } noop_fold_item(item, self) } diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 2f5b386346bc8..9c2c22476e9d9 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -33,7 +33,7 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion { let ident = keywords::Invalid.ident(); let attrs = Vec::new(); let generics = ast::Generics::default(); - let vis = ast::Visibility::Inherited; + let vis = dummy_spanned(ast::VisibilityKind::Inherited); let span = DUMMY_SP; let expr_placeholder = || P(ast::Expr { id, span, diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7fcd88c94ca6f..7a024dbad8830 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -9,6 +9,7 @@ // except according to those terms. use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Stmt, Ty}; +use codemap::respan; use syntax_pos::Span; use ext::base::ExtCtxt; use ext::base; @@ -855,7 +856,12 @@ fn expand_wrapper(cx: &ExtCtxt, let mut stmts = imports.iter().map(|path| { // make item: `use ...;` let path = path.iter().map(|s| s.to_string()).collect(); - cx.stmt_item(sp, cx.item_use_glob(sp, ast::Visibility::Inherited, ids_ext(path))) + let use_item = cx.item_use_glob( + sp, + respan(sp.empty(), ast::VisibilityKind::Inherited), + ids_ext(path), + ); + cx.stmt_item(sp, use_item) }).chain(Some(stmt_let_ext_cx)).collect::>(); stmts.push(cx.stmt_expr(expr)); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3b137f9570a39..c0fde71d086f4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1816,8 +1816,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_vis(&mut self, vis: &'a ast::Visibility) { - if let ast::Visibility::Crate(span, ast::CrateSugar::JustCrate) = *vis { - gate_feature_post!(&self, crate_visibility_modifier, span, + if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node { + gate_feature_post!(&self, crate_visibility_modifier, vis.span, "`crate` visibility modifier is experimental"); } visit::walk_vis(self, vis); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 921ed3565a471..1a2025b073b2b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1018,7 +1018,7 @@ pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, ident: keywords::Invalid.ident(), attrs, id: ast::DUMMY_NODE_ID, - vis: ast::Visibility::Public, + vis: respan(span.empty(), ast::VisibilityKind::Public), span, node: ast::ItemKind::Mod(module), tokens: None, @@ -1367,11 +1367,13 @@ pub fn noop_fold_stmt_kind(node: StmtKind, folder: &mut T) -> SmallVe } pub fn noop_fold_vis(vis: Visibility, folder: &mut T) -> Visibility { - match vis { - Visibility::Restricted { path, id } => Visibility::Restricted { - path: path.map(|path| folder.fold_path(path)), - id: folder.new_id(id) - }, + match vis.node { + VisibilityKind::Restricted { path, id } => { + respan(vis.span, VisibilityKind::Restricted { + path: path.map(|path| folder.fold_path(path)), + id: folder.new_id(id), + }) + } _ => vis, } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index b671f81c2a84b..06eb64e157cd5 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -664,7 +664,7 @@ pub fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler mod tests { use super::*; use syntax_pos::{self, Span, BytePos, Pos, NO_EXPANSION}; - use codemap::Spanned; + use codemap::{respan, Spanned}; use ast::{self, Ident, PatKind}; use abi::Abi; use attr::first_attr_value_str_by_name; @@ -932,7 +932,7 @@ mod tests { span: sp(15,21), recovered: false, })), - vis: ast::Visibility::Inherited, + vis: respan(sp(0, 0), ast::VisibilityKind::Inherited), span: sp(0,21)}))); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ac582627f88fd..573de215a5ec5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -36,7 +36,7 @@ use ast::StrStyle; use ast::SelfKind; use ast::{TraitItem, TraitRef, TraitObjectSyntax}; use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds}; -use ast::{Visibility, WhereClause, CrateSugar}; +use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar}; use ast::{UseTree, UseTreeKind}; use ast::{BinOpKind, UnOp}; use ast::{RangeEnd, RangeSyntax}; @@ -4132,7 +4132,7 @@ impl<'a> Parser<'a> { token::Ident(ident) if ident.name == "macro_rules" && self.look_ahead(1, |t| *t == token::Not) => { let prev_span = self.prev_span; - self.complain_if_pub_macro(vis, prev_span); + self.complain_if_pub_macro(&vis.node, prev_span); self.bump(); self.bump(); @@ -4169,7 +4169,11 @@ impl<'a> Parser<'a> { node: StmtKind::Local(self.parse_local(attrs.into())?), span: lo.to(self.prev_span), } - } else if let Some(macro_def) = self.eat_macro_def(&attrs, &Visibility::Inherited, lo)? { + } else if let Some(macro_def) = self.eat_macro_def( + &attrs, + &codemap::respan(lo, VisibilityKind::Inherited), + lo, + )? { Stmt { id: ast::DUMMY_NODE_ID, node: StmtKind::Item(macro_def), @@ -4296,7 +4300,7 @@ impl<'a> Parser<'a> { self.mk_item( span, id /*id is good here*/, ItemKind::Mac(respan(span, Mac_ { path: pth, tts: tts })), - Visibility::Inherited, + respan(lo, VisibilityKind::Inherited), attrs) }), } @@ -5213,15 +5217,15 @@ impl<'a> Parser<'a> { }) } - fn complain_if_pub_macro(&mut self, vis: &Visibility, sp: Span) { + fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) { if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) { err.emit(); } } - fn complain_if_pub_macro_diag(&mut self, vis: &Visibility, sp: Span) -> PResult<'a, ()> { + fn complain_if_pub_macro_diag(&mut self, vis: &VisibilityKind, sp: Span) -> PResult<'a, ()> { match *vis { - Visibility::Inherited => Ok(()), + VisibilityKind::Inherited => Ok(()), _ => { let is_macro_rules: bool = match self.token { token::Ident(sid) => sid.name == Symbol::intern("macro_rules"), @@ -5283,7 +5287,7 @@ impl<'a> Parser<'a> { self.expect(&token::Not)?; } - self.complain_if_pub_macro(vis, prev_span); + self.complain_if_pub_macro(&vis.node, prev_span); // eat a matched-delimiter token tree: *at_end = true; @@ -5686,12 +5690,13 @@ impl<'a> Parser<'a> { self.expected_tokens.push(TokenType::Keyword(keywords::Crate)); if self.is_crate_vis() { self.bump(); // `crate` - return Ok(Visibility::Crate(self.prev_span, CrateSugar::JustCrate)); + return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate))); } if !self.eat_keyword(keywords::Pub) { - return Ok(Visibility::Inherited) + return Ok(respan(self.prev_span, VisibilityKind::Inherited)) } + let lo = self.prev_span; if self.check(&token::OpenDelim(token::Paren)) { // We don't `self.bump()` the `(` yet because this might be a struct definition where @@ -5702,25 +5707,35 @@ impl<'a> Parser<'a> { // `pub(crate)` self.bump(); // `(` self.bump(); // `crate` - let vis = Visibility::Crate(self.prev_span, CrateSugar::PubCrate); self.expect(&token::CloseDelim(token::Paren))?; // `)` + let vis = respan( + lo.to(self.prev_span), + VisibilityKind::Crate(CrateSugar::PubCrate), + ); return Ok(vis) } else if self.look_ahead(1, |t| t.is_keyword(keywords::In)) { // `pub(in path)` self.bump(); // `(` self.bump(); // `in` let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `path` - let vis = Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }; self.expect(&token::CloseDelim(token::Paren))?; // `)` + let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted { + path: P(path), + id: ast::DUMMY_NODE_ID, + }); return Ok(vis) } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) && self.look_ahead(1, |t| t.is_keyword(keywords::Super) || - t.is_keyword(keywords::SelfValue)) { + t.is_keyword(keywords::SelfValue)) + { // `pub(self)` or `pub(super)` self.bump(); // `(` let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `super`/`self` - let vis = Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID }; self.expect(&token::CloseDelim(token::Paren))?; // `)` + let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted { + path: P(path), + id: ast::DUMMY_NODE_ID, + }); return Ok(vis) } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct // `pub(something) fn ...` or `struct X { pub(something) y: Z }` @@ -5740,7 +5755,7 @@ impl<'a> Parser<'a> { } } - Ok(Visibility::Public) + Ok(respan(lo, VisibilityKind::Public)) } /// Parse defaultness: `default` or nothing. @@ -6573,7 +6588,7 @@ impl<'a> Parser<'a> { // Verify wether we have encountered a struct or method definition where the user forgot to // add the `struct` or `fn` keyword after writing `pub`: `pub S {}` - if visibility == Visibility::Public && + if visibility.node == VisibilityKind::Public && self.check_ident() && self.look_ahead(1, |t| *t != token::Not) { @@ -6681,7 +6696,7 @@ impl<'a> Parser<'a> { // MACRO INVOCATION ITEM let prev_span = self.prev_span; - self.complain_if_pub_macro(&visibility, prev_span); + self.complain_if_pub_macro(&visibility.node, prev_span); let mac_lo = self.span; @@ -6715,8 +6730,8 @@ impl<'a> Parser<'a> { } // FAILURE TO PARSE ITEM - match visibility { - Visibility::Inherited => {} + match visibility.node { + VisibilityKind::Inherited => {} _ => { return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`")); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ae459c668aae4..3dfe3c9e5b990 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -377,7 +377,7 @@ pub fn fun_to_string(decl: &ast::FnDecl, to_string(|s| { s.head("")?; s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), - generics, &ast::Visibility::Inherited)?; + generics, &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?; s.end()?; // Close the head box s.end() // Close the outer box }) @@ -1458,13 +1458,13 @@ impl<'a> State<'a> { } pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> { - match *vis { - ast::Visibility::Public => self.word_nbsp("pub"), - ast::Visibility::Crate(_, sugar) => match sugar { + match vis.node { + ast::VisibilityKind::Public => self.word_nbsp("pub"), + ast::VisibilityKind::Crate(sugar) => match sugar { ast::CrateSugar::PubCrate => self.word_nbsp("pub(crate)"), ast::CrateSugar::JustCrate => self.word_nbsp("crate") } - ast::Visibility::Restricted { ref path, .. } => { + ast::VisibilityKind::Restricted { ref path, .. } => { let path = to_string(|s| s.print_path(path, false, 0, true)); if path == "self" || path == "super" { self.word_nbsp(&format!("pub({})", path)) @@ -1472,7 +1472,7 @@ impl<'a> State<'a> { self.word_nbsp(&format!("pub(in {})", path)) } } - ast::Visibility::Inherited => Ok(()) + ast::VisibilityKind::Inherited => Ok(()) } } @@ -1569,15 +1569,23 @@ impl<'a> State<'a> { self.print_outer_attributes(&ti.attrs)?; match ti.node { ast::TraitItemKind::Const(ref ty, ref default) => { - self.print_associated_const(ti.ident, ty, - default.as_ref().map(|expr| &**expr), - &ast::Visibility::Inherited)?; + self.print_associated_const( + ti.ident, + ty, + default.as_ref().map(|expr| &**expr), + &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited), + )?; } ast::TraitItemKind::Method(ref sig, ref body) => { if body.is_some() { self.head("")?; } - self.print_method_sig(ti.ident, &ti.generics, sig, &ast::Visibility::Inherited)?; + self.print_method_sig( + ti.ident, + &ti.generics, + sig, + &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited), + )?; if let Some(ref body) = *body { self.nbsp()?; self.print_block_with_attrs(body, &ti.attrs)?; @@ -3055,7 +3063,7 @@ impl<'a> State<'a> { abi, name, &generics, - &ast::Visibility::Inherited)?; + &codemap::dummy_spanned(ast::VisibilityKind::Inherited))?; self.end() } diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 00546400bb542..da24107f4c33b 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -14,7 +14,7 @@ use std::cell::Cell; use ext::hygiene::{Mark, SyntaxContext}; use symbol::{Symbol, keywords}; use syntax_pos::{DUMMY_SP, Span}; -use codemap::{ExpnInfo, NameAndSpan, MacroAttribute}; +use codemap::{ExpnInfo, NameAndSpan, MacroAttribute, dummy_spanned, respan}; use ptr::P; use tokenstream::TokenStream; @@ -60,7 +60,7 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option P { prefix: path_node(vec![id_test]), kind: ast::UseTreeKind::Simple(id_test), })), - ast::Visibility::Public, keywords::Invalid.ident()) + ast::VisibilityKind::Public, keywords::Invalid.ident()) } else { - (ast::ItemKind::ExternCrate(None), ast::Visibility::Inherited, id_test) + (ast::ItemKind::ExternCrate(None), ast::VisibilityKind::Inherited, id_test) }; P(ast::Item { id: ast::DUMMY_NODE_ID, ident, node: vi, attrs: vec![], - vis, + vis: dummy_spanned(vis), span: sp, tokens: None, }) @@ -513,7 +513,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { attrs: vec![main_attr], id: ast::DUMMY_NODE_ID, node: main, - vis: ast::Visibility::Public, + vis: dummy_spanned(ast::VisibilityKind::Public), span: sp, tokens: None, }) @@ -543,7 +543,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P, Option>) { ident: mod_ident, attrs: vec![], node: item_, - vis: ast::Visibility::Public, + vis: dummy_spanned(ast::VisibilityKind::Public), span: DUMMY_SP, tokens: None, })).pop().unwrap(); @@ -562,7 +562,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P, Option>) { ident: keywords::Invalid.ident(), attrs: vec![], node: ast::ItemKind::Use(P(use_path)), - vis: ast::Visibility::Inherited, + vis: dummy_spanned(ast::VisibilityKind::Inherited), span: DUMMY_SP, tokens: None, })).pop().unwrap() diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bbb123dab2868..4691ddafa36e8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -811,7 +811,7 @@ pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { } pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { - if let Visibility::Restricted { ref path, id } = *vis { + if let VisibilityKind::Restricted { ref path, id } = vis.node { visitor.visit_path(path, id); } } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 0dfe9cb970efb..1b3917efdd1e7 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -530,7 +530,7 @@ impl<'a> TraitDef<'a> { id: ast::DUMMY_NODE_ID, span: self.span, ident, - vis: ast::Visibility::Inherited, + vis: respan(self.span.empty(), ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, attrs: Vec::new(), generics: Generics::default(), @@ -977,7 +977,7 @@ impl<'a> MethodDef<'a> { attrs: self.attributes.clone(), generics: fn_generics, span: trait_.span, - vis: ast::Visibility::Inherited, + vis: respan(trait_.span.empty(), ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, ident: method_ident, node: ast::ImplItemKind::Method(ast::MethodSig { diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 81226ba599ae6..9605f6b5c5a9d 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -19,6 +19,7 @@ /// therefore apply. use syntax::ast; +use syntax::codemap::respan; use syntax::ext::base; use syntax::ext::base::*; use syntax::feature_gate; @@ -59,7 +60,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt, asm, ctxt: cx.backtrace(), })), - vis: ast::Visibility::Inherited, + vis: respan(sp.empty(), ast::VisibilityKind::Inherited), span: sp, tokens: None, }))) diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index 0ba21e6b366cf..e623779ce63ba 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -14,7 +14,7 @@ use errors; use syntax::ast::{self, Ident, NodeId}; use syntax::attr; -use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute}; +use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute, respan}; use syntax::ext::base::ExtCtxt; use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; @@ -103,7 +103,7 @@ impl<'a> CollectProcMacros<'a> { fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) { if self.is_proc_macro_crate && self.in_root && - *vis == ast::Visibility::Public { + vis.node == ast::VisibilityKind::Public { self.handler.span_err(sp, "`proc-macro` crate types cannot \ export any items other than functions \ @@ -181,7 +181,7 @@ impl<'a> CollectProcMacros<'a> { Vec::new() }; - if self.in_root && item.vis == ast::Visibility::Public { + if self.in_root && item.vis.node == ast::VisibilityKind::Public { self.derives.push(ProcMacroDerive { span: item.span, trait_name, @@ -206,7 +206,7 @@ impl<'a> CollectProcMacros<'a> { return; } - if self.in_root && item.vis == ast::Visibility::Public { + if self.in_root && item.vis.node == ast::VisibilityKind::Public { self.attr_macros.push(ProcMacroDef { span: item.span, function_name: item.ident, @@ -229,7 +229,7 @@ impl<'a> CollectProcMacros<'a> { return; } - if self.in_root && item.vis == ast::Visibility::Public { + if self.in_root && item.vis.node == ast::VisibilityKind::Public { self.bang_macros.push(ProcMacroDef { span: item.span, function_name: item.ident, @@ -439,12 +439,12 @@ fn mk_registrar(cx: &mut ExtCtxt, let derive_registrar = cx.attribute(span, derive_registrar); let func = func.map(|mut i| { i.attrs.push(derive_registrar); - i.vis = ast::Visibility::Public; + i.vis = respan(span, ast::VisibilityKind::Public); i }); let ident = ast::Ident::with_empty_ctxt(Symbol::gensym("registrar")); let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| { - i.vis = ast::Visibility::Public; + i.vis = respan(span, ast::VisibilityKind::Public); i }); diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 294506625bc05..0f6dbc39e217a 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -216,6 +216,12 @@ impl Span { self.data().with_ctxt(ctxt) } + /// Returns a new span representing an empty span at the beginning of this span + #[inline] + pub fn empty(self) -> Span { + self.with_hi(self.lo()) + } + /// Returns `self` if `self` is not the dummy span, and `other` otherwise. pub fn substitute_dummy(self, other: Span) -> Span { if self.source_equal(&DUMMY_SP) { other } else { self } diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs index 8e193efaf8504..9e7c3aa490180 100644 --- a/src/test/rustdoc/playground.rs +++ b/src/test/rustdoc/playground.rs @@ -34,6 +34,6 @@ //! } //! ``` -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" // @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly"]' "Run" diff --git a/src/test/ui/error-codes/E0449.stderr b/src/test/ui/error-codes/E0449.stderr index 2270167303a80..3587319ed0cbc 100644 --- a/src/test/ui/error-codes/E0449.stderr +++ b/src/test/ui/error-codes/E0449.stderr @@ -2,23 +2,21 @@ error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:17:1 | 17 | pub impl Bar {} //~ ERROR E0449 - | ^^^^^^^^^^^^^^^ `pub` not needed here + | ^^^ `pub` not needed here | = note: place qualifiers on individual impl items instead error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:19:1 | -19 | / pub impl Foo for Bar { //~ ERROR E0449 -20 | | pub fn foo() {} //~ ERROR E0449 -21 | | } - | |_^ `pub` not needed here +19 | pub impl Foo for Bar { //~ ERROR E0449 + | ^^^ `pub` not needed here error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:20:5 | 20 | pub fn foo() {} //~ ERROR E0449 - | ^^^^^^^^^^^^^^^ `pub` not needed here + | ^^^ `pub` not needed here error: aborting due to 3 previous errors diff --git a/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs new file mode 100644 index 0000000000000..b6463ca067b7f --- /dev/null +++ b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs @@ -0,0 +1,29 @@ +// Copyright 2016 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. + +// Regression test for #47244: in this specific scenario, when the +// expected type indicated 1 argument but the closure takes two, we +// would (early on) create type variables for the type of `b`. If the +// user then attempts to invoke a method on `b`, we would get an error +// saying that the type of `b` must be known, which was not very +// helpful. + +use std::collections::HashMap; +fn main() { + + let m = HashMap::new(); + m.insert( "foo", "bar" ); + + m.iter().map( |_, b| { + //~^ ERROR closure is expected to take a single 2-tuple + + b.to_string() + }); +} diff --git a/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr new file mode 100644 index 0000000000000..34934b8d19598 --- /dev/null +++ b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr @@ -0,0 +1,14 @@ +error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count-expected-type-issue-47244.rs:24:14 + | +24 | m.iter().map( |_, b| { + | ^^^ ------ takes 2 distinct arguments + | | + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +24 | m.iter().map( |(_, b)| { + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/tools/cargo b/src/tools/cargo index 1d6dfea44f971..91e36aa86c703 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 1d6dfea44f97199d5d5c177c7dadcde393eaff9a +Subproject commit 91e36aa86c7037de50642f2fec1cf47c3d18af02