diff options
Diffstat (limited to '')
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, |