Skip to content

Make PartialEq a const_trait #142822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ use crate::ops::ControlFlow;
append_const_msg
)]
#[rustc_diagnostic_item = "PartialEq"]
#[const_trait]
#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
/// Tests for `self` and `other` values to be equal, and is used by `==`.
#[must_use]
Expand Down Expand Up @@ -1811,7 +1813,8 @@ mod impls {
macro_rules! partial_eq_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for $t {
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl const PartialEq for $t {
#[inline]
fn eq(&self, other: &Self) -> bool { *self == *other }
#[inline]
Expand Down Expand Up @@ -2018,9 +2021,10 @@ mod impls {
// & pointers

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &A
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A
where
A: PartialEq<B>,
A: ~const PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&B) -> bool {
Expand Down Expand Up @@ -2089,9 +2093,10 @@ mod impls {
// &mut pointers

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &mut A
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &mut A
where
A: PartialEq<B>,
A: ~const PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&mut B) -> bool {
Expand Down Expand Up @@ -2158,9 +2163,10 @@ mod impls {
impl<A: PointeeSized> Eq for &mut A where A: Eq {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &A
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &A
where
A: PartialEq<B>,
A: ~const PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&mut B) -> bool {
Expand All @@ -2173,9 +2179,10 @@ mod impls {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &mut A
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &mut A
where
A: PartialEq<B>,
A: ~const PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&B) -> bool {
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/consts/const_cmp_type_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use std::any::TypeId;
fn main() {
const {
assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
//~^ ERROR cannot call non-const operator in constants
//~^ ERROR the trait bound `TypeId: const PartialEq` is not satisfied
assert!(TypeId::of::<()>() != TypeId::of::<u8>());
//~^ ERROR cannot call non-const operator in constants
//~^ ERROR the trait bound `TypeId: const PartialEq` is not satisfied
let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
//~^ ERROR cannot call non-const operator in constants
// can't assert `_a` because it is not deterministic
// FIXME(const_trait_impl) make it pass
}
Expand Down
26 changes: 4 additions & 22 deletions tests/ui/consts/const_cmp_type_id.stderr
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
error[E0015]: cannot call non-const operator in constants
error[E0277]: the trait bound `TypeId: const PartialEq` is not satisfied
--> $DIR/const_cmp_type_id.rs:8:17
|
LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const operator in constants
error[E0277]: the trait bound `TypeId: const PartialEq` is not satisfied
--> $DIR/const_cmp_type_id.rs:10:17
|
LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const operator in constants
--> $DIR/const_cmp_type_id.rs:12:18
|
LL | let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0277`.
18 changes: 4 additions & 14 deletions tests/ui/consts/fn_trait_refs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ error[E0635]: unknown feature `const_fn_trait_ref_impls`
LL | #![feature(const_fn_trait_ref_impls)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0635]: unknown feature `const_cmp`
--> $DIR/fn_trait_refs.rs:7:12
|
LL | #![feature(const_cmp)]
| ^^^^^^^^^

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:8
|
Expand Down Expand Up @@ -155,21 +149,17 @@ note: `FnMut` can't be used with `~const` because it isn't annotated with `#[con
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0015]: cannot call non-const operator in constants
error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
--> $DIR/fn_trait_refs.rs:71:17
|
LL | assert!(test_one == (1, 1, 1));
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const operator in constants
error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied
--> $DIR/fn_trait_refs.rs:74:17
|
LL | assert!(test_two == (2, 2));
| ^^^^^^^^^^^^^^^^^^
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:16:5
Expand All @@ -195,7 +185,7 @@ LL | f()
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error: aborting due to 22 previous errors
error: aborting due to 21 previous errors

Some errors have detailed explanations: E0015, E0635.
Some errors have detailed explanations: E0015, E0277, E0635.
For more information about an error, try `rustc --explain E0015`.
8 changes: 2 additions & 6 deletions tests/ui/consts/issue-73976-monomorphic.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
error[E0015]: cannot call non-const operator in constant functions
error[E0277]: the trait bound `TypeId: ~const PartialEq` is not satisfied
--> $DIR/issue-73976-monomorphic.rs:21:5
|
LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= 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`.
For more information about this error, try `rustc --explain E0277`.
15 changes: 12 additions & 3 deletions tests/ui/consts/issue-90870.rs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is no longer testing the issue - can we change this to another one that still shows the errors? or just remove this test completely (or just have const_trait_impl removed in this test)

Copy link
Member

@fee1-dead fee1-dead Jun 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also means

let mut sugg = None;
if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) {
match (args[0].kind(), args[1].kind()) {
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
if self_ty == rhs_ty
&& self_ty.is_ref()
&& self_ty.peel_refs().is_primitive() =>
{
let mut num_refs = 0;
let mut tmp_ty = self_ty;
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
num_refs += 1;
tmp_ty = *inner_ty;
}
let deref = "*".repeat(num_refs);
if let Ok(call_str) = ccx.tcx.sess.source_map().span_to_snippet(span) {
if let Some(eq_idx) = call_str.find("==") {
if let Some(rhs_idx) =
call_str[(eq_idx + 2)..].find(|c: char| !c.is_whitespace())
{
let rhs_pos =
span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx);
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
sugg = Some(errors::ConsiderDereferencing {
deref,
span: span.shrink_to_lo(),
rhs_span,
});
}
}
}
}
_ => {}
}
should be deleted (or with a FIXME to delete once we stabilize stuff)

Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,31 @@
#![allow(dead_code)]

const fn f(a: &u8, b: &u8) -> bool {
//~^ HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
//~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
//~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
a == b
//~^ ERROR: cannot call non-const operator in constant functions [E0015]
//~^ ERROR: cannot call conditionally-const operator in constant functions
//~| ERROR: `PartialEq` is not yet stable as a const trait
//~| HELP: consider dereferencing here
//~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
}

const fn g(a: &&&&i64, b: &&&&i64) -> bool {
a == b
//~^ ERROR: cannot call non-const operator in constant functions [E0015]
//~^ ERROR: cannot call conditionally-const operator in constant functions
//~| ERROR: `PartialEq` is not yet stable as a const trait
//~| HELP: consider dereferencing here
//~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
}

const fn h(mut a: &[u8], mut b: &[u8]) -> bool {
while let ([l, at @ ..], [r, bt @ ..]) = (a, b) {
if l == r {
//~^ ERROR: cannot call non-const operator in constant functions [E0015]
//~^ ERROR: cannot call conditionally-const operator in constant functions
//~| ERROR: `PartialEq` is not yet stable as a const trait
//~| HELP: consider dereferencing here
//~| HELP: add `#![feature(const_trait_impl)]` to the crate attributes to enable
a = at;
b = bt;
} else {
Expand Down
58 changes: 50 additions & 8 deletions tests/ui/consts/issue-90870.stderr
Original file line number Diff line number Diff line change
@@ -1,39 +1,81 @@
error[E0015]: cannot call non-const operator in constant functions
--> $DIR/issue-90870.rs:6:5
error[E0658]: cannot call conditionally-const operator in constant functions
--> $DIR/issue-90870.rs:9:5
|
LL | a == b
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> 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
help: consider dereferencing here
|
LL | *a == *b
| + +

error[E0015]: cannot call non-const operator in constant functions
--> $DIR/issue-90870.rs:12:5
error: `PartialEq` is not yet stable as a const trait
--> $DIR/issue-90870.rs:9:5
|
LL | a == b
| ^^^^^^
|
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

error[E0658]: cannot call conditionally-const operator in constant functions
--> $DIR/issue-90870.rs:17:5
|
LL | a == b
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> 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
help: consider dereferencing here
|
LL | ****a == ****b
| ++++ ++++

error[E0015]: cannot call non-const operator in constant functions
--> $DIR/issue-90870.rs:19:12
error: `PartialEq` is not yet stable as a const trait
--> $DIR/issue-90870.rs:17:5
|
LL | a == b
| ^^^^^^
|
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

error[E0658]: cannot call conditionally-const operator in constant functions
--> $DIR/issue-90870.rs:26:12
|
LL | if l == r {
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> 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
help: consider dereferencing here
|
LL | if *l == *r {
| + +

error: aborting due to 3 previous errors
error: `PartialEq` is not yet stable as a const trait
--> $DIR/issue-90870.rs:26:12
|
LL | if l == r {
| ^^^^^^
|
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0658`.
3 changes: 1 addition & 2 deletions tests/ui/traits/const-traits/call-const-trait-method-pass.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ known-bug: #110395

#![feature(const_trait_impl, const_ops)]
//@ check-pass

struct Int(i32);

Expand Down
20 changes: 0 additions & 20 deletions tests/ui/traits/const-traits/call-const-trait-method-pass.stderr

This file was deleted.

3 changes: 1 addition & 2 deletions tests/ui/traits/const-traits/call-generic-in-impl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ known-bug: #110395
// FIXME(const_trait_impl) check-pass
//@ check-pass
#![feature(const_trait_impl)]

#[const_trait]
Expand Down
30 changes: 0 additions & 30 deletions tests/ui/traits/const-traits/call-generic-in-impl.stderr

This file was deleted.

3 changes: 1 addition & 2 deletions tests/ui/traits/const-traits/call-generic-method-chain.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! Basic test for calling methods on generic type parameters in `const fn`.
//@ known-bug: #110395
//@ compile-flags: -Znext-solver
// FIXME(const_trait_impl) check-pass
//@ check-pass

#![feature(const_trait_impl)]

Expand Down
Loading
Loading