From 23d033e17788d828aad233ff7c55652ac310d0b8 Mon Sep 17 00:00:00 2001 From: AlexApps99 Date: Fri, 22 Oct 2021 10:03:18 +1300 Subject: [PATCH 01/12] Added const versions of common numeric operations # Conflicts: # library/core/src/lib.rs --- library/core/src/internal_macros.rs | 68 +++++++++++++++ library/core/src/lib.rs | 1 + library/core/src/num/nonzero.rs | 21 +++-- library/core/src/num/wrapping.rs | 128 +++++++++++++++++----------- library/core/src/ops/arith.rs | 65 ++++++++------ library/core/src/ops/bit.rs | 55 +++++++----- 6 files changed, 232 insertions(+), 106 deletions(-) diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index be12f90464084..b5c1bf6897c18 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -5,6 +5,22 @@ macro_rules! forward_ref_unop { forward_ref_unop!(impl $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; + (impl const $imp:ident, $method:ident for $t:ty) => { + forward_ref_unop!(impl const $imp, $method for $t, + #[stable(feature = "rust1", since = "1.0.0")]); + }; + (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp for &$t { + type Output = <$t as $imp>::Output; + + #[inline] + fn $method(self) -> <$t as $imp>::Output { + $imp::$method(*self) + } + } + }; (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] impl $imp for &$t { @@ -25,6 +41,44 @@ macro_rules! forward_ref_binop { forward_ref_binop!(impl $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; + (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_binop!(impl const $imp, $method for $t, $u, + #[stable(feature = "rust1", since = "1.0.0")]); + }; + (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl<'a> const $imp<$u> for &'a $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, other) + } + } + + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for $t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { + $imp::$method(self, *other) + } + } + + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for &$t { + type Output = <$t as $imp<$u>>::Output; + + #[inline] + fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { + $imp::$method(*self, *other) + } + } + }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl<'a> $imp<$u> for &'a $t { @@ -65,6 +119,20 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; + (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_op_assign!(impl const $imp, $method for $t, $u, + #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); + }; + (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { + #[$attr] + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const $imp<&$u> for $t { + #[inline] + fn $method(&mut self, other: &$u) { + $imp::$method(self, *other); + } + } + }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl $imp<&$u> for $t { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 58a170401e7c1..87857873dfd88 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -116,6 +116,7 @@ #![feature(const_maybe_uninit_as_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_num_from_num)] +#![feature(const_ops)] #![feature(const_option)] #![feature(const_pin)] #![feature(const_replace)] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 9b1a4de5d8037..7708094e1fcea 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -92,7 +92,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { @@ -103,7 +104,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr<$Int> for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr<$Int> for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: $Int) -> Self::Output { @@ -115,7 +117,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOr<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr<$Ty> for $Int { type Output = $Ty; #[inline] fn bitor(self, rhs: $Ty) -> Self::Output { @@ -127,7 +130,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for $Ty { #[inline] fn bitor_assign(&mut self, rhs: Self) { *self = *self | rhs; @@ -135,7 +139,8 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - impl BitOrAssign<$Int> for $Ty { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign<$Int> for $Ty { #[inline] fn bitor_assign(&mut self, rhs: $Int) { *self = *self | rhs; @@ -257,7 +262,8 @@ macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Div<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -270,7 +276,8 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - impl Rem<$Ty> for $Int { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index f387bd5b41cc4..a0e42c51e4517 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -87,7 +87,8 @@ impl fmt::UpperHex for Wrapping { macro_rules! sh_impl_signed { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -99,20 +100,22 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -124,24 +127,26 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } }; } macro_rules! sh_impl_unsigned { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -149,20 +154,22 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -170,17 +177,18 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } }; } @@ -209,7 +217,8 @@ sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } macro_rules! wrapping_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Add for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Add for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -217,20 +226,22 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_add(other.0)) } } - forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Add, add for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl AddAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const AddAssign for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } - forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "rust1", since = "1.0.0")] - impl Sub for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Sub for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -238,20 +249,22 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_sub(other.0)) } } - forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Sub, sub for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl SubAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const SubAssign for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } - forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "rust1", since = "1.0.0")] - impl Mul for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Mul for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -263,16 +276,18 @@ macro_rules! wrapping_impl { #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl MulAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const MulAssign for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } - forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_div", since = "1.3.0")] - impl Div for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -280,20 +295,22 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_div(other.0)) } } - forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Div, div for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl DivAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const DivAssign for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } } - forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_impls", since = "1.7.0")] - impl Rem for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -301,20 +318,22 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_rem(other.0)) } } - forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const Rem, rem for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl RemAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const RemAssign for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } } - forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "rust1", since = "1.0.0")] - impl Not for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Not for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -322,11 +341,12 @@ macro_rules! wrapping_impl { Wrapping(!self.0) } } - forward_ref_unop! { impl Not, not for Wrapping<$t>, + forward_ref_unop! { impl const Not, not for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "rust1", since = "1.0.0")] - impl BitXor for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXor for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -334,20 +354,22 @@ macro_rules! wrapping_impl { Wrapping(self.0 ^ other.0) } } - forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitXorAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXorAssign for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } } - forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "rust1", since = "1.0.0")] - impl BitOr for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -355,20 +377,22 @@ macro_rules! wrapping_impl { Wrapping(self.0 | other.0) } } - forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitOr, bitor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitOrAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } - forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "rust1", since = "1.0.0")] - impl BitAnd for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -376,27 +400,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } - forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl const BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitAndAssign for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAndAssign for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } - forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_neg", since = "1.10.0")] - impl Neg for Wrapping<$t> { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Neg for Wrapping<$t> { type Output = Self; #[inline] fn neg(self) -> Self { Wrapping(0) - self } } - forward_ref_unop! { impl Neg, neg for Wrapping<$t>, + forward_ref_unop! { impl const Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } )*) diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index a0577b287ce24..e954742938910 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -92,7 +92,8 @@ pub trait Add { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Add for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Add for $t { type Output = $t; #[inline] @@ -100,7 +101,7 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } - forward_ref_binop! { impl Add, add for $t, $t } + forward_ref_binop! { impl const Add, add for $t, $t } )*) } @@ -198,7 +199,8 @@ pub trait Sub { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Sub for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Sub for $t { type Output = $t; #[inline] @@ -206,7 +208,7 @@ macro_rules! sub_impl { fn sub(self, other: $t) -> $t { self - other } } - forward_ref_binop! { impl Sub, sub for $t, $t } + forward_ref_binop! { impl const Sub, sub for $t, $t } )*) } @@ -326,7 +328,8 @@ pub trait Mul { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Mul for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Mul for $t { type Output = $t; #[inline] @@ -334,7 +337,7 @@ macro_rules! mul_impl { fn mul(self, other: $t) -> $t { self * other } } - forward_ref_binop! { impl Mul, mul for $t, $t } + forward_ref_binop! { impl const Mul, mul for $t, $t } )*) } @@ -464,14 +467,15 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - impl Div for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl Div, div for $t, $t } + forward_ref_binop! { impl const Div, div for $t, $t } )*)*) } @@ -483,14 +487,15 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Div for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl Div, div for $t, $t } + forward_ref_binop! { impl const Div, div for $t, $t } )*) } @@ -564,14 +569,15 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - impl Rem for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl Rem, rem for $t, $t } + forward_ref_binop! { impl const Rem, rem for $t, $t } )*)*) } @@ -598,14 +604,15 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - impl Rem for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl Rem, rem for $t, $t } + forward_ref_binop! { impl const Rem, rem for $t, $t } )*) } @@ -671,7 +678,8 @@ pub trait Neg { macro_rules! neg_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Neg for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Neg for $t { type Output = $t; #[inline] @@ -679,7 +687,7 @@ macro_rules! neg_impl { fn neg(self) -> $t { -self } } - forward_ref_unop! { impl Neg, neg for $t } + forward_ref_unop! { impl const Neg, neg for $t } )*) } @@ -739,13 +747,14 @@ pub trait AddAssign { macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl AddAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn add_assign(&mut self, other: $t) { *self += other } } - forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } + forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t } )+) } @@ -805,13 +814,14 @@ pub trait SubAssign { macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl SubAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn sub_assign(&mut self, other: $t) { *self -= other } } - forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } + forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t } )+) } @@ -862,13 +872,14 @@ pub trait MulAssign { macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl MulAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn mul_assign(&mut self, other: $t) { *self *= other } } - forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } + forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t } )+) } @@ -919,12 +930,13 @@ pub trait DivAssign { macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl DivAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const DivAssign for $t { #[inline] fn div_assign(&mut self, other: $t) { *self /= other } } - forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } + forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t } )+) } @@ -979,12 +991,13 @@ pub trait RemAssign { macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl RemAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const RemAssign for $t { #[inline] fn rem_assign(&mut self, other: $t) { *self %= other } } - forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } + forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t } )+) } diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 92f45ac9e7ea9..255f6cb7933a2 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -54,14 +54,15 @@ pub trait Not { macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl Not for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } - forward_ref_unop! { impl Not, not for $t } + forward_ref_unop! { impl const Not, not for $t } )*) } @@ -154,14 +155,15 @@ pub trait BitAnd { macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitAnd for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAnd for $t { type Output = $t; #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } - forward_ref_binop! { impl BitAnd, bitand for $t, $t } + forward_ref_binop! { impl const BitAnd, bitand for $t, $t } )*) } @@ -254,14 +256,15 @@ pub trait BitOr { macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitOr for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOr for $t { type Output = $t; #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } - forward_ref_binop! { impl BitOr, bitor for $t, $t } + forward_ref_binop! { impl const BitOr, bitor for $t, $t } )*) } @@ -354,14 +357,15 @@ pub trait BitXor { macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - impl BitXor for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXor for $t { type Output = $t; #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } - forward_ref_binop! { impl BitXor, bitxor for $t, $t } + forward_ref_binop! { impl const BitXor, bitxor for $t, $t } )*) } @@ -451,7 +455,8 @@ pub trait Shl { macro_rules! shl_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shl<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shl<$f> for $t { type Output = $t; #[inline] @@ -461,7 +466,7 @@ macro_rules! shl_impl { } } - forward_ref_binop! { impl Shl, shl for $t, $f } + forward_ref_binop! { impl const Shl, shl for $t, $f } }; } @@ -569,7 +574,8 @@ pub trait Shr { macro_rules! shr_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Shr<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const Shr<$f> for $t { type Output = $t; #[inline] @@ -579,7 +585,7 @@ macro_rules! shr_impl { } } - forward_ref_binop! { impl Shr, shr for $t, $f } + forward_ref_binop! { impl const Shr, shr for $t, $f } }; } @@ -704,12 +710,13 @@ pub trait BitAndAssign { macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitAndAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitAndAssign for $t { #[inline] fn bitand_assign(&mut self, other: $t) { *self &= other } } - forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t } + forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } )+) } @@ -775,12 +782,13 @@ pub trait BitOrAssign { macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitOrAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitOrAssign for $t { #[inline] fn bitor_assign(&mut self, other: $t) { *self |= other } } - forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t } + forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } )+) } @@ -846,12 +854,13 @@ pub trait BitXorAssign { macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl BitXorAssign for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const BitXorAssign for $t { #[inline] fn bitxor_assign(&mut self, other: $t) { *self ^= other } } - forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t } + forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } )+) } @@ -907,7 +916,8 @@ pub trait ShlAssign { macro_rules! shl_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShlAssign<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shl_assign(&mut self, other: $f) { @@ -915,7 +925,7 @@ macro_rules! shl_assign_impl { } } - forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f } + forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } }; } @@ -989,7 +999,8 @@ pub trait ShrAssign { macro_rules! shr_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - impl ShrAssign<$f> for $t { + #[rustc_const_unstable(feature = "const_ops", issue = "90080")] + impl const ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shr_assign(&mut self, other: $f) { @@ -997,7 +1008,7 @@ macro_rules! shr_assign_impl { } } - forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f } + forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } }; } From 361c978fbd41535f3c7fd0b2f956d4e1ee4aeefd Mon Sep 17 00:00:00 2001 From: AlexApps99 Date: Thu, 21 Oct 2021 12:26:26 +1300 Subject: [PATCH 02/12] Added docs to internal_macro const --- library/core/src/internal_macros.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index b5c1bf6897c18..9c6acfb1e8c94 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -9,6 +9,7 @@ macro_rules! forward_ref_unop { forward_ref_unop!(impl const $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] #[rustc_const_unstable(feature = "const_ops", issue = "90080")] @@ -45,6 +46,7 @@ macro_rules! forward_ref_binop { forward_ref_binop!(impl const $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] #[rustc_const_unstable(feature = "const_ops", issue = "90080")] @@ -123,6 +125,7 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl const $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; + // Equivalent to the non-const version, with the addition of `rustc_const_unstable` (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] #[rustc_const_unstable(feature = "const_ops", issue = "90080")] From 29a4e4a009a32094e85bb9867432d45a2e0edacd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 28 Oct 2021 11:51:00 +0200 Subject: [PATCH 03/12] Fix incorrect doc link --- library/core/src/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 607a0179ff4b9..7939ea3bb7fb2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -1663,7 +1663,7 @@ impl str { /// If the pattern allows a reverse search but its results might differ /// from a forward search, the [`rmatch_indices`] method can be used. /// - /// [`rmatch_indices`]: str::match_indices + /// [`rmatch_indices`]: str::rmatch_indices /// /// # Examples /// From 991a296ce7617443c021c164644e2791890849bc Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Oct 2021 17:15:25 +0300 Subject: [PATCH 04/12] Make `core::slice::from_raw_parts[_mut]` const --- library/core/src/lib.rs | 1 + library/core/src/slice/raw.rs | 55 ++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 36496193d0370..da537262f6bd5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -105,6 +105,7 @@ #![feature(const_caller_location)] #![feature(const_cell_into_inner)] #![feature(const_discriminant)] +#![cfg_attr(not(bootstrap), feature(const_eval_select))] #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_fmt_arguments_new)] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index ad38aaf9f8300..6653c998fa2ba 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -1,8 +1,6 @@ //! Free functions to create `&[T]` and `&mut [T]`. use crate::array; -use crate::intrinsics::is_aligned_and_not_null; -use crate::mem; use crate::ptr; /// Forms a slice from a pointer and a length. @@ -85,12 +83,10 @@ use crate::ptr; /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { - debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); - debug_assert!( - mem::size_of::().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering at least half the address space" - ); +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { + debug_check_data_len(data, len); + // SAFETY: the caller must uphold the safety contract for `from_raw_parts`. unsafe { &*ptr::slice_from_raw_parts(data, len) } } @@ -126,16 +122,47 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] -pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { - debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); - debug_assert!( - mem::size_of::().saturating_mul(len) <= isize::MAX as usize, - "attempt to create slice covering at least half the address space" - ); +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { + debug_check_data_len(data as _, len); + // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) } } +// In debug builds checks that `data` pointer is aligned and non-null and that slice with given `len` would cover less than half the address space +#[cfg(all(not(bootstrap), debug_assertions))] +#[unstable(feature = "const_slice_from_raw_parts", issue = "none")] +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +const fn debug_check_data_len(data: *const T, len: usize) { + fn rt_check(data: *const T) { + use crate::intrinsics::is_aligned_and_not_null; + + assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); + } + + const fn ctfe_check(_data: *const T) { + // It's impossible to check alignment in const fn. + // + // CTFE engine checks that the pointer is aligned and not null. + } + + // SAFETY: + // - `calling from_raw_parts[_mut]` with arguments that fail to fulfil checks made here is UB, so unless UB is already triggered this is noop + // - CTFE makes the same checks as `rt_check`, so behavior change is not observable due to compilation error + unsafe { + crate::intrinsics::const_eval_select((data,), ctfe_check, rt_check); + } + + assert!( + crate::mem::size_of::().saturating_mul(len) <= isize::MAX as usize, + "attempt to create slice covering at least half the address space" + ); +} + +#[cfg(not(all(not(bootstrap), debug_assertions)))] +const fn debug_check_data_len(_data: *const T, _len: usize) {} + /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")] From 04cb19692c8bf15fb1cc02872fdd209228db6329 Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 29 Oct 2021 12:32:06 +0200 Subject: [PATCH 05/12] don't mutably borrow inner infcx in all of ConstInferUnifier::consts --- compiler/rustc_infer/src/infer/combine.rs | 29 ++++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 3f54247ecef21..09bfb3290f4ca 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -866,6 +866,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } + #[tracing::instrument(level = "debug", skip(self))] fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { debug_assert_eq!(t, _t); debug!("ConstInferUnifier: t={:?}", t); @@ -941,6 +942,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } + #[tracing::instrument(level = "debug", skip(self))] fn consts( &mut self, c: &'tcx ty::Const<'tcx>, @@ -951,29 +953,38 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let variable_table = &mut inner.const_unification_table(); - // Check if the current unification would end up // unifying `target_vid` with a const which contains // an inference variable which is unioned with `target_vid`. // // Not doing so can easily result in stack overflows. - if variable_table.unioned(self.target_vid, vid) { + if self + .infcx + .inner + .borrow_mut() + .const_unification_table() + .unioned(self.target_vid, vid) + { return Err(TypeError::CyclicConst(c)); } - let var_value = variable_table.probe_value(vid); + let var_value = + self.infcx.inner.borrow_mut().const_unification_table().probe_value(vid); match var_value.val { ConstVariableValue::Known { value: u } => self.consts(u, u), ConstVariableValue::Unknown { universe } => { if self.for_universe.can_name(universe) { Ok(c) } else { - let new_var_id = variable_table.new_key(ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { universe: self.for_universe }, - }); + let new_var_id = + self.infcx.inner.borrow_mut().const_unification_table().new_key( + ConstVarValue { + origin: var_value.origin, + val: ConstVariableValue::Unknown { + universe: self.for_universe, + }, + }, + ); Ok(self.tcx().mk_const_var(new_var_id, c.ty)) } } From a39c50b64caca297b3e98ebf7cdb68c96ca0f3c1 Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 29 Oct 2021 12:38:28 +0200 Subject: [PATCH 06/12] add test --- .../ui/const-generics/issues/issue-89304.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-89304.rs diff --git a/src/test/ui/const-generics/issues/issue-89304.rs b/src/test/ui/const-generics/issues/issue-89304.rs new file mode 100644 index 0000000000000..d544d637cc490 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-89304.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct GenericStruct { val: i64 } + +impl From> for GenericStruct<{T + 1}> { + fn from(other: GenericStruct) -> Self { + Self { val: other.val } + } +} + +impl From> for GenericStruct { + fn from(other: GenericStruct<{T + 1}>) -> Self { + Self { val: other.val } + } +} + +fn main() {} From 87fbf3c5aaff62cb70cf95ccfd756f4f147e8fea Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 29 Oct 2021 13:14:44 +0200 Subject: [PATCH 07/12] ignore type flags insertion in default_anon_const_substs if error occurred --- compiler/rustc_typeck/src/collect/type_of.rs | 3 ++- src/test/ui/const-generics/issues/issue-88997.rs | 14 ++++++++++++++ .../ui/const-generics/issues/issue-88997.stderr | 15 +++++++++++++++ src/test/ui/const-generics/issues/issue-90364.rs | 9 +++++++++ .../ui/const-generics/issues/issue-90364.stderr | 9 +++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/const-generics/issues/issue-88997.rs create mode 100644 src/test/ui/const-generics/issues/issue-88997.stderr create mode 100644 src/test/ui/const-generics/issues/issue-90364.rs create mode 100644 src/test/ui/const-generics/issues/issue-90364.stderr diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index cee3679d0a052..96211be8cdcf7 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -292,7 +292,8 @@ pub(super) fn default_anon_const_substs(tcx: TyCtxt<'_>, def_id: DefId) -> Subst // Getting this wrong can lead to ICE and unsoundness, so we assert it here. for arg in substs.iter() { let allowed_flags = ty::TypeFlags::MAY_NEED_DEFAULT_CONST_SUBSTS - | ty::TypeFlags::STILL_FURTHER_SPECIALIZABLE; + | ty::TypeFlags::STILL_FURTHER_SPECIALIZABLE + | ty::TypeFlags::HAS_ERROR; assert!(!arg.has_type_flags(!allowed_flags)); } substs diff --git a/src/test/ui/const-generics/issues/issue-88997.rs b/src/test/ui/const-generics/issues/issue-88997.rs new file mode 100644 index 0000000000000..7666a514101da --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-88997.rs @@ -0,0 +1,14 @@ +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +struct ConstAssert; +trait True {} +impl True for ConstAssert {} + +struct Range(T) +//~^ ERROR the type of const parameters must not depend on other generic parameters +//~| ERROR the type of const parameters must not depend on other generic parameters +where + ConstAssert<{ MIN <= MAX }>: True; + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-88997.stderr b/src/test/ui/const-generics/issues/issue-88997.stderr new file mode 100644 index 0000000000000..505ba0da23214 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-88997.stderr @@ -0,0 +1,15 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-88997.rs:8:40 + | +LL | struct Range(T) + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-88997.rs:8:54 + | +LL | struct Range(T) + | ^ the type must not depend on the parameter `T` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/src/test/ui/const-generics/issues/issue-90364.rs b/src/test/ui/const-generics/issues/issue-90364.rs new file mode 100644 index 0000000000000..b11b07b5023b2 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-90364.rs @@ -0,0 +1,9 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +pub struct Foo(T) +//~^ ERROR the type of const parameters must not depend on other generic parameters +where + [(); 1]:; + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-90364.stderr b/src/test/ui/const-generics/issues/issue-90364.stderr new file mode 100644 index 0000000000000..e85bd136ef6dc --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-90364.stderr @@ -0,0 +1,9 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/issue-90364.rs:4:28 + | +LL | pub struct Foo(T) + | ^ the type must not depend on the parameter `T` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0770`. From 60bf2f192678337a7e8dcb5cebf6c17762707466 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 29 Oct 2021 11:15:45 -0400 Subject: [PATCH 08/12] Add a few query descriptions --- compiler/rustc_middle/src/query/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 6d384f5f3d645..06041bbb02d35 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -687,12 +687,13 @@ rustc_queries! { desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) } } - /// The signature of functions. + /// Computes the signature of the function. query fn_sig(key: DefId) -> ty::PolyFnSig<'tcx> { desc { |tcx| "computing function signature of `{}`", tcx.def_path_str(key) } separate_provide_extern } + /// Performs lint checking for the module. query lint_mod(key: LocalDefId) -> () { desc { |tcx| "linting {}", describe_as_module(key, tcx) } } @@ -702,6 +703,7 @@ rustc_queries! { desc { |tcx| "checking attributes in {}", describe_as_module(key, tcx) } } + /// Checks for uses of unstable APIs in the module. query check_mod_unstable_api_usage(key: LocalDefId) -> () { desc { |tcx| "checking for unstable API usage in {}", describe_as_module(key, tcx) } } @@ -928,6 +930,7 @@ rustc_queries! { desc { |tcx| "computing drop scopes for `{}`", tcx.def_path_str(def_id) } } + /// Generates a MIR body for the shim. query mir_shims(key: ty::InstanceDef<'tcx>) -> mir::Body<'tcx> { storage(ArenaCacheSelector<'tcx>) desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } @@ -946,11 +949,13 @@ rustc_queries! { separate_provide_extern } + /// Gets the span for the definition. query def_span(def_id: DefId) -> Span { desc { |tcx| "looking up span for `{}`", tcx.def_path_str(def_id) } separate_provide_extern } + /// Gets the span for the identifier of the definition. query def_ident_span(def_id: DefId) -> Option { desc { |tcx| "looking up span for `{}`'s identifier", tcx.def_path_str(def_id) } separate_provide_extern @@ -1466,6 +1471,8 @@ rustc_queries! { desc { "fetching what a dependency looks like" } separate_provide_extern } + + /// Gets the name of the crate. query crate_name(_: CrateNum) -> Symbol { eval_always desc { "fetching what a crate is named" } From 0c708311715befda3fcb7592f2324d96d9afeb74 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Oct 2021 14:44:47 +0200 Subject: [PATCH 09/12] Unify titles in rustdoc book doc attributes chapter --- compiler/rustc_passes/src/check_attr.rs | 2 +- src/doc/rustdoc/src/the-doc-attribute.md | 8 ++++++-- src/test/rustdoc-ui/invalid-doc-attr.stderr | 4 ++-- src/test/ui/attributes/invalid-doc-attr.stderr | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 92d9e89c3a383..658a4d3eac73d 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -768,7 +768,7 @@ impl CheckAttrVisitor<'tcx> { "not a `use` item", ); } - err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information") + err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information") .emit(); }, ); diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index 5ee06c5f91711..a75b6d3893128 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -153,7 +153,9 @@ example, if you want your doctests to fail if they produce any warnings, you cou These forms of the `#[doc]` attribute are used on individual items, to control how they are documented. -### `#[doc(no_inline)]`/`#[doc(inline)]` +### `inline` and `no_inline` + + These attributes are used on `use` statements, and control where the documentation shows up. For example, consider this Rust code: @@ -219,7 +221,9 @@ Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere. One special case: In Rust 2018 and later, if you `pub use` one of your dependencies, `rustdoc` will not eagerly inline it as a module unless you add `#[doc(inline)]`. -### `#[doc(hidden)]` +### `hidden` + + Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless the `strip-hidden` pass is removed. diff --git a/src/test/rustdoc-ui/invalid-doc-attr.stderr b/src/test/rustdoc-ui/invalid-doc-attr.stderr index 595ece2ea7247..55006b2087eb0 100644 --- a/src/test/rustdoc-ui/invalid-doc-attr.stderr +++ b/src/test/rustdoc-ui/invalid-doc-attr.stderr @@ -29,7 +29,7 @@ LL | pub fn foo() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: this attribute can only be applied at the crate level --> $DIR/invalid-doc-attr.rs:15:12 @@ -72,7 +72,7 @@ LL | pub fn baz() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: aborting due to 6 previous errors diff --git a/src/test/ui/attributes/invalid-doc-attr.stderr b/src/test/ui/attributes/invalid-doc-attr.stderr index 595ece2ea7247..55006b2087eb0 100644 --- a/src/test/ui/attributes/invalid-doc-attr.stderr +++ b/src/test/ui/attributes/invalid-doc-attr.stderr @@ -29,7 +29,7 @@ LL | pub fn foo() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: this attribute can only be applied at the crate level --> $DIR/invalid-doc-attr.rs:15:12 @@ -72,7 +72,7 @@ LL | pub fn baz() {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 - = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information + = note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline for more information error: aborting due to 6 previous errors From 878ac10fe13761664da2d205c64e2a398f469601 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 29 Oct 2021 22:45:10 +0300 Subject: [PATCH 10/12] Use proper issue number for `feature(const_slice_from_raw_parts)` --- library/core/src/slice/raw.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 6653c998fa2ba..edae555206fbe 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -83,7 +83,7 @@ use crate::ptr; /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_check_data_len(data, len); @@ -122,7 +122,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_check_data_len(data as _, len); @@ -132,8 +132,8 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m // In debug builds checks that `data` pointer is aligned and non-null and that slice with given `len` would cover less than half the address space #[cfg(all(not(bootstrap), debug_assertions))] -#[unstable(feature = "const_slice_from_raw_parts", issue = "none")] -#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "none")] +#[unstable(feature = "const_slice_from_raw_parts", issue = "67456")] +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] const fn debug_check_data_len(data: *const T, len: usize) { fn rt_check(data: *const T) { use crate::intrinsics::is_aligned_and_not_null; From afaa54a99d75bc6287d835b1ee33e1b15bda462e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 29 Oct 2021 23:45:09 +0300 Subject: [PATCH 11/12] Apply changes proposed in the review --- library/core/src/slice/raw.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index edae555206fbe..81bb16d54015e 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -141,17 +141,18 @@ const fn debug_check_data_len(data: *const T, len: usize) { assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); } - const fn ctfe_check(_data: *const T) { - // It's impossible to check alignment in const fn. - // - // CTFE engine checks that the pointer is aligned and not null. - } + const fn noop(_: *const T) {} // SAFETY: - // - `calling from_raw_parts[_mut]` with arguments that fail to fulfil checks made here is UB, so unless UB is already triggered this is noop - // - CTFE makes the same checks as `rt_check`, so behavior change is not observable due to compilation error + // + // `rt_check` is just a debug assert to hint users that they are causing UB, + // it is not required for safety (the safety must be guatanteed by + // the `from_raw_parts[_mut]` caller). + // + // Since the checks are not required, we ignore them in CTFE as they can't + // be done there (alignment does not make much sense there). unsafe { - crate::intrinsics::const_eval_select((data,), ctfe_check, rt_check); + crate::intrinsics::const_eval_select((data,), noop, rt_check); } assert!( From b6851ba3c9eccfb1def7fdb5e4c64edcad55e612 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 30 Oct 2021 02:07:37 +0000 Subject: [PATCH 12/12] Remove unnecessary `macro_use`s in rustdoc --- src/librustdoc/html/render/context.rs | 4 ++-- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/render/write_shared.rs | 1 + src/librustdoc/lib.rs | 7 ++----- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 0e29cc85f9e75..1ce6a5c00be74 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -22,8 +22,7 @@ use super::{ BASIC_KEYWORDS, }; -use crate::clean; -use crate::clean::ExternalCrate; +use crate::clean::{self, ExternalCrate}; use crate::config::RenderOptions; use crate::docfs::{DocFS, PathError}; use crate::error::Error; @@ -35,6 +34,7 @@ use crate::html::format::Buffer; use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap}; use crate::html::{layout, sources}; use crate::scrape_examples::AllCallLocations; +use crate::try_err; /// Major driving force in all rustdoc rendering. This contains information /// about where in the tree-like hierarchy rendering is occurring and controls diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 07dea624d7c52..0354b87e7b992 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -77,6 +77,7 @@ use crate::html::highlight; use crate::html::markdown::{HeadingOffset, Markdown, MarkdownHtml, MarkdownSummaryLine}; use crate::html::sources; use crate::scrape_examples::CallData; +use crate::try_none; /// A pair of name and its optional document. crate type NameDoc = (String, Option); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 34f1b4cd68408..27277015cd13f 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -17,6 +17,7 @@ use crate::config::{EmitType, RenderOptions}; use crate::docfs::PathError; use crate::error::Error; use crate::html::{layout, static_files}; +use crate::{try_err, try_none}; static FILES_UNVERSIONED: Lazy> = Lazy::new(|| { map! { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 93dffc27659c2..b50fbf58bae29 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -103,17 +103,14 @@ macro_rules! map { }} } -#[macro_use] -mod externalfiles; - mod clean; mod config; mod core; mod docfs; +mod doctest; mod doctree; -#[macro_use] mod error; -mod doctest; +mod externalfiles; mod fold; mod formats; // used by the error-index generator, so it needs to be public