mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Make slices [const] PartialEq
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {}
|
||||
)+};
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
//@ check-fail
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_intrinsics, const_cmp)]
|
||||
use std::intrinsics::compare_bytes;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user