Make slices [const] PartialEq

This commit is contained in:
Oli Scherer
2025-07-11 10:20:25 +00:00
parent 250648e871
commit 68b415a0c4
12 changed files with 54 additions and 34 deletions
+2 -1
View File
@@ -381,7 +381,8 @@ pub struct AssertParamIsEq<T: Eq + PointeeSized> {
///
/// assert_eq!(2.cmp(&1), Ordering::Greater);
/// ```
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
#[derive(Clone, Copy, Eq, PartialOrd, Ord, Debug, Hash)]
#[derive_const(PartialEq)]
#[stable(feature = "rust1", since = "1.0.0")]
// This is a lang item only so that `BinOp::Cmp` in MIR can return it.
// It has no special behavior, but does require that the three variants
+6 -2
View File
@@ -17,11 +17,15 @@
/// - Neither `Self` nor `Rhs` have provenance, so integer comparisons are correct.
/// - `<Self as PartialEq<Rhs>>::{eq,ne}` are equivalent to comparing the bytes.
#[rustc_specialization_trait]
pub(crate) unsafe trait BytewiseEq<Rhs = Self>: PartialEq<Rhs> + Sized {}
#[const_trait]
pub(crate) unsafe trait BytewiseEq<Rhs = Self>:
~const PartialEq<Rhs> + Sized
{
}
macro_rules! is_bytewise_comparable {
($($t:ty),+ $(,)?) => {$(
unsafe impl BytewiseEq for $t {}
unsafe impl const BytewiseEq for $t {}
)+};
}
+1
View File
@@ -2208,6 +2208,7 @@ pub const fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8 {
/// [valid]: crate::ptr#safety
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
pub const unsafe fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
/// See documentation of [`std::hint::black_box`] for details.
+2
View File
@@ -103,6 +103,7 @@
#![feature(cfg_select)]
#![feature(cfg_target_has_reliable_f16_f128)]
#![feature(const_carrying_mul_add)]
#![feature(const_cmp)]
#![feature(const_destruct)]
#![feature(const_eval_select)]
#![feature(core_intrinsics)]
@@ -146,6 +147,7 @@
#![feature(const_trait_impl)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(derive_const)]
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
#![feature(doc_notable_trait)]
+15 -7
View File
@@ -8,9 +8,10 @@
use crate::ops::ControlFlow;
#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U> PartialEq<[U]> for [T]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<T, U> const PartialEq<[U]> for [T]
where
T: PartialEq<U>,
T: ~const PartialEq<U>,
{
fn eq(&self, other: &[U]) -> bool {
SlicePartialEq::equal(self, other)
@@ -94,6 +95,8 @@ fn __chaining_ge(&self, other: &Self) -> ControlFlow<bool> {
#[doc(hidden)]
// intermediate trait for specialization of slice's PartialEq
#[const_trait]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
trait SlicePartialEq<B> {
fn equal(&self, other: &[B]) -> bool;
@@ -103,9 +106,10 @@ fn not_equal(&self, other: &[B]) -> bool {
}
// Generic slice equality
impl<A, B> SlicePartialEq<B> for [A]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A, B> const SlicePartialEq<B> for [A]
where
A: PartialEq<B>,
A: ~const PartialEq<B>,
{
default fn equal(&self, other: &[B]) -> bool {
if self.len() != other.len() {
@@ -115,11 +119,14 @@ impl<A, B> SlicePartialEq<B> for [A]
// Implemented as explicit indexing rather
// than zipped iterators for performance reasons.
// See PR https://github.com/rust-lang/rust/pull/116846
for idx in 0..self.len() {
// FIXME(const_hack): make this a `for idx in 0..self.len()` loop.
let mut idx = 0;
while idx < self.len() {
// bound checks are optimized away
if self[idx] != other[idx] {
return false;
}
idx += 1;
}
true
@@ -128,9 +135,10 @@ impl<A, B> SlicePartialEq<B> for [A]
// When each element can be compared byte-wise, we can compare all the bytes
// from the whole size in one call to the intrinsics.
impl<A, B> SlicePartialEq<B> for [A]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A, B> const SlicePartialEq<B> for [A]
where
A: BytewiseEq<B>,
A: ~const BytewiseEq<B>,
{
fn equal(&self, other: &[B]) -> bool {
if self.len() != other.len() {
+2 -1
View File
@@ -23,7 +23,8 @@ fn cmp(&self, other: &str) -> Ordering {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for str {
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl const PartialEq for str {
#[inline]
fn eq(&self, other: &str) -> bool {
self.as_bytes() == other.as_bytes()
+1 -1
View File
@@ -1,6 +1,6 @@
//@ check-fail
#![feature(core_intrinsics)]
#![feature(core_intrinsics, const_cmp)]
use std::intrinsics::compare_bytes;
use std::mem::MaybeUninit;
+1 -1
View File
@@ -1,6 +1,6 @@
//@ run-pass
#![feature(core_intrinsics)]
#![feature(core_intrinsics, const_cmp)]
use std::intrinsics::compare_bytes;
fn main() {
@@ -1,7 +1,7 @@
//@ compile-flags: -Znext-solver
//@ known-bug: #110395
// Broken until we have `const PartialEq` impl in stdlib
// Broken until `(): const PartialEq`
#![allow(incomplete_features)]
#![feature(const_trait_impl, const_cmp, const_destruct)]
@@ -1,12 +0,0 @@
error[E0015]: cannot match on `str` in constant functions
--> $DIR/match-non-const-eq.rs:7:9
|
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
| ^^^
|
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0015`.
@@ -1,11 +1,12 @@
//@ known-bug: #110395
//@ revisions: stock gated
#![cfg_attr(gated, feature(const_trait_impl))]
#![cfg_attr(gated, feature(const_trait_impl, const_cmp))]
//@[gated] check-pass
const fn foo(input: &'static str) {
match input {
"a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
//FIXME ~^ ERROR cannot match on `str` in constant functions
"a" => (),
//[stock]~^ ERROR cannot match on `str` in constant functions
//[stock]~| ERROR `PartialEq` is not yet stable as a const trait
_ => (),
}
}
@@ -1,12 +1,26 @@
error[E0015]: cannot match on `str` in constant functions
error[E0658]: cannot match on `str` in constant functions
--> $DIR/match-non-const-eq.rs:7:9
|
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
LL | "a" => (),
| ^^^
|
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
error: `PartialEq` is not yet stable as a const trait
--> $DIR/match-non-const-eq.rs:7:9
|
LL | "a" => (),
| ^^^
|
help: add `#![feature(const_cmp)]` to the crate attributes to enable
|
LL + #![feature(const_cmp)]
|
For more information about this error, try `rustc --explain E0015`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.