From 1b9ab8939efc1a38a7a5398a069517466fd88d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Tue, 29 May 2018 11:42:13 +0200 Subject: [PATCH 01/13] Make most integer operations const fns --- src/libcore/lib.rs | 1 + src/libcore/num/mod.rs | 154 ++++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 40 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 32cf31231c301..71a727f4c017b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -81,6 +81,7 @@ #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] +#![feature(const_int_ops)] #![feature(core_float)] #![feature(custom_attribute)] #![feature(doc_cfg)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index ea652ad811e3c..60fdd4a3642f6 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -267,8 +267,9 @@ $EndFeature, " ``` "), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } + pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } } doc_comment! { @@ -282,8 +283,9 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn count_zeros(self) -> u32 { + pub const fn count_zeros(self) -> u32 { (!self).count_ones() } } @@ -302,8 +304,9 @@ assert_eq!(n.leading_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn leading_zeros(self) -> u32 { + pub const fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() } } @@ -322,8 +325,9 @@ assert_eq!(n.trailing_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn trailing_zeros(self) -> u32 { + pub const fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() } } @@ -396,8 +400,9 @@ $EndFeature, " /// assert_eq!(m, 21760); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn swap_bytes(self) -> Self { + pub const fn swap_bytes(self) -> Self { (self as $UnsignedT).swap_bytes() as Self } @@ -447,9 +452,17 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn from_be(x: Self) -> Self { - if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + pub const fn from_be(x: Self) -> Self { + #[cfg(target_endian = "big")] + { + x + } + #[cfg(not(target_endian = "big"))] + { + x.swap_bytes() + } } } @@ -473,9 +486,17 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn from_le(x: Self) -> Self { - if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + pub const fn from_le(x: Self) -> Self { + #[cfg(target_endian = "little")] + { + x + } + #[cfg(not(target_endian = "little"))] + { + x.swap_bytes() + } } } @@ -499,9 +520,17 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn to_be(self) -> Self { // or not to be? - if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + pub const fn to_be(self) -> Self { // or not to be? + #[cfg(target_endian = "big")] + { + self + } + #[cfg(not(target_endian = "big"))] + { + self.swap_bytes() + } } } @@ -525,9 +554,17 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn to_le(self) -> Self { - if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + pub const fn to_le(self) -> Self { + #[cfg(target_endian = "little")] + { + self + } + #[cfg(not(target_endian = "little"))] + { + self.swap_bytes() + } } } @@ -1943,6 +1980,19 @@ impl isize { int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" } } +// Emits the correct `cttz` call, depending on the size of the type. +macro_rules! uint_cttz_call { + // 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. + ($value:expr, 8) => { intrinsics::cttz($value as u16 | 0x100) }; + ($value:expr, $_BITS:expr) => { intrinsics::cttz($value) } +} + // `Int` + `UnsignedInt` implemented for unsigned integers macro_rules! uint_impl { ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr) => { @@ -2020,8 +2070,9 @@ Basic usage: assert_eq!(n.count_ones(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn count_ones(self) -> u32 { + pub const fn count_ones(self) -> u32 { unsafe { intrinsics::ctpop(self as $ActualT) as u32 } } } @@ -2037,8 +2088,9 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn count_zeros(self) -> u32 { + pub const fn count_zeros(self) -> u32 { (!self).count_ones() } } @@ -2056,8 +2108,9 @@ Basic usage: assert_eq!(n.leading_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn leading_zeros(self) -> u32 { + pub const fn leading_zeros(self) -> u32 { unsafe { intrinsics::ctlz(self as $ActualT) as u32 } } } @@ -2076,22 +2129,10 @@ Basic usage: assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[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 - } - } + pub const fn trailing_zeros(self) -> u32 { + unsafe { uint_cttz_call!(self, $BITS) as u32 } } } @@ -2167,8 +2208,9 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " /// assert_eq!(m, 21760); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn swap_bytes(self) -> Self { + pub const fn swap_bytes(self) -> Self { unsafe { intrinsics::bswap(self as $ActualT) as Self } } @@ -2218,9 +2260,17 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn from_be(x: Self) -> Self { - if cfg!(target_endian = "big") { x } else { x.swap_bytes() } + pub const fn from_be(x: Self) -> Self { + #[cfg(target_endian = "big")] + { + x + } + #[cfg(not(target_endian = "big"))] + { + x.swap_bytes() + } } } @@ -2244,9 +2294,17 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn from_le(x: Self) -> Self { - if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + pub const fn from_le(x: Self) -> Self { + #[cfg(target_endian = "little")] + { + x + } + #[cfg(not(target_endian = "little"))] + { + x.swap_bytes() + } } } @@ -2270,9 +2328,17 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn to_be(self) -> Self { // or not to be? - if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + pub const fn to_be(self) -> Self { // or not to be? + #[cfg(target_endian = "big")] + { + self + } + #[cfg(not(target_endian = "big"))] + { + self.swap_bytes() + } } } @@ -2296,9 +2362,17 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_int_ops")] #[inline] - pub fn to_le(self) -> Self { - if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + pub const fn to_le(self) -> Self { + #[cfg(target_endian = "little")] + { + self + } + #[cfg(not(target_endian = "little"))] + { + self.swap_bytes() + } } } From 8a27c19c92b293051bd5fa8c3bd18082d8d7dd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sat, 2 Jun 2018 11:24:32 +0200 Subject: [PATCH 02/13] Make integer methods non-const in stage0 --- src/libcore/num/mod.rs | 192 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 60fdd4a3642f6..26dd08b10b9b8 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -267,11 +267,20 @@ $EndFeature, " ``` "), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } + } + doc_comment! { concat!("Returns the number of zeros in the binary representation of `self`. @@ -283,6 +292,7 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn count_zeros(self) -> u32 { @@ -290,6 +300,16 @@ Basic usage: } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentatio"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } + } + doc_comment! { concat!("Returns the number of leading zeros in the binary representation of `self`. @@ -304,6 +324,7 @@ assert_eq!(n.leading_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn leading_zeros(self) -> u32 { @@ -311,6 +332,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[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`. @@ -325,6 +356,7 @@ assert_eq!(n.trailing_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn trailing_zeros(self) -> u32 { @@ -332,6 +364,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn trailing_zeros(self) -> u32 { + (self as $UnsignedT).trailing_zeros() + } + } + /// Shifts the bits to the left by a specified amount, `n`, /// wrapping the truncated bits to the end of the resulting integer. /// @@ -400,12 +442,21 @@ $EndFeature, " /// assert_eq!(m, 21760); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn swap_bytes(self) -> Self { (self as $UnsignedT).swap_bytes() as Self } + /// Dummy docs. See !stage0 documentation. + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn swap_bytes(self) -> Self { + (self as $UnsignedT).swap_bytes() as Self + } + /// Reverses the bit pattern of the integer. /// /// # Examples @@ -452,6 +503,7 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn from_be(x: Self) -> Self { @@ -466,6 +518,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[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 little endian to the target's endianness. @@ -486,6 +548,7 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn from_le(x: Self) -> Self { @@ -500,6 +563,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } + } + doc_comment! { concat!("Converts `self` to big endian from the target's endianness. @@ -520,6 +593,7 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn to_be(self) -> Self { // or not to be? @@ -534,6 +608,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + } + } + doc_comment! { concat!("Converts `self` to little endian from the target's endianness. @@ -554,6 +638,7 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn to_le(self) -> Self { @@ -568,6 +653,16 @@ $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + } + } + doc_comment! { concat!("Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred. @@ -2070,6 +2165,7 @@ Basic usage: assert_eq!(n.count_ones(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn count_ones(self) -> u32 { @@ -2077,6 +2173,16 @@ assert_eq!(n.count_ones(), 3);", $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn count_ones(self) -> u32 { + unsafe { intrinsics::ctpop(self as $ActualT) as u32 } + } + } + doc_comment! { concat!("Returns the number of zeros in the binary representation of `self`. @@ -2088,6 +2194,7 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn count_zeros(self) -> u32 { @@ -2095,6 +2202,16 @@ Basic usage: } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn count_zeros(self) -> u32 { + (!self).count_ones() + } + } + doc_comment! { concat!("Returns the number of leading zeros in the binary representation of `self`. @@ -2108,6 +2225,7 @@ Basic usage: assert_eq!(n.leading_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn leading_zeros(self) -> u32 { @@ -2115,6 +2233,16 @@ assert_eq!(n.leading_zeros(), 2);", $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn leading_zeros(self) -> u32 { + unsafe { intrinsics::ctlz(self as $ActualT) as u32 } + } + } + doc_comment! { concat!("Returns the number of trailing zeros in the binary representation of `self`. @@ -2129,6 +2257,7 @@ Basic usage: assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn trailing_zeros(self) -> u32 { @@ -2136,6 +2265,16 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn trailing_zeros(self) -> u32 { + unsafe { uint_cttz_call!(self, $BITS) as u32 } + } + } + /// Shifts the bits to the left by a specified amount, `n`, /// wrapping the truncated bits to the end of the resulting integer. /// @@ -2208,12 +2347,21 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " /// assert_eq!(m, 21760); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn swap_bytes(self) -> Self { unsafe { intrinsics::bswap(self as $ActualT) as Self } } + /// Dummy docs. See !stage0 documentation. + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn swap_bytes(self) -> Self { + unsafe { intrinsics::bswap(self as $ActualT) as Self } + } + /// Reverses the bit pattern of the integer. /// /// # Examples @@ -2260,6 +2408,7 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn from_be(x: Self) -> Self { @@ -2274,6 +2423,16 @@ if cfg!(target_endian = \"big\") { } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[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 little endian to the target's endianness. @@ -2294,6 +2453,7 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn from_le(x: Self) -> Self { @@ -2308,6 +2468,16 @@ if cfg!(target_endian = \"little\") { } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn from_le(x: Self) -> Self { + if cfg!(target_endian = "little") { x } else { x.swap_bytes() } + } + } + doc_comment! { concat!("Converts `self` to big endian from the target's endianness. @@ -2328,6 +2498,7 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn to_be(self) -> Self { // or not to be? @@ -2342,6 +2513,16 @@ if cfg!(target_endian = \"big\") { } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn to_be(self) -> Self { // or not to be? + if cfg!(target_endian = "big") { self } else { self.swap_bytes() } + } + } + doc_comment! { concat!("Converts `self` to little endian from the target's endianness. @@ -2362,6 +2543,7 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(not(stage0))] #[rustc_const_unstable(feature = "const_int_ops")] #[inline] pub const fn to_le(self) -> Self { @@ -2376,6 +2558,16 @@ if cfg!(target_endian = \"little\") { } } + doc_comment! { + concat!("Dummy docs. See !stage0 documentation"), + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(stage0)] + #[inline] + pub fn to_le(self) -> Self { + if cfg!(target_endian = "little") { self } else { self.swap_bytes() } + } + } + doc_comment! { concat!("Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred. From 490c57b1563266a02c970405e731d73f4f2fc42b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Tue, 29 May 2018 11:39:26 +0200 Subject: [PATCH 03/13] Add test for const endianess conversion --- src/test/run-pass/const-endianess.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/run-pass/const-endianess.rs diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs new file mode 100644 index 0000000000000..9d815a7cf54c6 --- /dev/null +++ b/src/test/run-pass/const-endianess.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_int_ops)] + +const BE_U32: u32 = 55u32.to_be(); +const LE_U32: u32 = 55u32.to_le(); +const BE_U128: u128 = 999999u128.to_be(); +const LE_I128: i128 = -999999i128.to_le(); + +fn main() { + assert_eq!(BE_U32, 55u32.to_be()); + assert_eq!(LE_U32, 55u32.to_le()); + assert_eq!(BE_U128, 999999u128.to_be()); + assert_eq!(LE_I128, -999999i128.to_le()); +} From 4f4f7dfc00d69b8a94638ed1d9e666ada9911217 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 31 May 2018 21:36:15 +0200 Subject: [PATCH 04/13] Generate br for all two target SwitchInts Instead of only for booleans. This means that if let also becomes a br. Apart from making the IR slightly simpler, this is supported by FastISel. --- src/librustc_codegen_llvm/mir/block.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs index 1669059a760f4..14d20b6dbe297 100644 --- a/src/librustc_codegen_llvm/mir/block.rs +++ b/src/librustc_codegen_llvm/mir/block.rs @@ -191,14 +191,23 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { let discr = self.codegen_operand(&bx, discr); - if switch_ty == bx.tcx().types.bool { + if targets.len() == 2 { + // If there are two targets, emit br instead of switch let lltrue = llblock(self, targets[0]); let llfalse = llblock(self, targets[1]); - if let [0] = values[..] { - bx.cond_br(discr.immediate(), llfalse, lltrue); + if switch_ty == bx.tcx().types.bool { + // Don't generate trivial icmps when switching on bool + if let [0] = values[..] { + bx.cond_br(discr.immediate(), llfalse, lltrue); + } else { + assert_eq!(&values[..], &[1]); + bx.cond_br(discr.immediate(), lltrue, llfalse); + } } else { - assert_eq!(&values[..], &[1]); - bx.cond_br(discr.immediate(), lltrue, llfalse); + let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx); + let llval = C_uint_big(switch_llty, values[0]); + let cmp = bx.icmp(llvm::IntEQ, discr.immediate(), llval); + bx.cond_br(cmp, lltrue, llfalse); } } else { let (otherwise, targets) = targets.split_last().unwrap(); From 7a52f1c7cf659c62fbb89bd38d6e4fe4902622cc Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sun, 3 Jun 2018 00:13:27 +0200 Subject: [PATCH 05/13] Allow enabling incremental via config.toml --- config.toml.example | 3 +++ src/bootstrap/config.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/config.toml.example b/config.toml.example index 33ad9147ce059..5054a8f44b971 100644 --- a/config.toml.example +++ b/config.toml.example @@ -279,6 +279,9 @@ # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) #backtrace = true +# Whether to always use incremental compilation when building rustc +#incremental = false + # Build rustc with experimental parallelization #experimental-parallel-queries = false diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9840682d1379b..fbe9976b41397 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -303,6 +303,7 @@ struct Rust { dist_src: Option, quiet_tests: Option, test_miri: Option, + incremental: Option, save_toolstates: Option, codegen_backends: Option>, codegen_backends_dir: Option, @@ -529,6 +530,7 @@ impl Config { set(&mut config.rust_dist_src, rust.dist_src); set(&mut config.quiet_tests, rust.quiet_tests); set(&mut config.test_miri, rust.test_miri); + set(&mut config.incremental, rust.incremental); set(&mut config.wasm_syscall, rust.wasm_syscall); set(&mut config.lld_enabled, rust.lld); config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false); From 7df009922bc190977ad0ab4e64dd7a72804a442a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 3 Jun 2018 03:13:29 +0200 Subject: [PATCH 06/13] Pass literal through black_box --- src/test/run-pass/const-endianess.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs index 9d815a7cf54c6..b3be827545a2f 100644 --- a/src/test/run-pass/const-endianess.rs +++ b/src/test/run-pass/const-endianess.rs @@ -9,6 +9,10 @@ // except according to those terms. #![feature(const_int_ops)] +#![feature(test)] + +extern crate test; +use test::black_box as b; const BE_U32: u32 = 55u32.to_be(); const LE_U32: u32 = 55u32.to_le(); @@ -16,8 +20,8 @@ const BE_U128: u128 = 999999u128.to_be(); const LE_I128: i128 = -999999i128.to_le(); fn main() { - assert_eq!(BE_U32, 55u32.to_be()); - assert_eq!(LE_U32, 55u32.to_le()); - assert_eq!(BE_U128, 999999u128.to_be()); - assert_eq!(LE_I128, -999999i128.to_le()); + assert_eq!(BE_U32, b(55u32).to_be()); + assert_eq!(LE_U32, b(55u32).to_le()); + assert_eq!(BE_U128, b(999999u128).to_be()); + assert_eq!(LE_I128, b(-999999i128).to_le()); } From 3b02376c8f9ea0d41c164931f60c52bea68df225 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sun, 3 Jun 2018 08:44:56 +0200 Subject: [PATCH 07/13] command line args trump config.toml settings --- src/bootstrap/config.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index fbe9976b41397..47feb8a8ab66d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -530,7 +530,10 @@ impl Config { set(&mut config.rust_dist_src, rust.dist_src); set(&mut config.quiet_tests, rust.quiet_tests); set(&mut config.test_miri, rust.test_miri); - set(&mut config.incremental, rust.incremental); + // in the case "false" is set explicitly, do not overwrite the command line args + if let Some(true) = rust.incremental { + config.incremental = true; + } set(&mut config.wasm_syscall, rust.wasm_syscall); set(&mut config.lld_enabled, rust.lld); config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false); From 8b5f962762b500a1428e9d6937d964922a233fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 3 Jun 2018 11:18:24 +0200 Subject: [PATCH 08/13] Ignore i128 test on asmjs --- src/test/run-pass/const-endianess.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs index b3be827545a2f..fa34b49210a6a 100644 --- a/src/test/run-pass/const-endianess.rs +++ b/src/test/run-pass/const-endianess.rs @@ -16,12 +16,17 @@ use test::black_box as b; const BE_U32: u32 = 55u32.to_be(); const LE_U32: u32 = 55u32.to_le(); -const BE_U128: u128 = 999999u128.to_be(); -const LE_I128: i128 = -999999i128.to_le(); + fn main() { assert_eq!(BE_U32, b(55u32).to_be()); assert_eq!(LE_U32, b(55u32).to_le()); - assert_eq!(BE_U128, b(999999u128).to_be()); - assert_eq!(LE_I128, b(-999999i128).to_le()); + + #[cfg(not(target_arch = "asmjs"))] + { + const BE_U128: u128 = 999999u128.to_be(); + const LE_I128: i128 = -999999i128.to_le(); + assert_eq!(BE_U128, b(999999u128).to_be()); + assert_eq!(LE_I128, b(-999999i128).to_le()); + } } From adaf8e6abfac277a8e5e835bbcd704b2848ae2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 3 Jun 2018 17:33:49 +0300 Subject: [PATCH 09/13] Move TrustedLen and FusedIterator impl of Iter/IterMut into macro --- src/libcore/slice/mod.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ab986e4c86d88..f1ad5b169f031 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2513,6 +2513,12 @@ macro_rules! iterator { accum } } + + #[stable(feature = "fused", since = "1.26.0")] + impl<'a, T> FusedIterator for $name<'a, T> {} + + #[unstable(feature = "trusted_len", issue = "37572")] + unsafe impl<'a, T> TrustedLen for $name<'a, T> {} } } @@ -2639,12 +2645,6 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> { } } -#[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for Iter<'a, T> {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T> TrustedLen for Iter<'a, T> {} - #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } @@ -2767,13 +2767,6 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> { } } -#[stable(feature = "fused", since = "1.26.0")] -impl<'a, T> FusedIterator for IterMut<'a, T> {} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {} - - // Return the number of elements of `T` from `start` to `end`. // Return the arithmetic difference if `T` is zero size. #[inline(always)] From 325c676677081b5f680938a8618ca3db71a6de84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 3 Jun 2018 17:34:23 +0300 Subject: [PATCH 10/13] Remove mention of Slice/SliceMut traits from IterMut documentation These don't exist anymore. --- src/libcore/slice/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index f1ad5b169f031..29f86a88fc2d0 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2706,9 +2706,7 @@ impl<'a, T> IterMut<'a, T> { /// View the underlying data as a subslice of the original data. /// /// To avoid creating `&mut` references that alias, this is forced - /// to consume the iterator. Consider using the `Slice` and - /// `SliceMut` implementations for obtaining slices with more - /// restricted lifetimes that do not consume the iterator. + /// to consume the iterator. /// /// # Examples /// From 10cf7bb328345373b1fe59e4d323bef65d06765a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 3 Jun 2018 17:38:49 +0300 Subject: [PATCH 11/13] Implement TrustedLen for Windows and the 4 Chunks iterators --- src/libcore/slice/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 29f86a88fc2d0..1dec7c3020d02 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3362,6 +3362,9 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Windows<'a, T> {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, T> TrustedLen for Windows<'a, T> {} + #[stable(feature = "fused", since = "1.26.0")] impl<'a, T> FusedIterator for Windows<'a, T> {} @@ -3481,6 +3484,9 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for Chunks<'a, T> {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, T> TrustedLen for Chunks<'a, T> {} + #[stable(feature = "fused", since = "1.26.0")] impl<'a, T> FusedIterator for Chunks<'a, T> {} @@ -3597,6 +3603,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, T> TrustedLen for ChunksMut<'a, T> {} + #[stable(feature = "fused", since = "1.26.0")] impl<'a, T> FusedIterator for ChunksMut<'a, T> {} @@ -3707,6 +3716,9 @@ impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> { } } +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {} + #[unstable(feature = "exact_chunks", issue = "47115")] impl<'a, T> FusedIterator for ExactChunks<'a, T> {} @@ -3804,6 +3816,9 @@ impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> { } } +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {} + #[unstable(feature = "exact_chunks", issue = "47115")] impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {} From efa02b6d2fff602c464ad2d0cd912fc4e6789dff Mon Sep 17 00:00:00 2001 From: kennytm Date: Mon, 4 Jun 2018 01:10:19 +0800 Subject: [PATCH 12/13] Remove the unused `-Z trans-time-graph` flag. Rebase of #50783 has accidentally revived the flag (which should be renamed to `-Z codegen-time-graph` by #50615). --- src/librustc/session/config.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cc8e8c7c31c20..2c8f021c6a520 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1304,8 +1304,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "enable polonius-based borrow-checker"), codegen_time_graph: bool = (false, parse_bool, [UNTRACKED], "generate a graphical HTML report of time spent in codegen and LLVM"), - trans_time_graph: bool = (false, parse_bool, [UNTRACKED], - "generate a graphical HTML report of time spent in trans and LLVM"), thinlto: Option = (None, parse_opt_bool, [TRACKED], "enable ThinLTO when possible"), inline_in_all_cgus: Option = (None, parse_opt_bool, [TRACKED], From 19e0b7da1c0ccabf93bcdc94c78c49b9359484c3 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 1 Jun 2018 19:00:34 -0600 Subject: [PATCH 13/13] Remove is_import field --- src/librustc/hir/def.rs | 3 --- src/librustc/ich/impls_hir.rs | 3 +-- src/librustc_metadata/decoder.rs | 9 +++------ src/librustc_resolve/macros.rs | 1 - src/librustc_resolve/resolve_imports.rs | 1 - src/librustdoc/visit_lib.rs | 3 ++- 6 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index ae1cf6046fbd4..0adbdbe99333f 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -134,9 +134,6 @@ pub struct Export { /// The visibility of the export. /// We include non-`pub` exports for hygienic macros that get used from extern crates. pub vis: ty::Visibility, - /// True if from a `use` or and `extern crate`. - /// Used in rustdoc. - pub is_import: bool, } impl CtorKind { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 397638fc55d4b..a781fc7240ab3 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1115,8 +1115,7 @@ impl_stable_hash_for!(struct hir::def::Export { ident, def, vis, - span, - is_import + span }); impl<'a> HashStable> diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 69e873bb95d25..fd00cde375b90 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -665,7 +665,6 @@ impl<'a, 'tcx> CrateMetadata { def: def, vis: ty::Visibility::Public, span: DUMMY_SP, - is_import: false, }); } } @@ -705,7 +704,6 @@ impl<'a, 'tcx> CrateMetadata { ident: Ident::from_interned_str(self.item_name(child_index)), vis: self.get_visibility(child_index), span: self.entry(child_index).span.decode((self, sess)), - is_import: false, }); } } @@ -722,8 +720,7 @@ impl<'a, 'tcx> CrateMetadata { (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) { let ident = Ident::from_interned_str(name); let vis = self.get_visibility(child_index); - let is_import = false; - callback(def::Export { def, ident, vis, span, is_import }); + callback(def::Export { def, ident, vis, span }); // For non-re-export structs and variants add their constructors to children. // Re-export lists automatically contain constructors when necessary. match def { @@ -734,7 +731,7 @@ impl<'a, 'tcx> CrateMetadata { callback(def::Export { def: ctor_def, vis: self.get_visibility(ctor_def_id.index), - ident, span, is_import, + ident, span, }); } } @@ -744,7 +741,7 @@ impl<'a, 'tcx> CrateMetadata { let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::VariantCtor(def_id, ctor_kind); let vis = self.get_visibility(child_index); - callback(def::Export { def: ctor_def, ident, vis, span, is_import }); + callback(def::Export { def: ctor_def, ident, vis, span }); } _ => {} } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0cc59e3129c30..fe6909f759159 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -803,7 +803,6 @@ impl<'a> Resolver<'a> { def: def, vis: ty::Visibility::Public, span: item.span, - is_import: false, }); } else { self.unused_macros.insert(def_id); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 34f84597adfc5..c44f330128a23 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1008,7 +1008,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { def: def, span: binding.span, vis: binding.vis, - is_import: true, }); } } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 15a8b58d0f6b9..4c773fc1dd78b 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -68,7 +68,8 @@ impl<'a, 'tcx, 'rcx> LibEmbargoVisitor<'a, 'tcx, 'rcx> { } for item in self.cx.tcx.item_children(def_id).iter() { - if !item.is_import || item.vis == Visibility::Public { + if self.cx.tcx.def_key(item.def.def_id()).parent.map_or(false, |d| d == def_id.index) || + item.vis == Visibility::Public { self.visit_item(item.def); } }