Change derive macro for Eq to not impl Eq trait fn#153125
Change derive macro for Eq to not impl Eq trait fn#153125KiChjang wants to merge 6 commits intorust-lang:mainfrom
Conversation
|
Changes to the code generated for builtin derived traits. cc @nnethercote |
This comment has been minimized.
This comment has been minimized.
|
A test case that seems like might break with this: trait Trait<T> {}
#[derive(PartialEq, Eq)]
struct Thing<T: Trait<Self>>(T); |
|
A less exotic test case: #[derive(PartialEq, Eq)]
struct Thing(Option<Box<Self>>); |
|
Nick, I would reassign to you (feel free to reroll) since @cyrgani is a triage member and can't approve compiler changes r? nnethercote |
Gah, because we're now generating a const item instead of a trait impl block, we'd need to rewrite the A better solution now would be to emit the following: impl<...> Type<...> {
const fn assert_fields_are_eq() {
let _: ::core::cmp::AssertParamIsEq<Option<Box<Self>>>;
}
}This would side-step the issue of rewriting |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Looks like CI is passing now, r? @nnethercote |
|
Requested reviewer is already assigned to this pull request. Please choose another assignee. |
|
You should be able to delete the |
|
Could you also add a test that something like fn main() {
X::assert_fields_are_eq();
}
#[derive(PartialEq, Eq)]
struct X(u8);will not compile? |
There was a problem hiding this comment.
This is now completely different to the original idea of using a const. I'm no lang expert, but injecting X::assert_fields_are_eq doesn't seem acceptable to me.
Beyond that, I've only skimmed the PR so far. I think the 8 commits should be squashed down to 1 or 2. I'm also surprised at how much extra code is required in eq.rs to generate a slight variation on what is currently generated.
This probably would still compile, since what I essentially did was move the trait method to be under an inherent impl instead, which is probably why it isn't desirable. Given so, I'd probably need to revert to the original idea of using a const item block, however the const fn would still have to stay the same because I'd still need to somehow bring all lifetime/type parameters into scope, and if we don't use an impl, then a fn is the minimal vehicle to do so. |
That's right. Currently we have a hidden method in |
|
I've built the compiler with this PR's changes applied and the code I posted above still (correctly) does not compile.(probably due to some hygiene rules that make the function name unaccessible outside the |
|
Ah, it's likely due to visibility issues -- it's not accessible publicly, but if you call it within an impl block for the type, then it would compile. Example: fn main() {
X::foo();
}
#[derive(PartialEq, Eq)]
struct X(u8);
impl X {
pub fn foo() {
Self::assert_fields_are_eq();
}
}I have local changes that revert the emitted code to be using a const impl block with a const fn inside of it, however some UI test expectations need to be updated as a result of that change. Will push as soon as I get around to fix them. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Did you explore what I wrote briefly in #149978 (comment), to do something like:
#[derive(PartialEq, Eq)]
pub struct A<'a, T> {
field1: &'a [T],
field2: Option<Box<Self>>,
}
// Generates
const _: () = {
struct __AssertIsEq<'a, T: core::eq::Eq> {
field1: core::eq::AssertParamIsEq<&'a [T]>,
field2: core::eq::AssertParamIsEq<Option<Box<Self>>>,
}
impl<'a, T: core::eq::PartialEq> PartialEq for __AssertIsEq<'a, T> {
#[inline]
fn eq(&self, other: &Self) -> bool { unimplemented!() }
}
impl<'a, T: core::eq::Eq> Eq for __AssertIsEq<'a, T> {}
};Also, this is apparently perf-sensitive, please remember to do a perf-run before merging.
32d0739 to
c9cc7ea
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
c9cc7ea to
b5a6295
Compare
|
@bors try @rust-timer queue |
|
@KiChjang: 🔑 Insufficient privileges: not in try users |
|
Insufficient permissions to issue commands to rust-timer. |
This seems to emit quite a lot of boilerplate for the purpose of making sure that Would appreciate some help in putting this on the timer queue though as I don't have sufficient permissions. |
| impl ::core::cmp::Eq for PackedPoint { | ||
| #[inline] | ||
| impl ::core::cmp::Eq for PackedPoint { } | ||
| const { |
There was a problem hiding this comment.
This isn't even valid syntax, it should be const _: () = {.
There was a problem hiding this comment.
This is the code that gets generated when I tell the compiler to emit a ast::ItemKind::ConstBlock:
rust/compiler/rustc_ast/src/ast.rs
Lines 3955 to 3959 in 8d50bcc
This comment has been minimized.
This comment has been minimized.
c694584 to
602529d
Compare
602529d to
c70ca54
Compare
View all comments
Fixes #152504.
r? @cyrgani