summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_builtin_macros/src/deriving
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs70
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/debug.rs16
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/decodable.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs29
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/encodable.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs100
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/ty.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/hash.rs6
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs18
14 files changed, 131 insertions, 148 deletions
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 5ef68c6ae..7bd344467 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -15,8 +15,8 @@ pub fn expand_deriving_copy(
) {
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(marker::Copy),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index 7755ff779..fa8685f5f 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -1,12 +1,12 @@
use crate::deriving::generic::ty::*;
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;
+use thin_vec::thin_vec;
pub fn expand_deriving_clone(
cx: &mut ExtCtxt<'_>,
@@ -68,11 +68,11 @@ pub fn expand_deriving_clone(
}
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(clone::Clone),
+ skip_path_as_bound: false,
additional_bounds: bounds,
generics: Bounds::empty(),
supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
index 4e798bf6a..eab67b0d3 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_eq(
cx: &mut ExtCtxt<'_>,
@@ -20,11 +21,11 @@ pub fn expand_deriving_eq(
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
let no_coverage = cx.meta_word(span, sym::no_coverage);
- let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
+ let attrs = thin_vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::Eq),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
index 1612be862..7f117981a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs
@@ -1,11 +1,11 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::path_std;
-
use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_ord(
cx: &mut ExtCtxt<'_>,
@@ -15,11 +15,11 @@ pub fn expand_deriving_ord(
push: &mut dyn FnMut(Annotatable),
) {
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::Ord),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
index 0141b3377..236cbccaf 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs
@@ -1,12 +1,12 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_local, path_std};
-
use rustc_ast::ptr::P;
use rustc_ast::{BinOpKind, BorrowKind, Expr, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_partial_eq(
cx: &mut ExtCtxt<'_>,
@@ -15,14 +15,8 @@ pub fn expand_deriving_partial_eq(
item: &Annotatable,
push: &mut dyn FnMut(Annotatable),
) {
- fn cs_op(
- cx: &mut ExtCtxt<'_>,
- span: Span,
- substr: &Substructure<'_>,
- op: BinOpKind,
- combiner: BinOpKind,
- base: bool,
- ) -> BlockOrExpr {
+ fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
+ let base = true;
let expr = cs_fold(
true, // use foldl
cx,
@@ -47,39 +41,22 @@ pub fn expand_deriving_partial_eq(
cx.expr_deref(field.span, expr.clone())
}
};
- cx.expr_binary(field.span, op, convert(&field.self_expr), convert(other_expr))
+ cx.expr_binary(
+ field.span,
+ BinOpKind::Eq,
+ convert(&field.self_expr),
+ convert(other_expr),
+ )
+ }
+ CsFold::Combine(span, expr1, expr2) => {
+ cx.expr_binary(span, BinOpKind::And, expr1, expr2)
}
- CsFold::Combine(span, expr1, expr2) => cx.expr_binary(span, combiner, expr1, expr2),
CsFold::Fieldless => cx.expr_bool(span, base),
},
);
BlockOrExpr::new_expr(expr)
}
- fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
- cs_op(cx, span, substr, BinOpKind::Eq, BinOpKind::And, true)
- }
- fn cs_ne(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
- cs_op(cx, span, substr, BinOpKind::Ne, BinOpKind::Or, false)
- }
-
- macro_rules! md {
- ($name:expr, $f:ident) => {{
- let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
- MethodDef {
- name: $name,
- generics: Bounds::empty(),
- explicit_self: true,
- nonself_args: vec![(self_ref(), sym::other)],
- ret_ty: Path(path_local!(bool)),
- attributes: attrs,
- unify_fieldless_variants: true,
- combine_substructure: combine_substructure(Box::new(|a, b, c| $f(a, b, c))),
- }
- }};
- }
-
super::inject_impl_of_structural_trait(
cx,
span,
@@ -88,18 +65,25 @@ pub fn expand_deriving_partial_eq(
push,
);
- // avoid defining `ne` if we can
- // c-like enums, enums without any fields and structs without fields
- // can safely define only `eq`.
- let mut methods = vec![md!(sym::eq, cs_eq)];
- if !is_type_without_fields(item) {
- methods.push(md!(sym::ne, cs_ne));
- }
+ // No need to generate `ne`, the default suffices, and not generating it is
+ // faster.
+ let inline = cx.meta_word(span, sym::inline);
+ let attrs = thin_vec![cx.attribute(inline)];
+ let methods = vec![MethodDef {
+ name: sym::eq,
+ generics: Bounds::empty(),
+ explicit_self: true,
+ nonself_args: vec![(self_ref(), sym::other)],
+ ret_ty: Path(path_local!(bool)),
+ attributes: attrs,
+ unify_fieldless_variants: true,
+ combine_substructure: combine_substructure(Box::new(|a, b, c| cs_eq(a, b, c))),
+ }];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(cmp::PartialEq),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
index 2ebb01cc8..4173403a1 100644
--- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs
@@ -1,11 +1,11 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_std, pathvec_std};
-
use rustc_ast::MetaItem;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
+use thin_vec::thin_vec;
pub fn expand_deriving_partial_ord(
cx: &mut ExtCtxt<'_>,
@@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord(
Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std));
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let partial_cmp_def = MethodDef {
name: sym::partial_cmp,
@@ -36,8 +36,8 @@ pub fn expand_deriving_partial_ord(
let trait_def = TraitDef {
span,
- attributes: vec![],
path: path_std!(cmp::PartialOrd),
+ skip_path_as_bound: false,
additional_bounds: vec![],
generics: Bounds::empty(),
supports_unions: false,
diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs
index ceef893e8..2cf614ed9 100644
--- a/compiler/rustc_builtin_macros/src/deriving/debug.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs
@@ -19,8 +19,8 @@ pub fn expand_deriving_debug(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: path_std!(fmt::Debug),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
@@ -30,7 +30,7 @@ pub fn expand_deriving_debug(
explicit_self: true,
nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)),
- attributes: Vec::new(),
+ attributes: ast::AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c)
@@ -52,7 +52,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
// We want to make sure we have the ctxt set so that we can use unstable methods
let span = cx.with_def_site_ctxt(span);
- let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
+ let name = cx.expr_str(span, ident.name);
let fmt = substr.nonselflike_args[0].clone();
// Struct and tuples are similar enough that we use the same code for both,
@@ -89,10 +89,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
for i in 0..fields.len() {
let field = &fields[i];
if is_struct {
- let name = cx.expr_lit(
- field.span,
- ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
- );
+ let name = cx.expr_str(field.span, field.name.unwrap().name);
args.push(name);
}
// Use an extra indirection to make sure this works for unsized types.
@@ -108,10 +105,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
for field in fields {
if is_struct {
- name_exprs.push(cx.expr_lit(
- field.span,
- ast::LitKind::Str(field.name.unwrap().name, ast::StrStyle::Cooked),
- ));
+ name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name));
}
// Use an extra indirection to make sure this works for unsized types.
diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
index d688143a2..d669f6168 100644
--- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs
@@ -22,8 +22,8 @@ pub fn expand_deriving_rustc_decodable(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
@@ -48,7 +48,7 @@ pub fn expand_deriving_rustc_decodable(
],
PathKind::Std,
)),
- attributes: Vec::new(),
+ attributes: ast::AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate)
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 517769091..17df9fb27 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -1,16 +1,14 @@
use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
-
use rustc_ast as ast;
-use rustc_ast::walk_list;
-use rustc_ast::EnumDef;
-use rustc_ast::VariantData;
+use rustc_ast::{walk_list, EnumDef, VariantData};
use rustc_errors::Applicability;
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident;
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;
use smallvec::SmallVec;
+use thin_vec::thin_vec;
pub fn expand_deriving_default(
cx: &mut ExtCtxt<'_>,
@@ -22,11 +20,11 @@ pub fn expand_deriving_default(
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
let inline = cx.meta_word(span, sym::inline);
- let attrs = vec![cx.attribute(inline)];
+ let attrs = thin_vec![cx.attribute(inline)];
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new(vec![kw::Default, sym::Default]),
+ skip_path_as_bound: has_a_default_variant(item),
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
@@ -265,3 +263,22 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, '
}
}
}
+
+fn has_a_default_variant(item: &Annotatable) -> bool {
+ struct HasDefaultAttrOnVariant {
+ found: bool,
+ }
+
+ impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant {
+ fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) {
+ if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) {
+ self.found = true;
+ }
+ // no need to subrecurse.
+ }
+ }
+
+ let mut visitor = HasDefaultAttrOnVariant { found: false };
+ item.visit_with(&mut visitor);
+ visitor.found
+}
diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
index 70167cac6..f83f58b97 100644
--- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs
@@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::pathvec_std;
-use rustc_ast::{ExprKind, MetaItem, Mutability};
+use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::Span;
@@ -106,8 +106,8 @@ pub fn expand_deriving_rustc_encodable(
let trait_def = TraitDef {
span,
- attributes: Vec::new(),
path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global),
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
@@ -132,7 +132,7 @@ pub fn expand_deriving_rustc_encodable(
],
PathKind::Std,
)),
- attributes: Vec::new(),
+ attributes: AttrVec::new(),
unify_fieldless_variants: false,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c, krate)
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 735017aa5..16ee3aa89 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -162,33 +162,35 @@
pub use StaticFields::*;
pub use SubstructureFields::*;
-use std::cell::RefCell;
-use std::iter;
-use std::vec;
-
+use crate::deriving;
use rustc_ast::ptr::P;
-use rustc_ast::{self as ast, EnumDef, Expr, Generics, PatKind};
+use rustc_ast::{
+ self as ast, BindingAnnotation, ByRef, EnumDef, Expr, Generics, Mutability, PatKind,
+};
use rustc_ast::{GenericArg, GenericParamKind, VariantData};
use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
-
+use std::cell::RefCell;
+use std::iter;
+use std::ops::Not;
+use std::vec;
+use thin_vec::thin_vec;
use ty::{Bounds, Path, Ref, Self_, Ty};
-use crate::deriving;
-
pub mod ty;
pub struct TraitDef<'a> {
/// The span for the current #[derive(Foo)] header.
pub span: Span,
- pub attributes: Vec<ast::Attribute>,
-
/// Path of the trait, including any type parameters
pub path: Path,
+ /// Whether to skip adding the current trait as a bound to the type parameters of the type.
+ pub skip_path_as_bound: bool,
+
/// Additional bounds required of any type parameters of the type,
/// other than the current trait
pub additional_bounds: Vec<Ty>,
@@ -219,7 +221,7 @@ pub struct MethodDef<'a> {
/// Returns type
pub ret_ty: Ty,
- pub attributes: Vec<ast::Attribute>,
+ pub attributes: ast::AttrVec,
/// Can we combine fieldless variants for enums into a single match arm?
/// If true, indicates that the trait operation uses the enum tag in some
@@ -383,16 +385,11 @@ fn find_type_parameters(
}
// Place bound generic params on a stack, to extract them when a type is encountered.
- fn visit_poly_trait_ref(
- &mut self,
- trait_ref: &'a ast::PolyTraitRef,
- modifier: &'a ast::TraitBoundModifier,
- ) {
+ fn visit_poly_trait_ref(&mut self, trait_ref: &'a ast::PolyTraitRef) {
let stack_len = self.bound_generic_params_stack.len();
- self.bound_generic_params_stack
- .extend(trait_ref.bound_generic_params.clone().into_iter());
+ self.bound_generic_params_stack.extend(trait_ref.bound_generic_params.iter().cloned());
- visit::walk_poly_trait_ref(self, trait_ref, modifier);
+ visit::walk_poly_trait_ref(self, trait_ref);
self.bound_generic_params_stack.truncate(stack_len);
}
@@ -568,8 +565,8 @@ impl<'a> TraitDef<'a> {
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
- attrs: Vec::new(),
- kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
+ attrs: ast::AttrVec::new(),
+ kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias {
defaultness: ast::Defaultness::Final,
generics: Generics::default(),
where_clauses: (
@@ -603,13 +600,13 @@ impl<'a> TraitDef<'a> {
cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
}).chain(
// require the current trait
- iter::once(cx.trait_bound(trait_path.clone()))
+ self.skip_path_as_bound.not().then(|| cx.trait_bound(trait_path.clone()))
).chain(
// also add in any bounds from the declaration
param.bounds.iter().cloned()
).collect();
- cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, vec![], bounds, None)
+ cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None)
}
GenericParamKind::Const { ty, kw_span, .. } => {
let const_nodefault_kind = GenericParamKind::Const {
@@ -644,11 +641,7 @@ impl<'a> TraitDef<'a> {
}
ast::WherePredicate::EqPredicate(we) => {
let span = we.span.with_ctxt(ctxt);
- ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
- id: ast::DUMMY_NODE_ID,
- span,
- ..we.clone()
- })
+ ast::WherePredicate::EqPredicate(ast::WhereEqPredicate { span, ..we.clone() })
}
}
}));
@@ -726,15 +719,13 @@ impl<'a> TraitDef<'a> {
let self_type = cx.ty_path(path);
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
+ let attrs = thin_vec![attr];
let opt_trait_ref = Some(trait_ref);
- let mut a = vec![attr];
- a.extend(self.attributes.iter().cloned());
-
cx.item(
self.span,
Ident::empty(),
- a,
+ attrs,
ast::ItemKind::Impl(Box::new(ast::Impl {
unsafety: ast::Unsafe::No,
polarity: ast::ImplPolarity::Positive,
@@ -1078,9 +1069,9 @@ impl<'a> MethodDef<'a> {
let mut body = mk_body(cx, selflike_fields);
let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]);
- let use_ref_pat = is_packed && !always_copy;
+ let by_ref = ByRef::from(is_packed && !always_copy);
let patterns =
- trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, use_ref_pat);
+ trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, by_ref);
// Do the let-destructuring.
let mut stmts: Vec<_> = iter::zip(selflike_args, patterns)
@@ -1123,6 +1114,11 @@ impl<'a> MethodDef<'a> {
/// ```
/// is equivalent to:
/// ```
+ /// #![feature(core_intrinsics)]
+ /// enum A {
+ /// A1,
+ /// A2(i32)
+ /// }
/// impl ::core::cmp::PartialEq for A {
/// #[inline]
/// fn eq(&self, other: &A) -> bool {
@@ -1262,13 +1258,13 @@ impl<'a> MethodDef<'a> {
let sp = variant.span.with_ctxt(trait_.span.ctxt());
let variant_path = cx.path(sp, vec![type_ident, variant.ident]);
- let use_ref_pat = false; // because enums can't be repr(packed)
+ let by_ref = ByRef::No; // because enums can't be repr(packed)
let mut subpats: Vec<_> = trait_.create_struct_patterns(
cx,
variant_path,
&variant.data,
&prefixes,
- use_ref_pat,
+ by_ref,
);
// `(VariantK, VariantK, ...)` or just `VariantK`.
@@ -1429,7 +1425,7 @@ impl<'a> TraitDef<'a> {
struct_path: ast::Path,
struct_def: &'a VariantData,
prefixes: &[String],
- use_ref_pat: bool,
+ by_ref: ByRef,
) -> Vec<P<ast::Pat>> {
prefixes
.iter()
@@ -1437,17 +1433,19 @@ impl<'a> TraitDef<'a> {
let pieces_iter =
struct_def.fields().iter().enumerate().map(|(i, struct_field)| {
let sp = struct_field.span.with_ctxt(self.span.ctxt());
- let binding_mode = if use_ref_pat {
- ast::BindingMode::ByRef(ast::Mutability::Not)
- } else {
- ast::BindingMode::ByValue(ast::Mutability::Not)
- };
let ident = self.mk_pattern_ident(prefix, i);
let path = ident.with_span_pos(sp);
(
sp,
struct_field.ident,
- cx.pat(path.span, PatKind::Ident(binding_mode, path, None)),
+ cx.pat(
+ path.span,
+ PatKind::Ident(
+ BindingAnnotation(by_ref, Mutability::Not),
+ path,
+ None,
+ ),
+ ),
)
});
@@ -1637,19 +1635,3 @@ where
StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
-
-/// Returns `true` if the type has no value fields
-/// (for an enum, no variant has any fields)
-pub fn is_type_without_fields(item: &Annotatable) -> bool {
- if let Annotatable::Item(ref item) = *item {
- match item.kind {
- ast::ItemKind::Enum(ref enum_def, _) => {
- enum_def.variants.iter().all(|v| v.data.fields().is_empty())
- }
- ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
- _ => false,
- }
- } else {
- false
- }
-}
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
index 4d46f7cd4..36e2e2930 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs
@@ -146,7 +146,6 @@ fn mk_ty_param(
cx: &ExtCtxt<'_>,
span: Span,
name: Symbol,
- attrs: &[ast::Attribute],
bounds: &[Path],
self_ident: Ident,
self_generics: &Generics,
@@ -158,7 +157,7 @@ fn mk_ty_param(
cx.trait_bound(path)
})
.collect();
- cx.typaram(span, Ident::new(name, span), attrs.to_owned(), bounds, None)
+ cx.typaram(span, Ident::new(name, span), bounds, None)
}
/// Bounds on type parameters.
@@ -183,7 +182,7 @@ impl Bounds {
.iter()
.map(|t| {
let (name, ref bounds) = *t;
- mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
+ mk_ty_param(cx, span, name, &bounds, self_ty, self_generics)
})
.collect();
diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs
index 32ae3d344..6e9d5f08b 100644
--- a/compiler/rustc_builtin_macros/src/deriving/hash.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs
@@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::deriving::{path_std, pathvec_std};
-use rustc_ast::{MetaItem, Mutability};
+use rustc_ast::{AttrVec, MetaItem, Mutability};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@@ -21,8 +21,8 @@ pub fn expand_deriving_hash(
let arg = Path::new_local(typaram);
let hash_trait_def = TraitDef {
span,
- attributes: Vec::new(),
path,
+ skip_path_as_bound: false,
additional_bounds: Vec::new(),
generics: Bounds::empty(),
supports_unions: false,
@@ -32,7 +32,7 @@ pub fn expand_deriving_hash(
explicit_self: true,
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
ret_ty: Unit,
- attributes: vec![],
+ attributes: AttrVec::new(),
unify_fieldless_variants: true,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c)
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index c1ca089da..ee346047a 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -131,6 +131,8 @@ fn inject_impl_of_structural_trait(
// Create generics param list for where clauses and impl headers
let mut generics = generics.clone();
+ let ctxt = span.ctxt();
+
// Create the type of `self`.
//
// in addition, remove defaults from generic params (impls cannot have them).
@@ -138,16 +140,18 @@ fn inject_impl_of_structural_trait(
.params
.iter_mut()
.map(|param| match &mut param.kind {
- ast::GenericParamKind::Lifetime => {
- ast::GenericArg::Lifetime(cx.lifetime(span, param.ident))
- }
+ ast::GenericParamKind::Lifetime => ast::GenericArg::Lifetime(
+ cx.lifetime(param.ident.span.with_ctxt(ctxt), param.ident),
+ ),
ast::GenericParamKind::Type { default } => {
*default = None;
- ast::GenericArg::Type(cx.ty_ident(span, param.ident))
+ ast::GenericArg::Type(cx.ty_ident(param.ident.span.with_ctxt(ctxt), param.ident))
}
ast::GenericParamKind::Const { ty: _, kw_span: _, default } => {
*default = None;
- ast::GenericArg::Const(cx.const_ident(span, param.ident))
+ ast::GenericArg::Const(
+ cx.const_ident(param.ident.span.with_ctxt(ctxt), param.ident),
+ )
}
})
.collect();
@@ -164,7 +168,7 @@ fn inject_impl_of_structural_trait(
// Keep the lint and stability attributes of the original item, to control
// how the generated implementation is linted.
- let mut attrs = Vec::new();
+ let mut attrs = ast::AttrVec::new();
attrs.extend(
item.attrs
.iter()
@@ -174,6 +178,8 @@ fn inject_impl_of_structural_trait(
})
.cloned(),
);
+ // Mark as `automatically_derived` to avoid some silly lints.
+ attrs.push(cx.attribute(cx.meta_word(span, sym::automatically_derived)));
let newitem = cx.item(
span,