Skip to content

Commit 824df7b

Browse files
committed
Only derive all of PartialOrd's methods when not also deriving PartialEq
1 parent 1f7762b commit 824df7b

File tree

6 files changed

+52
-23
lines changed

6 files changed

+52
-23
lines changed

compiler/rustc_builtin_macros/src/deriving/clone.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::deriving::path_std;
44

55
use rustc_ast::ptr::P;
66
use rustc_ast::{self as ast, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData};
7-
use rustc_expand::base::{Annotatable, ExtCtxt};
7+
use rustc_expand::base::{Annotatable, BuiltinDerive, ExtCtxt};
88
use rustc_span::symbol::{kw, sym, Ident, Symbol};
99
use rustc_span::Span;
1010

@@ -37,7 +37,7 @@ pub fn expand_deriving_clone(
3737
ItemKind::Struct(_, Generics { ref params, .. })
3838
| ItemKind::Enum(_, Generics { ref params, .. }) => {
3939
let container_id = cx.current_expansion.id.expn_data().parent;
40-
if cx.resolver.has_derive_copy(container_id)
40+
if cx.resolver.has_derive(container_id, BuiltinDerive::Copy)
4141
&& !params.iter().any(|param| match param.kind {
4242
ast::GenericParamKind::Type { .. } => true,
4343
_ => false,

compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::deriving::{path_local, path_std, pathvec_std};
66

77
use rustc_ast::ptr::P;
88
use rustc_ast::{self as ast, BinOpKind, Expr, MetaItem};
9-
use rustc_expand::base::{Annotatable, ExtCtxt};
9+
use rustc_expand::base::{Annotatable, BuiltinDerive, ExtCtxt};
1010
use rustc_span::symbol::{sym, Ident, Symbol};
1111
use rustc_span::Span;
1212

@@ -63,9 +63,12 @@ pub fn expand_deriving_partial_ord(
6363
};
6464

6565
// avoid defining extra methods if we can
66-
// c-like enums, enums without any fields and structs without fields
67-
// can safely define only `partial_cmp`.
68-
let methods = if is_type_without_fields(item) {
66+
// c-like enums, enums without any fields, structs without fields,
67+
// as well as types that derive `PartialEq` can safely define only `partial_cmp`.
68+
let container_id = cx.current_expansion.id.expn_data().parent;
69+
let methods = if is_type_without_fields(item)
70+
|| cx.resolver.has_derive(container_id, BuiltinDerive::PartialEq)
71+
{
6972
vec![partial_cmp_def]
7073
} else {
7174
vec![

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ use rustc_ast::{self as ast, BinOpKind, EnumDef, Expr, Generics, PatKind};
186186
use rustc_ast::{GenericArg, GenericParamKind, VariantData};
187187
use rustc_attr as attr;
188188
use rustc_data_structures::map_in_place::MapInPlace;
189-
use rustc_expand::base::{Annotatable, ExtCtxt};
189+
use rustc_expand::base::{Annotatable, BuiltinDerive, ExtCtxt};
190190
use rustc_span::symbol::{kw, sym, Ident, Symbol};
191191
use rustc_span::Span;
192192

@@ -410,7 +410,8 @@ impl<'a> TraitDef<'a> {
410410
_ => unreachable!(),
411411
};
412412
let container_id = cx.current_expansion.id.expn_data().parent;
413-
let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
413+
let always_copy =
414+
has_no_type_params && cx.resolver.has_derive(container_id, BuiltinDerive::Copy);
414415
let use_temporaries = is_packed && always_copy;
415416

416417
let newitem = match item.kind {

compiler/rustc_expand/src/base.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,8 @@ pub struct SyntaxExtension {
726726
/// Built-in macros have a couple of special properties like availability
727727
/// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
728728
pub is_builtin: bool,
729-
/// We have to identify macros providing a `Copy` impl early for compatibility reasons.
730-
pub is_derive_copy: bool,
729+
/// Keeps track of which builtin derives (if any) this is
730+
pub derive: Option<BuiltinDerive>,
731731
}
732732

733733
impl SyntaxExtension {
@@ -756,7 +756,7 @@ impl SyntaxExtension {
756756
helper_attrs: Vec::new(),
757757
edition,
758758
is_builtin: false,
759-
is_derive_copy: false,
759+
derive: None,
760760
kind,
761761
}
762762
}
@@ -789,6 +789,7 @@ impl SyntaxExtension {
789789
.span_diagnostic
790790
.span_err(span, "macros cannot have const stability attributes");
791791
}
792+
let derive = if is_builtin { BuiltinDerive::from_name(name) } else { None };
792793

793794
SyntaxExtension {
794795
kind,
@@ -801,7 +802,7 @@ impl SyntaxExtension {
801802
helper_attrs,
802803
edition,
803804
is_builtin,
804-
is_derive_copy: is_builtin && name == sym::Copy,
805+
derive,
805806
}
806807
}
807808

@@ -855,6 +856,25 @@ impl SyntaxExtension {
855856
}
856857
}
857858

859+
/// Built-in derives
860+
/// Only derives that are being used for special casing expansion are represented here
861+
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
862+
pub enum BuiltinDerive {
863+
Copy,
864+
PartialEq,
865+
}
866+
867+
impl BuiltinDerive {
868+
/// Possibly turn a symbol into a built-in derive
869+
fn from_name(name: Symbol) -> Option<Self> {
870+
match name {
871+
sym::Copy => Some(Self::Copy),
872+
sym::PartialEq => Some(Self::PartialEq),
873+
_ => None,
874+
}
875+
}
876+
}
877+
858878
/// Result of resolving a macro invocation.
859879
pub enum InvocationRes {
860880
Single(Lrc<SyntaxExtension>),
@@ -894,8 +914,8 @@ pub trait ResolverExpand {
894914
fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId;
895915

896916
// Resolver interfaces for specific built-in macros.
897-
/// Does `#[derive(...)]` attribute with the given `ExpnId` have built-in `Copy` inside it?
898-
fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
917+
/// Does `#[derive(...)]` attribute with the given `ExpnId` have the given built-in derive inside it?
918+
fn has_derive(&self, expn_id: ExpnId, derive: BuiltinDerive) -> bool;
899919
/// Path resolution logic for `#[cfg_accessible(path)]`.
900920
fn cfg_accessible(&mut self, expn_id: ExpnId, path: &ast::Path) -> Result<bool, Indeterminate>;
901921
}

compiler/rustc_resolve/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
3333
use rustc_data_structures::ptr_key::PtrKey;
3434
use rustc_data_structures::sync::Lrc;
3535
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
36-
use rustc_expand::base::SyntaxExtension;
36+
use rustc_expand::base::{BuiltinDerive, SyntaxExtension};
3737
use rustc_hir::def::Namespace::*;
3838
use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes};
3939
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
@@ -967,10 +967,10 @@ pub struct Resolver<'a> {
967967
multi_segment_macro_resolutions:
968968
Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>, Option<Res>)>,
969969
builtin_attrs: Vec<(Ident, ParentScope<'a>)>,
970-
/// `derive(Copy)` marks items they are applied to so they are treated specially later.
970+
/// built-in derives mark items they are applied to so they are treated specially later.
971971
/// Derive macros cannot modify the item themselves and have to store the markers in the global
972972
/// context, so they attach the markers to derive container IDs using this resolver table.
973-
containers_deriving_copy: FxHashSet<ExpnId>,
973+
containers_derives: FxHashMap<ExpnId, FxHashSet<BuiltinDerive>>,
974974
/// Parent scopes in which the macros were invoked.
975975
/// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
976976
invocation_parent_scopes: FxHashMap<ExpnId, ParentScope<'a>>,
@@ -1318,7 +1318,7 @@ impl<'a> Resolver<'a> {
13181318
single_segment_macro_resolutions: Default::default(),
13191319
multi_segment_macro_resolutions: Default::default(),
13201320
builtin_attrs: Default::default(),
1321-
containers_deriving_copy: Default::default(),
1321+
containers_derives: Default::default(),
13221322
active_features: features
13231323
.declared_lib_features
13241324
.iter()

compiler/rustc_resolve/src/macros.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ use rustc_data_structures::fx::FxHashSet;
1414
use rustc_data_structures::ptr_key::PtrKey;
1515
use rustc_data_structures::sync::Lrc;
1616
use rustc_errors::struct_span_err;
17-
use rustc_expand::base::{Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension};
17+
use rustc_expand::base::{
18+
BuiltinDerive, Indeterminate, InvocationRes, ResolverExpand, SyntaxExtension,
19+
};
1820
use rustc_expand::compile_declarative_macro;
1921
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind};
2022
use rustc_feature::is_builtin_attr_name;
@@ -285,8 +287,11 @@ impl<'a> ResolverExpand for Resolver<'a> {
285287
helper_attrs.extend(
286288
ext.helper_attrs.iter().map(|name| Ident::new(*name, span)),
287289
);
288-
if ext.is_derive_copy {
289-
self.containers_deriving_copy.insert(invoc_id);
290+
if let Some(derive) = ext.derive {
291+
self.containers_derives
292+
.entry(invoc_id)
293+
.or_default()
294+
.insert(derive);
290295
}
291296
ext
292297
}
@@ -347,8 +352,8 @@ impl<'a> ResolverExpand for Resolver<'a> {
347352
.map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[*id])
348353
}
349354

350-
fn has_derive_copy(&self, expn_id: ExpnId) -> bool {
351-
self.containers_deriving_copy.contains(&expn_id)
355+
fn has_derive(&self, expn_id: ExpnId, derive: BuiltinDerive) -> bool {
356+
self.containers_derives.get(&expn_id).map(|d| d.contains(&derive)).unwrap_or(false)
352357
}
353358

354359
// The function that implements the resolution logic of `#[cfg_accessible(path)]`.

0 commit comments

Comments
 (0)