diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-07-01 16:32:20 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2022-07-04 18:36:39 +1000 |
| commit | a7b1d31a9f358747221e8eb9986bb8303d5d6586 (patch) | |
| tree | 800969fe38a3592be6582cc24567496b42a92a85 /compiler/rustc_builtin_macros | |
| parent | 5762d2385ebdd735b110ab82e80eed6efa7d7c55 (diff) | |
| download | rust-a7b1d31a9f358747221e8eb9986bb8303d5d6586.tar.gz rust-a7b1d31a9f358747221e8eb9986bb8303d5d6586.zip | |
Don't repeat `AssertParamIs{Clone,Eq}` assertions.
It's common to see repeated assertions like this in derived `clone` and `eq` methods: ``` let _: ::core::clone::AssertParamIsClone<u32>; let _: ::core::clone::AssertParamIsClone<u32>; ``` This commit avoids them.
Diffstat (limited to 'compiler/rustc_builtin_macros')
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/clone.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs | 25 |
2 files changed, 35 insertions, 16 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index b37b82dd089..0a55d4e0ce0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -3,6 +3,7 @@ use crate::deriving::generic::*; use crate::deriving::path_std; use rustc_ast::{self as ast, Generics, ItemKind, MetaItem, VariantData}; +use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; @@ -99,20 +100,29 @@ fn cs_clone_simple( is_union: bool, ) -> BlockOrExpr { let mut stmts = Vec::new(); + let mut seen_type_names = FxHashSet::default(); let mut process_variant = |variant: &VariantData| { for field in variant.fields() { - // let _: AssertParamIsClone<FieldTy>; - super::assert_ty_bounds( - cx, - &mut stmts, - field.ty.clone(), - field.span, - &[sym::clone, sym::AssertParamIsClone], - ); + // This basic redundancy checking only prevents duplication of + // assertions like `AssertParamIsClone<Foo>` where the type is a + // simple name. That's enough to get a lot of cases, though. + if let Some(name) = field.ty.kind.is_simple_path() && !seen_type_names.insert(name) { + // Already produced an assertion for this type. + } else { + // let _: AssertParamIsClone<FieldTy>; + super::assert_ty_bounds( + cx, + &mut stmts, + field.ty.clone(), + field.span, + &[sym::clone, sym::AssertParamIsClone], + ); + } } }; if is_union { + // Just a single assertion for unions, that the union impls `Copy`. // let _: AssertParamIsCopy<Self>; let self_ty = cx.ty_path(cx.path_ident(trait_span, Ident::with_dummy_span(kw::SelfUpper))); super::assert_ty_bounds( diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 59f8fbc4a08..c1a2ebcc146 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -3,6 +3,7 @@ use crate::deriving::generic::*; use crate::deriving::path_std; use rustc_ast::{self as ast, MetaItem}; +use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -53,16 +54,24 @@ fn cs_total_eq_assert( substr: &Substructure<'_>, ) -> BlockOrExpr { let mut stmts = Vec::new(); + let mut seen_type_names = FxHashSet::default(); let mut process_variant = |variant: &ast::VariantData| { for field in variant.fields() { - // let _: AssertParamIsEq<FieldTy>; - super::assert_ty_bounds( - cx, - &mut stmts, - field.ty.clone(), - field.span, - &[sym::cmp, sym::AssertParamIsEq], - ); + // This basic redundancy checking only prevents duplication of + // assertions like `AssertParamIsEq<Foo>` where the type is a + // simple name. That's enough to get a lot of cases, though. + if let Some(name) = field.ty.kind.is_simple_path() && !seen_type_names.insert(name) { + // Already produced an assertion for this type. + } else { + // let _: AssertParamIsEq<FieldTy>; + super::assert_ty_bounds( + cx, + &mut stmts, + field.ty.clone(), + field.span, + &[sym::cmp, sym::AssertParamIsEq], + ); + } } }; |
