about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src/deriving/cmp
AgeCommit message (Collapse)AuthorLines
2025-08-09remove `P`Deadbeef-5/+4
2025-07-17Make `derive_const` usable within libcore againOli Scherer-0/+5
Also make it *only* usable on nightly
2025-06-03Rollup merge of #141724 - Sol-Ell:issue-141141-fix, r=nnethercoteMatthias Krüger-57/+158
fix(#141141): When expanding `PartialEq`, check equality of scalar types first. Fixes rust-lang/rust#141141. Now, `cs_eq` function of `partial_eq.rs` compares [scalar types](https://doc.rust-lang.org/rust-by-example/primitives.html#scalar-types) first. - Add `is_scalar` field to `FieldInfo`. - Add `is_scalar` method to `TyKind`. - Pass `FieldInfo` via `CsFold::Combine` and refactor code relying on it. - Implement `TryFrom<&str>` and `TryFrom<Symbol>` for FloatTy. - Implement `TryFrom<&str>` and `TryFrom<Symbol>` for IntTy. - Implement `TryFrom<&str>` and `TryFrom<Symbol>` for UintTy.
2025-06-02Separately check equality of the scalar types and compound types in the ↵Ell-57/+158
order of declaration.
2025-05-28Reorder `ast::ItemKind::{Struct,Enum,Union}` fields.Nicholas Nethercote-1/+1
So they match the order of the parts in the source code, e.g.: ``` struct Foo<T, U> { t: T, u: U } <-><----> <------------> / | \ ident generics variant_data ```
2025-04-01Move `ast::Item::ident` into `ast::ItemKind`.Nicholas Nethercote-1/+1
`ast::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, `Trait`, `TraitAlias`, `MacroDef`, `Delegation`. - It's always empty for these item kinds: `Use`, `ForeignMod`, `GlobalAsm`, `Impl`, `MacCall`, `DelegationMac`. There is a similar story for `AssocItemKind` and `ForeignItemKind`. Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. The commit is large but it's mostly obvious plumbing work. Some notable things. - `ast::Item` got 8 bytes bigger. This could be avoided by boxing the fields within some of the `ast::ItemKind` variants (specifically: `Struct`, `Union`, `Enum`). I might do that in a follow-up; this commit is big enough already. - For the visitors: `FnKind` no longer needs an `ident` field because the `Fn` within how has one. - In the parser, the `ItemInfo` typedef is no longer needed. It was used in various places to return an `Ident` alongside an `ItemKind`, but now the `Ident` (if present) is within the `ItemKind`. - In a few places I renamed identifier variables called `name` (or `foo_name`) as `ident` (or `foo_ident`), to better match the type, and because `name` is normally used for `Symbol`s. It's confusing to see something like `foo_name.name`.
2025-02-08Rustfmtbjorn3-4/+7
2024-12-18Re-export more `rustc_span::symbol` things from `rustc_span`.Nicholas Nethercote-8/+4
`rustc_span::symbol` defines some things that are re-exported from `rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some closely related things such as `Ident` and `kw`. So you can do `use rustc_span::{Symbol, sym}` but you have to do `use rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good reason. This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`, and changes many `rustc_span::symbol::` qualifiers in `compiler/` to `rustc_span::`. This is a 200+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
2024-09-22Reformat using the new identifier sorting from rustfmtMichael Goulet-12/+9
2024-07-29Reformat `use` declarations.Nicholas Nethercote-13/+16
The previous commit updated `rustfmt.toml` appropriately. This commit is the outcome of running `x fmt --all` with the new formatting options.
2024-05-09Auto merge of #124157 - wutchzone:partial_eq, r=estebankbors-3/+2
Do not add leading asterisk in the `PartialEq` I think we should address this issue, however I am not exactly sure, if this is the right way to do it. It is related to the #123056. Imagine the simplified code: ```rust trait MyTrait {} impl PartialEq for dyn MyTrait { fn eq(&self, _other: &Self) -> bool { true } } #[derive(PartialEq)] enum Bar { Foo(Box<dyn MyTrait>), } ``` On the nightly compiler, the `derive` produces invalid code with the weird error message: ``` error[E0507]: cannot move out of `*__arg1_0` which is behind a shared reference --> src/main.rs:11:9 | 9 | #[derive(PartialEq)] | --------- in this derive macro expansion 10 | enum Things { 11 | Foo(Box<dyn MyTrait>), | ^^^^^^^^^^^^^^^^ move occurs because `*__arg1_0` has type `Box<dyn MyTrait>`, which does not implement the `Copy` trait | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) ``` It may be related to the perfect derive problem, although requiring the _type_ to be `Copy` seems unfortunate because it is not necessary. Besides, we are adding the extra dereference only for the diagnostics?
2024-04-26Adjust some `pub`s.Nicholas Nethercote-5/+5
2024-04-23Do not add leading asterisk in the `PartialEq`Daniel Sedlak-3/+2
Adding leading asterisk can cause compilation failure for the _types_ that don't implement the `Copy`.
2024-04-14builtin-derive: tag → discriminantRalf Jung-10/+10
2024-03-28change BuiltinDeriveFn type to get ExtCtxt by immutable ref and fix signaturesklensy-4/+4
2024-03-28compiler: fix few needless_pass_by_ref_mut clippy lintsklensy-3/+3
warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\clone.rs:160:9 | 160 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\cmp\partial_ord.rs:72:9 | 72 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\cmp\partial_eq.rs:19:18 | 19 | fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\cmp\ord.rs:42:19 | 42 | pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:917:13 | 917 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1406:13 | 1406 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1157:13 | 1157 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1103:13 | 1103 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1080:13 | 1080 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:859:13 | 859 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:805:13 | 805 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:467:13 | 467 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:457:13 | 457 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
2024-03-28compiler: fix few needless_pass_by_ref_mut clippy lintsklensy-1/+1
warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\mod.rs:120:9 | 120 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1573:13 | 1573 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1556:13 | 1556 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1463:13 | 1463 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:1433:36 | 1433 | fn summarise_struct(&self, cx: &mut ExtCtxt<'_>, struct_def: &VariantData) -> StaticFields { | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:953:13 | 953 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:932:13 | 932 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:580:13 | 580 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\generic\mod.rs:989:13 | 989 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\clone.rs:97:9 | 97 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\cmp\eq.rs:52:9 | 52 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\hash.rs:50:9 | 50 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\encodable.rs:150:9 | 150 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\default.rs:176:9 | 176 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\default.rs:106:9 | 106 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\default.rs:57:9 | 57 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\default.rs:84:9 | 84 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\debug.rs:212:9 | 212 | cx: &mut ExtCtxt<'_>, | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut warning: this argument is a mutable reference, but not used mutably --> compiler\rustc_builtin_macros\src\deriving\debug.rs:48:26 | 48 | fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr { | ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
2024-03-06Add MatchKind member to the Match expr for pretty printing & fmtRoss Smyth-1/+1
2024-01-24remove StructuralEq traitRalf Jung-13/+0
2023-12-24Remove `ExtCtxt` methods that duplicate `DiagCtxt` methods.Nicholas Nethercote-4/+5
2023-12-03Parse a pattern with no armNadrieril-1/+1
2023-10-13Format all the let chains in compilerMichael Goulet-24/+31
2023-09-18simplify inject_impl_of_structural_traitRalf Jung-9/+27
2023-09-08Rework no_coverage to coverage(off)Andy Caldwell-1/+1
2023-07-12Re-format let-else per rustfmt updateMark Rousskov-4/+4
2023-05-26Avoid some unnecessary local `attr` variables.Nicholas Nethercote-13/+8
2023-02-21Use `ThinVec` in `ast::ExprKind::Match`.Nicholas Nethercote-2/+2
2023-02-21Use `ThinVec` in `ast::Block`.Nicholas Nethercote-2/+2
2023-02-21Use `ThinVec` in various AST types.Nicholas Nethercote-2/+2
This commit changes the sequence parsers to produce `ThinVec`, which triggers numerous conversions.
2023-02-01Fix syntax in `-Zunpretty-expanded` output for derived `PartialEq`.Nicholas Nethercote-5/+19
If you do `derive(PartialEq)` on a packed struct, the output shown by `-Zunpretty=expanded` includes expressions like this: ``` { self.x } == { other.x } ``` This is invalid syntax. This doesn't break compilation, because the AST nodes are constructed within the compiler. But it does mean anyone using `-Zunpretty=expanded` output as a guide for hand-written impls could get a nasty surprise. This commit fixes things by instead using this form: ``` ({ self.x }) == ({ other.x }) ```
2023-01-30Allow more deriving on packed structs.Nicholas Nethercote-0/+4
Currently, deriving on packed structs has some non-trivial limitations, related to the fact that taking references on unaligned fields is UB. The current approach to field accesses in derived code: - Normal case: `&self.0` - In a packed struct that derives `Copy`: `&{self.0}` - In a packed struct that doesn't derive `Copy`: `&self.0` Plus, we disallow deriving any builtin traits other than `Default` for any packed generic type, because it's possible that there might be misaligned fields. This is a fairly broad restriction. Plus, we disallow deriving any builtin traits other than `Default` for most packed types that don't derive `Copy`. (The exceptions are those where the alignments inherently satisfy the packing, e.g. in a type with `repr(packed(N))` where all the fields have alignments of `N` or less anyway. Such types are pretty strange, because the `packed` attribute is not having any effect.) This commit introduces a new, simpler approach to field accesses: - Normal case: `&self.0` - In a packed struct: `&{self.0}` In the latter case, this requires that all fields impl `Copy`, which is a new restriction. This means that the following example compiles under the old approach and doesn't compile under the new approach. ``` #[derive(Debug)] struct NonCopy(u8); #[derive(Debug) #[repr(packed)] struct MyType(NonCopy); ``` (Note that the old approach's support for cases like this was brittle. Changing the `u8` to a `u16` would be enough to stop it working. So not much capability is lost here.) However, the other constraints from the old rules are removed. We can now derive builtin traits for packed generic structs like this: ``` trait Trait { type A; } #[derive(Hash)] #[repr(packed)] pub struct Foo<T: Trait>(T, T::A); ``` To allow this, we add a `T: Copy` bound in the derived impl and a `T::A: Copy` bound in where clauses. So `T` and `T::A` must impl `Copy`. We can now also derive builtin traits for packed structs that don't derive `Copy`, so long as the fields impl `Copy`: ``` #[derive(Hash)] #[repr(packed)] pub struct Foo(u32); ``` This includes types that hand-impl `Copy` rather than deriving it, such as the following, that show up in winapi-0.2: ``` #[derive(Clone)] #[repr(packed)] struct MyType(i32); impl Copy for MyType {} ``` The new approach is simpler to understand and implement, and it avoids the need for the `unsafe_derive_on_repr_packed` check. One exception is required for backwards-compatibility: we allow `[u8]` fields for now. There is a new lint for this, `byte_slice_in_packed_struct_with_derive`.
2023-01-28Auto merge of #103659 - clubby789:improve-partialord-derive, r=nagisabors-9/+73
Special-case deriving `PartialOrd` for enums with dataless variants I was able to get slightly better codegen by flipping the derived `PartialOrd` logic for two-variant enums. I also tried to document the implementation of the derive macro to make the special-case logic a little clearer. ```rs #[derive(PartialEq, PartialOrd)] pub enum A<T> { A, B(T) } ``` ```diff impl<T: ::core::cmp::PartialOrd> ::core::cmp::PartialOrd for A<T> { #[inline] fn partial_cmp( &self, other: &A<T>, ) -> ::core::option::Option<::core::cmp::Ordering> { let __self_tag = ::core::intrinsics::discriminant_value(self); let __arg1_tag = ::core::intrinsics::discriminant_value(other); - match ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag) { - ::core::option::Option::Some(::core::cmp::Ordering::Equal) => { - match (self, other) { - (A::B(__self_0), A::B(__arg1_0)) => { - ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) - } - _ => ::core::option::Option::Some(::core::cmp::Ordering::Equal), - } + match (self, other) { + (A::B(__self_0), A::B(__arg1_0)) => { + ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0) } - cmp => cmp, + _ => ::core::cmp::PartialOrd::partial_cmp(&__self_tag, &__arg1_tag), } } } ``` Godbolt: [Current](https://godbolt.org/z/GYjEzG1T8), [New](https://godbolt.org/z/GoK78qx15) I'm not sure how common a case comparing two enums like this (such as `Option`) is, and if it's worth the slowdown of adding a special case to the derive. If it causes overall regressions it might be worth just manually implementing this for `Option`.
2023-01-19Add enum for fieldless unificationclubby789-4/+4
2023-01-15Special case deriving `PartialOrd` for certain enum layoutsclubby789-9/+73
2022-11-29Avoid more `MetaItem`-to-`Attribute` conversions.Nicholas Nethercote-12/+9
There is code for converting `Attribute` (syntactic) to `MetaItem` (semantic). There is also code for the reverse direction. The reverse direction isn't really necessary; it's currently only used when generating attributes, e.g. in `derive` code. This commit adds some new functions for creating `Attributes`s directly, without involving `MetaItem`s: `mk_attr_word`, `mk_attr_name_value_str`, `mk_attr_nested_word`, and `ExtCtxt::attr_{word,name_value_str,nested_word}`. These new methods replace the old functions for creating `Attribute`s: `mk_attr_inner`, `mk_attr_outer`, and `ExtCtxt::attribute`. Those functions took `MetaItem`s as input, and relied on many other functions that created `MetaItems`, which are also removed: `mk_name_value_item`, `mk_list_item`, `mk_word_item`, `mk_nested_word_item`, `{MetaItem,MetaItemKind,NestedMetaItem}::token_trees`, `MetaItemKind::attr_args`, `MetaItemLit::{from_lit_kind,to_token}`, `ExtCtxt::meta_word`. Overall this cuts more than 100 lines of code and makes thing simpler.
2022-11-15Rollup merge of #104391 - nnethercote:deriving-cleanups, r=jackh726Matthias Krüger-4/+0
Deriving cleanups Fixing some minor problems `@RalfJung` found in #99046. r? `@RalfJung`
2022-11-14Remove TraitDef::generics.Nicholas Nethercote-4/+0
Because it's always empty.
2022-11-12Rollup merge of #102049 - fee1-dead-contrib:derive_const, r=oli-obkDylan DPC-0/+8
Add the `#[derive_const]` attribute Closes #102371. This is a minimal patchset for the attribute to work. There are no restrictions on what traits this attribute applies to. r? `````@oli-obk`````
2022-09-20Add the `#[derive_const]` attributeDeadbeef-0/+8
2022-09-05Fix `#[derive(Default)]` on a generic `#[default]` enum adding unnecessary ↵Daniel Henry-Mantilla-0/+4
`Default` bounds
2022-08-29Replace `rustc_data_structures::thin_vec::ThinVec` with `thin_vec::ThinVec`.Nicholas Nethercote-7/+8
`rustc_data_structures::thin_vec::ThinVec` looks like this: ``` pub struct ThinVec<T>(Option<Box<Vec<T>>>); ``` It's just a zero word if the vector is empty, but requires two allocations if it is non-empty. So it's only usable in cases where the vector is empty most of the time. This commit removes it in favour of `thin_vec::ThinVec`, which is also word-sized, but stores the length and capacity in the same allocation as the elements. It's good in a wider variety of situation, e.g. in enum variants where the vector is usually/always non-empty. The commit also: - Sorts some `Cargo.toml` dependency lists, to make additions easier. - Sorts some `use` item lists, to make additions easier. - Changes `clean_trait_ref_with_bindings` to take a `ThinVec<TypeBinding>` rather than a `&[TypeBinding]`, because this avoid some unnecessary allocations.
2022-08-22Use `AttrVec` in more places.Nicholas Nethercote-4/+4
In some places we use `Vec<Attribute>` and some places we use `ThinVec<Attribute>` (a.k.a. `AttrVec`). This results in various points where we have to convert between `Vec` and `ThinVec`. This commit changes the places that use `Vec<Attribute>` to use `AttrVec`. A lot of this is mechanical and boring, but there are some interesting parts: - It adds a few new methods to `ThinVec`. - It implements `MapInPlace` for `ThinVec`, and introduces a macro to avoid the repetition of this trait for `Vec`, `SmallVec`, and `ThinVec`. Overall, it makes the code a little nicer, and has little effect on performance. But it is a precursor to removing `rustc_data_structures::thin_vec::ThinVec` and replacing it with `thin_vec::ThinVec`, which is implemented more efficiently.
2022-08-18Auto merge of #98655 - nnethercote:dont-derive-PartialEq-ne, r=dtolnaybors-41/+25
Don't derive `PartialEq::ne`. Currently we skip deriving `PartialEq::ne` for C-like (fieldless) enums and empty structs, thus reyling on the default `ne`. This behaviour is unnecessarily conservative, because the `PartialEq` docs say this: > Implementations must ensure that eq and ne are consistent with each other: > > `a != b` if and only if `!(a == b)` (ensured by the default > implementation). This means that the default implementation (`!(a == b)`) is always good enough. So this commit changes things such that `ne` is never derived. The motivation for this change is that not deriving `ne` reduces compile times and binary sizes. Observable behaviour may change if a user has defined a type `A` with an inconsistent `PartialEq` and then defines a type `B` that contains an `A` and also derives `PartialEq`. Such code is already buggy and preserving bug-for-bug compatibility isn't necessary. Two side-effects of the change: - There is only one error message produced for types where `PartialEq` cannot be derived, instead of two. - For coverage reports, some warnings about generated `ne` methods not being executed have disappeared. Both side-effects seem fine, and possibly preferable.
2022-08-17Remove `TraitDef::attributes`.Nicholas Nethercote-4/+0
Because it's always empty.
2022-08-01Don't derive `PartialEq::ne`.Nicholas Nethercote-41/+25
Currently we skip deriving `PartialEq::ne` for C-like (fieldless) enums and empty structs, thus reyling on the default `ne`. This behaviour is unnecessarily conservative, because the `PartialEq` docs say this: > Implementations must ensure that eq and ne are consistent with each other: > > `a != b` if and only if `!(a == b)` (ensured by the default > implementation). This means that the default implementation (`!(a == b)`) is always good enough. So this commit changes things such that `ne` is never derived. The motivation for this change is that not deriving `ne` reduces compile times and binary sizes. Observable behaviour may change if a user has defined a type `A` with an inconsistent `PartialEq` and then defines a type `B` that contains an `A` and also derives `PartialEq`. Such code is already buggy and preserving bug-for-bug compatibility isn't necessary. Two side-effects of the change: - There is only one error message produced for types where `PartialEq` cannot be derived, instead of two. - For coverage reports, some warnings about generated `ne` methods not being executed have disappeared. Both side-effects seem fine, and possibly preferable.
2022-07-11Handle tags better.Nicholas Nethercote-22/+0
Currently, for the enums and comparison traits we always check the tag for equality before doing anything else. This is a bit clumsy. This commit changes things so that the tags are handled very much like a zeroth field in the enum. For `eq`/ne` this makes the code slightly cleaner. For `partial_cmp` and `cmp` it's a more notable change: in the case where the tags aren't equal, instead of having a tag equality check followed by a tag comparison, it just does a single tag comparison. The commit also improves how `Hash` works for enums: instead of having duplicated code to hash the tag for every arm within the match, we do it just once before the match. All this required replacing the `EnumNonMatchingCollapsed` value with a new `EnumTag` value. For fieldless enums the new code is particularly improved. All the code now produced is close to optimal, being very similar to what you'd write by hand.
2022-07-11Remove unnecessary `&*` sigil pairs in derived code.Nicholas Nethercote-10/+19
By producing `&T` expressions for fields instead of `T`. This matches what the existing comments (e.g. on `FieldInfo`) claim is happening, and it's also what most of the trait-specific code needs. The exception is `PartialEq`, which needs `T` expressions for lots of special case error messaging to work. So we now convert the `&T` back to a `T` for `PartialEq`.
2022-07-09Simplify `cs_fold`.Nicholas Nethercote-123/+70
`cs_fold` has four distinct cases, covered by three different function arguments: - first field - combine current field with previous results - no fields - non-matching enum variants This commit clarifies things by replacing the three function arguments with one that takes a new `CsFold` type with four slightly different) cases - single field - combine result for current field with results for previous fields - no fields - non-matching enum variants This makes the code shorter and clearer.
2022-07-09Fix some inconsistencies.Nicholas Nethercote-58/+31
This makes `cs_cmp`, `cs_partial_cmp`, and `cs_op` (for `PartialEq`) more similar. It also fixes some out of date comments.
2022-07-09Rename `FieldInfo` fields.Nicholas Nethercote-23/+34
Use `self_exprs` and `other_selflike_exprs` in a manner similar to the previous commit.