diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 12ef166b8b051..5ef68c6aeaa59 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -19,7 +19,6 @@ pub fn expand_deriving_copy( path: path_std!(marker::Copy), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: true, methods: Vec::new(), associated_types: Vec::new(), diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 8331710699063..1c507678489fe 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -15,23 +15,22 @@ pub fn expand_deriving_clone( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - // check if we can use a short form + // The simple form is `fn clone(&self) -> Self { *self }`, possibly with + // some additional `AssertParamIsClone` assertions. // - // the short form is `fn clone(&self) -> Self { *self }` - // - // we can use the short form if: - // - the item is Copy (unfortunately, all we can check is whether it's also deriving Copy) - // - there are no generic parameters (after specialization this limitation can be removed) - // if we used the short form with generics, we'd have to bound the generics with - // Clone + Copy, and then there'd be no Clone impl at all if the user fills in something - // that is Clone but not Copy. and until specialization we can't write both impls. - // - the item is a union with Copy fields - // Unions with generic parameters still can derive Clone because they require Copy - // for deriving, Clone alone is not enough. - // Wherever Clone is implemented for fields is irrelevant so we don't assert it. + // We can use the simple form if either of the following are true. + // - The type derives Copy and there are no generic parameters. (If we + // used the simple form with generics, we'd have to bound the generics + // with Clone + Copy, and then there'd be no Clone impl at all if the + // user fills in something that is Clone but not Copy. After + // specialization we can remove this no-generics limitation.) + // - The item is a union. (Unions with generic parameters still can derive + // Clone because they require Copy for deriving, Clone alone is not + // enough. Whether Clone is implemented for fields is irrelevant so we + // don't assert it.) let bounds; let substructure; - let is_shallow; + let is_simple; match *item { Annotatable::Item(ref annitem) => match annitem.kind { ItemKind::Struct(_, Generics { ref params, .. }) @@ -44,30 +43,25 @@ pub fn expand_deriving_clone( .any(|param| matches!(param.kind, ast::GenericParamKind::Type { .. })) { bounds = vec![]; - is_shallow = true; + is_simple = true; substructure = combine_substructure(Box::new(|c, s, sub| { - cs_clone_shallow("Clone", c, s, sub, false) + cs_clone_simple("Clone", c, s, sub, false) })); } else { bounds = vec![]; - is_shallow = false; + is_simple = false; substructure = combine_substructure(Box::new(|c, s, sub| cs_clone("Clone", c, s, sub))); } } ItemKind::Union(..) => { - bounds = vec![Literal(path_std!(marker::Copy))]; - is_shallow = true; + bounds = vec![Path(path_std!(marker::Copy))]; + is_simple = true; substructure = combine_substructure(Box::new(|c, s, sub| { - cs_clone_shallow("Clone", c, s, sub, true) + cs_clone_simple("Clone", c, s, sub, true) })); } - _ => { - bounds = vec![]; - is_shallow = false; - substructure = - combine_substructure(Box::new(|c, s, sub| cs_clone("Clone", c, s, sub))); - } + _ => cx.span_bug(span, "`#[derive(Clone)]` on wrong item kind"), }, _ => cx.span_bug(span, "`#[derive(Clone)]` on trait item or impl item"), @@ -81,26 +75,24 @@ pub fn expand_deriving_clone( path: path_std!(clone::Clone), additional_bounds: bounds, generics: Bounds::empty(), - is_unsafe: false, supports_unions: true, methods: vec![MethodDef { name: sym::clone, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), + explicit_self: true, args: Vec::new(), ret_ty: Self_, attributes: attrs, - is_unsafe: false, unify_fieldless_variants: false, combine_substructure: substructure, }], associated_types: Vec::new(), }; - trait_def.expand_ext(cx, mitem, item, push, is_shallow) + trait_def.expand_ext(cx, mitem, item, push, is_simple) } -fn cs_clone_shallow( +fn cs_clone_simple( name: &str, cx: &mut ExtCtxt<'_>, trait_span: Span, @@ -143,7 +135,7 @@ fn cs_clone_shallow( } _ => cx.span_bug( trait_span, - &format!("unexpected substructure in shallow `derive({})`", name), + &format!("unexpected substructure in simple `derive({})`", name), ), } } diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index f54ded3c87cab..cb2ad283a1971 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -27,16 +27,14 @@ pub fn expand_deriving_eq( path: path_std!(cmp::Eq), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: true, methods: vec![MethodDef { name: sym::assert_receiver_is_total_eq, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), + explicit_self: true, args: vec![], - ret_ty: nil_ty(), + ret_ty: Unit, attributes: attrs, - is_unsafe: false, unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| { cs_total_eq_assert(a, b, c) diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 2b3ac0a86c16c..c7850cd4b4cf6 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -23,16 +23,14 @@ pub fn expand_deriving_ord( path: path_std!(cmp::Ord), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::cmp, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), sym::other)], - ret_ty: Literal(path_std!(cmp::Ordering)), + explicit_self: true, + args: vec![(self_ref(), sym::other)], + ret_ty: Path(path_std!(cmp::Ordering)), attributes: attrs, - is_unsafe: false, unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))), }], @@ -99,8 +97,8 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P< cx.expr_match(span, new, vec![eq_arm, neq_arm]) }, cx.expr_path(equals_path.clone()), - Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| { - if self_args.len() != 2 { + Box::new(|cx, span, tag_tuple| { + if tag_tuple.len() != 2 { cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`") } else { ordering_collapsed(cx, span, tag_tuple) 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 eead8b37024c0..ca5ca29eb826a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -48,7 +48,7 @@ pub fn expand_deriving_partial_eq( None => cx.expr_bool(span, base), } }, - Box::new(|cx, span, _, _| cx.expr_bool(span, !base)), + Box::new(|cx, span, _| cx.expr_bool(span, !base)), cx, span, substr, @@ -69,11 +69,10 @@ pub fn expand_deriving_partial_eq( MethodDef { name: $name, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), sym::other)], - ret_ty: Literal(path_local!(bool)), + explicit_self: true, + args: vec![(self_ref(), sym::other)], + ret_ty: Path(path_local!(bool)), attributes: attrs, - is_unsafe: false, unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| $f(a, b, c))), } @@ -102,7 +101,6 @@ pub fn expand_deriving_partial_eq( path: path_std!(cmp::PartialEq), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods, associated_types: Vec::new(), 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 d28ac822a1ed9..07db82fee935b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -15,13 +15,9 @@ pub fn expand_deriving_partial_ord( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - let ordering_ty = Literal(path_std!(cmp::Ordering)); - let ret_ty = Literal(Path::new_( - pathvec_std!(option::Option), - None, - vec![Box::new(ordering_ty)], - PathKind::Std, - )); + let ordering_ty = Path(path_std!(cmp::Ordering)); + let ret_ty = + 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)]; @@ -29,11 +25,10 @@ pub fn expand_deriving_partial_ord( let partial_cmp_def = MethodDef { name: sym::partial_cmp, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), sym::other)], + explicit_self: true, + args: vec![(self_ref(), sym::other)], ret_ty, attributes: attrs, - is_unsafe: false, unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|cx, span, substr| { cs_partial_cmp(cx, span, substr) @@ -46,7 +41,6 @@ pub fn expand_deriving_partial_ord( path: path_std!(cmp::PartialOrd), additional_bounds: vec![], generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![partial_cmp_def], associated_types: Vec::new(), @@ -102,8 +96,8 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_ cx.expr_match(span, new, vec![eq_arm, neq_arm]) }, equals_expr, - Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| { - if self_args.len() != 2 { + Box::new(|cx, span, tag_tuple| { + if tag_tuple.len() != 2 { cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`") } else { let lft = cx.expr_addr_of(span, cx.expr_ident(span, tag_tuple[0])); diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 1fffd6f9727d7..1411c60c0bfd5 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -16,8 +16,7 @@ pub fn expand_deriving_debug( push: &mut dyn FnMut(Annotatable), ) { // &mut ::std::fmt::Formatter - let fmtr = - Ptr(Box::new(Literal(path_std!(fmt::Formatter))), Borrowed(None, ast::Mutability::Mut)); + let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut); let trait_def = TraitDef { span, @@ -25,16 +24,14 @@ pub fn expand_deriving_debug( path: path_std!(fmt::Debug), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::fmt, generics: Bounds::empty(), - explicit_self: borrowed_explicit_self(), + explicit_self: true, args: vec![(fmtr, sym::f)], - ret_ty: Literal(path_std!(fmt::Result)), + ret_ty: Path(path_std!(fmt::Result)), attributes: Vec::new(), - is_unsafe: false, unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|a, b, c| { show_substructure(a, b, c) @@ -64,8 +61,6 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> let (is_struct, args_per_field) = match vdata { ast::VariantData::Unit(..) => { // Special fast path for unit variants. - //let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); - //return cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]); assert!(fields.is_empty()); (false, 0) } diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index b39f35a9d4056..16154fb4d031b 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -23,40 +23,29 @@ pub fn expand_deriving_rustc_decodable( let trait_def = TraitDef { span, attributes: Vec::new(), - path: Path::new_(vec![krate, sym::Decodable], None, vec![], PathKind::Global), + path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::decode, generics: Bounds { bounds: vec![( typaram, - vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)], + vec![Path::new_(vec![krate, sym::Decoder], vec![], PathKind::Global)], )], }, - explicit_self: None, - args: vec![( - Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), - sym::d, - )], - ret_ty: Literal(Path::new_( + explicit_self: false, + args: vec![(Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut), sym::d)], + ret_ty: Path(Path::new_( pathvec_std!(result::Result), - None, vec![ Box::new(Self_), - Box::new(Literal(Path::new_( - vec![typaram, sym::Error], - None, - vec![], - PathKind::Local, - ))), + Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))), ], PathKind::Std, )), attributes: Vec::new(), - is_unsafe: false, 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 b49331e28753d..d41b25343b08e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -30,16 +30,14 @@ pub fn expand_deriving_default( path: Path::new(vec![kw::Default, sym::Default]), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: kw::Default, generics: Bounds::empty(), - explicit_self: None, + explicit_self: false, args: Vec::new(), ret_ty: Self_, attributes: attrs, - is_unsafe: false, unify_fieldless_variants: false, combine_substructure: combine_substructure(Box::new(|cx, trait_span, substr| { match substr.fields { diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index 6151a80a56d58..7dc0584618d66 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -108,40 +108,29 @@ pub fn expand_deriving_rustc_encodable( let trait_def = TraitDef { span, attributes: Vec::new(), - path: Path::new_(vec![krate, sym::Encodable], None, vec![], PathKind::Global), + path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::encode, generics: Bounds { bounds: vec![( typaram, - vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)], + vec![Path::new_(vec![krate, sym::Encoder], vec![], PathKind::Global)], )], }, - explicit_self: borrowed_explicit_self(), - args: vec![( - Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)), - sym::s, - )], - ret_ty: Literal(Path::new_( + explicit_self: true, + args: vec![(Ref(Box::new(Path(Path::new_local(typaram))), Mutability::Mut), sym::s)], + ret_ty: Path(Path::new_( pathvec_std!(result::Result), - None, vec![ - Box::new(Tuple(Vec::new())), - Box::new(Literal(Path::new_( - vec![typaram, sym::Error], - None, - vec![], - PathKind::Local, - ))), + Box::new(Unit), + Box::new(Path(Path::new_(vec![typaram, sym::Error], vec![], PathKind::Local))), ], PathKind::Std, )), attributes: Vec::new(), - is_unsafe: false, 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 8347cded2fe0b..ff431c8de5d3f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -146,8 +146,6 @@ //! //! ```{.text} //! EnumNonMatchingCollapsed( -//! vec![, ], -//! &[, ], //! &[, ]) //! ``` //! @@ -190,7 +188,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use ty::{Bounds, Path, Ptr, PtrTy, Self_, Ty}; +use ty::{Bounds, Path, Ref, Self_, Ty}; use crate::deriving; @@ -212,9 +210,6 @@ pub struct TraitDef<'a> { /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder` pub generics: Bounds, - /// Is it an `unsafe` trait? - pub is_unsafe: bool, - /// Can this trait be derived for unions? pub supports_unions: bool, @@ -229,10 +224,8 @@ pub struct MethodDef<'a> { /// List of generics, e.g., `R: rand::Rng` pub generics: Bounds, - /// Whether there is a self argument (outer Option) i.e., whether - /// this is a static function, and whether it is a pointer (inner - /// Option) - pub explicit_self: Option>, + /// Is there is a `&self` argument? If not, it is a static function. + pub explicit_self: bool, /// Arguments other than the self argument pub args: Vec<(Ty, Symbol)>, @@ -242,9 +235,6 @@ pub struct MethodDef<'a> { pub attributes: Vec, - // Is it an `unsafe fn`? - pub is_unsafe: bool, - /// Can we combine fieldless variants for enums into a single match arm? pub unify_fieldless_variants: bool, @@ -255,14 +245,7 @@ pub struct MethodDef<'a> { pub struct Substructure<'a> { /// ident of self pub type_ident: Ident, - /// ident of the method - pub method_ident: Ident, - /// dereferenced access to any [`Self_`] or [`Ptr(Self_, _)`][ptr] arguments - /// - /// [`Self_`]: ty::Ty::Self_ - /// [ptr]: ty::Ty::Ptr - pub self_args: &'a [P], - /// verbatim access to any other arguments + /// verbatim access to any non-self arguments pub nonself_args: &'a [P], pub fields: &'a SubstructureFields<'a>, } @@ -299,13 +282,10 @@ pub enum SubstructureFields<'a> { /// variant. EnumMatching(usize, usize, &'a ast::Variant, Vec>), - /// Non-matching variants of the enum, but with all state hidden from - /// the consequent code. The first component holds `Ident`s for all of - /// the `Self` arguments; the second component is a slice of all of the - /// variants for the enum itself, and the third component is a list of - /// `Ident`s bound to the variant index values for each of the actual - /// input `Self` arguments. - EnumNonMatchingCollapsed(Vec, &'a [ast::Variant], &'a [Ident]), + /// Non-matching variants of the enum, but with all state hidden from the + /// consequent code. The field is a list of `Ident`s bound to the variant + /// index values for each of the actual input `Self` arguments. + EnumNonMatchingCollapsed(&'a [Ident]), /// A static method where `Self` is a struct. StaticStruct(&'a ast::VariantData, StaticFields), @@ -318,13 +298,10 @@ pub enum SubstructureFields<'a> { pub type CombineSubstructureFunc<'a> = Box, Span, &Substructure<'_>) -> P + 'a>; -/// Deal with non-matching enum variants. The tuple is a list of -/// identifiers (one for each `Self` argument, which could be any of the -/// variants since they have been collapsed together) and the identifiers -/// holding the variant index value for each of the `Self` arguments. The -/// last argument is all the non-`Self` args of the method being derived. +/// Deal with non-matching enum variants. The slice is the identifiers holding +/// the variant index value for each of the `Self` arguments. pub type EnumNonMatchCollapsedFunc<'a> = - Box, Span, (&[Ident], &[Ident]), &[P]) -> P + 'a>; + Box, Span, &[Ident]) -> P + 'a>; pub fn combine_substructure( f: CombineSubstructureFunc<'_>, @@ -727,14 +704,12 @@ impl<'a> TraitDef<'a> { let mut a = vec![attr, unused_qual]; a.extend(self.attributes.iter().cloned()); - let unsafety = if self.is_unsafe { ast::Unsafe::Yes(self.span) } else { ast::Unsafe::No }; - cx.item( self.span, Ident::empty(), a, ast::ItemKind::Impl(Box::new(ast::Impl { - unsafety, + unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, constness: ast::Const::No, @@ -771,7 +746,6 @@ impl<'a> TraitDef<'a> { self, struct_def, type_ident, - &self_args, &nonself_args, ) } else { @@ -820,7 +794,6 @@ impl<'a> TraitDef<'a> { self, enum_def, type_ident, - &self_args, &nonself_args, ) } else { @@ -848,18 +821,11 @@ impl<'a> MethodDef<'a> { cx: &mut ExtCtxt<'_>, trait_: &TraitDef<'_>, type_ident: Ident, - self_args: &[P], nonself_args: &[P], fields: &SubstructureFields<'_>, ) -> P { let span = trait_.span; - let substructure = Substructure { - type_ident, - method_ident: Ident::new(self.name, span), - self_args, - nonself_args, - fields, - }; + let substructure = Substructure { type_ident, nonself_args, fields }; let mut f = self.combine_substructure.borrow_mut(); let f: &mut CombineSubstructureFunc<'_> = &mut *f; f(cx, span, &substructure) @@ -876,7 +842,7 @@ impl<'a> MethodDef<'a> { } fn is_static(&self) -> bool { - self.explicit_self.is_none() + !self.explicit_self } fn split_self_nonself_args( @@ -889,17 +855,15 @@ impl<'a> MethodDef<'a> { let mut self_args = Vec::new(); let mut nonself_args = Vec::new(); let mut arg_tys = Vec::new(); - let mut nonstatic = false; let span = trait_.span; - let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| { - let (self_expr, explicit_self) = ty::get_explicit_self(cx, span, self_ptr); - + let ast_explicit_self = if self.explicit_self { + let (self_expr, explicit_self) = ty::get_explicit_self(cx, span); self_args.push(self_expr); - nonstatic = true; - - explicit_self - }); + Some(explicit_self) + } else { + None + }; for (ty, name) in self.args.iter() { let ast_ty = ty.to_ty(cx, span, type_ident, generics); @@ -911,10 +875,10 @@ impl<'a> MethodDef<'a> { match *ty { // for static methods, just treat any Self // arguments as a normal arg - Self_ if nonstatic => { + Self_ if !self.is_static() => { self_args.push(arg_expr); } - Ptr(ref ty, _) if matches!(**ty, Self_) && nonstatic => { + Ref(ref ty, _) if matches!(**ty, Self_) && !self.is_static() => { self_args.push(cx.expr_deref(span, arg_expr)) } _ => { @@ -955,15 +919,9 @@ impl<'a> MethodDef<'a> { let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type)); let body_block = cx.block_expr(body); - let unsafety = if self.is_unsafe { ast::Unsafe::Yes(span) } else { ast::Unsafe::No }; - let trait_lo_sp = span.shrink_to_lo(); - let sig = ast::FnSig { - header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() }, - decl: fn_decl, - span, - }; + let sig = ast::FnSig { header: ast::FnHeader::default(), decl: fn_decl, span }; let defaultness = ast::Defaultness::Final; // Create the method. @@ -1083,7 +1041,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - self_args, nonself_args, &Struct(struct_def, fields), ); @@ -1104,7 +1061,6 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'_>, struct_def: &VariantData, type_ident: Ident, - self_args: &[P], nonself_args: &[P], ) -> P { let summary = trait_.summarise_struct(cx, struct_def); @@ -1113,7 +1069,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - self_args, nonself_args, &StaticStruct(struct_def, summary), ) @@ -1184,11 +1139,6 @@ impl<'a> MethodDef<'a> { ) .collect::>(); - let self_arg_idents = self_arg_names - .iter() - .map(|name| Ident::from_str_and_span(name, span)) - .collect::>(); - // The `vi_idents` will be bound, solely in the catch-all, to // a series of let statements mapping each self_arg to an int // value corresponding to its discriminant. @@ -1203,8 +1153,7 @@ impl<'a> MethodDef<'a> { // Builds, via callback to call_substructure_method, the // delegated expression that handles the catch-all case, // using `__variants_tuple` to drive logic if necessary. - let catch_all_substructure = - EnumNonMatchingCollapsed(self_arg_idents, &variants, &vi_idents); + let catch_all_substructure = EnumNonMatchingCollapsed(&vi_idents); let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty()); @@ -1303,7 +1252,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - &self_args[..], nonself_args, &substructure, ); @@ -1322,7 +1270,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - &self_args[..], nonself_args, &substructure, )) @@ -1393,7 +1340,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - &self_args[..], nonself_args, &catch_all_substructure, ); @@ -1491,7 +1437,6 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'_>, enum_def: &EnumDef, type_ident: Ident, - self_args: &[P], nonself_args: &[P], ) -> P { let summary = enum_def @@ -1507,7 +1452,6 @@ impl<'a> MethodDef<'a> { cx, trait_, type_ident, - self_args, nonself_args, &StaticEnum(enum_def, summary), ) @@ -1628,7 +1572,7 @@ impl<'a> TraitDef<'a> { // helpful premade recipes -pub fn cs_fold_fields<'a, F>( +fn cs_fold_fields<'a, F>( use_foldl: bool, mut f: F, base: P, @@ -1650,21 +1594,19 @@ where } } -pub fn cs_fold_enumnonmatch( +fn cs_fold_enumnonmatch( mut enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>, cx: &mut ExtCtxt<'_>, trait_span: Span, substructure: &Substructure<'_>, ) -> P { match *substructure.fields { - EnumNonMatchingCollapsed(ref all_args, _, tuple) => { - enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple), substructure.nonself_args) - } + EnumNonMatchingCollapsed(tuple) => enum_nonmatch_f(cx, trait_span, tuple), _ => cx.span_bug(trait_span, "cs_fold_enumnonmatch expected an EnumNonMatchingCollapsed"), } } -pub fn cs_fold_static(cx: &mut ExtCtxt<'_>, trait_span: Span) -> P { +fn cs_fold_static(cx: &mut ExtCtxt<'_>, trait_span: Span) -> P { cx.span_bug(trait_span, "static function in `derive`") } @@ -1717,22 +1659,21 @@ where { match *substructure.fields { EnumMatching(.., ref all_fields) | Struct(_, ref all_fields) => { - let (base, all_fields) = match (all_fields.is_empty(), use_foldl) { + let (base, rest) = match (all_fields.is_empty(), use_foldl) { (false, true) => { - let field = &all_fields[0]; - let args = (field.span, field.self_.clone(), &field.other[..]); - (b(cx, Some(args)), &all_fields[1..]) + let (first, rest) = all_fields.split_first().unwrap(); + let args = (first.span, first.self_.clone(), &first.other[..]); + (b(cx, Some(args)), rest) } (false, false) => { - let idx = all_fields.len() - 1; - let field = &all_fields[idx]; - let args = (field.span, field.self_.clone(), &field.other[..]); - (b(cx, Some(args)), &all_fields[..idx]) + let (last, rest) = all_fields.split_last().unwrap(); + let args = (last.span, last.self_.clone(), &last.other[..]); + (b(cx, Some(args)), rest) } (true, _) => (b(cx, None), &all_fields[..]), }; - cs_fold_fields(use_foldl, f, base, cx, all_fields) + cs_fold_fields(use_foldl, f, base, cx, rest) } EnumNonMatchingCollapsed(..) => { cs_fold_enumnonmatch(enum_nonmatch_f, cx, trait_span, substructure) diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 7a41800325084..4b20d87629d96 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -1,7 +1,6 @@ //! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use //! when specifying impls to be derived. -pub use PtrTy::*; pub use Ty::*; use rustc_ast::ptr::P; @@ -11,22 +10,11 @@ use rustc_span::source_map::{respan, DUMMY_SP}; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::Span; -/// The types of pointers -#[derive(Clone)] -pub enum PtrTy { - /// &'lifetime mut - Borrowed(Option, ast::Mutability), - /// *mut - #[allow(dead_code)] - Raw(ast::Mutability), -} - /// A path, e.g., `::std::option::Option::` (global). Has support -/// for type parameters and a lifetime. +/// for type parameters. #[derive(Clone)] pub struct Path { path: Vec, - lifetime: Option, params: Vec>, kind: PathKind, } @@ -40,18 +28,13 @@ pub enum PathKind { impl Path { pub fn new(path: Vec) -> Path { - Path::new_(path, None, Vec::new(), PathKind::Std) + Path::new_(path, Vec::new(), PathKind::Std) } pub fn new_local(path: Symbol) -> Path { - Path::new_(vec![path], None, Vec::new(), PathKind::Local) + Path::new_(vec![path], Vec::new(), PathKind::Local) } - pub fn new_( - path: Vec, - lifetime: Option, - params: Vec>, - kind: PathKind, - ) -> Path { - Path { path, lifetime, params, kind } + pub fn new_(path: Vec, params: Vec>, kind: PathKind) -> Path { + Path { path, params, kind } } pub fn to_ty( @@ -71,10 +54,8 @@ impl Path { self_generics: &Generics, ) -> ast::Path { let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect(); - let lt = mk_lifetimes(cx, span, &self.lifetime); let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)); - let params = - lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect(); + let params = tys.map(GenericArg::Type).collect(); match self.kind { PathKind::Global => cx.path_all(span, true, idents, params), @@ -92,40 +73,17 @@ impl Path { #[derive(Clone)] pub enum Ty { Self_, - /// &/Box/ Ty - Ptr(Box, PtrTy), + /// A reference. + Ref(Box, ast::Mutability), /// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type /// parameter, and things like `i32` - Literal(Path), - /// includes unit - Tuple(Vec), -} - -pub fn borrowed_ptrty() -> PtrTy { - Borrowed(None, ast::Mutability::Not) -} -pub fn borrowed(ty: Box) -> Ty { - Ptr(ty, borrowed_ptrty()) -} - -pub fn borrowed_explicit_self() -> Option> { - Some(Some(borrowed_ptrty())) -} - -pub fn borrowed_self() -> Ty { - borrowed(Box::new(Self_)) + Path(Path), + /// For () return types. + Unit, } -pub fn nil_ty() -> Ty { - Tuple(Vec::new()) -} - -fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option) -> Option { - lt.map(|ident| cx.lifetime(span, ident)) -} - -fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option) -> Vec { - mk_lifetime(cx, span, lt).into_iter().collect() +pub fn self_ref() -> Ty { + Ref(Box::new(Self_), ast::Mutability::Not) } impl Ty { @@ -136,23 +94,15 @@ impl Ty { self_ty: Ident, self_generics: &Generics, ) -> P { - match *self { - Ptr(ref ty, ref ptr) => { + match self { + Ref(ty, mutbl) => { let raw_ty = ty.to_ty(cx, span, self_ty, self_generics); - match *ptr { - Borrowed(ref lt, mutbl) => { - let lt = mk_lifetime(cx, span, lt); - cx.ty_rptr(span, raw_ty, lt, mutbl) - } - Raw(mutbl) => cx.ty_ptr(span, raw_ty, mutbl), - } + cx.ty_rptr(span, raw_ty, None, *mutbl) } - Literal(ref p) => p.to_ty(cx, span, self_ty, self_generics), + Path(p) => p.to_ty(cx, span, self_ty, self_generics), Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)), - Tuple(ref fields) => { - let ty = ast::TyKind::Tup( - fields.iter().map(|f| f.to_ty(cx, span, self_ty, self_generics)).collect(), - ); + Unit => { + let ty = ast::TyKind::Tup(vec![]); cx.ty(span, ty) } } @@ -185,9 +135,9 @@ impl Ty { cx.path_all(span, false, vec![self_ty], params) } - Literal(ref p) => p.to_path(cx, span, self_ty, generics), - Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"), - Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"), + Path(ref p) => p.to_path(cx, span, self_ty, generics), + Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"), + Unit => cx.span_bug(span, "unit in a path in generic `derive`"), } } } @@ -245,28 +195,10 @@ impl Bounds { } } -pub fn get_explicit_self( - cx: &ExtCtxt<'_>, - span: Span, - self_ptr: &Option, -) -> (P, ast::ExplicitSelf) { +pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P, ast::ExplicitSelf) { // this constructs a fresh `self` path let self_path = cx.expr_self(span); - match *self_ptr { - None => (self_path, respan(span, SelfKind::Value(ast::Mutability::Not))), - Some(ref ptr) => { - let self_ty = respan( - span, - match *ptr { - Borrowed(ref lt, mutbl) => { - let lt = lt.map(|s| cx.lifetime(span, s)); - SelfKind::Region(lt, mutbl) - } - Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition"), - }, - ); - let self_expr = cx.expr_deref(span, self_path); - (self_expr, self_ty) - } - } + let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not)); + let self_expr = cx.expr_deref(span, self_path); + (self_expr, self_ty) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index f1d46f03bad8f..9790449c4b331 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -15,7 +15,7 @@ pub fn expand_deriving_hash( item: &Annotatable, push: &mut dyn FnMut(Annotatable), ) { - let path = Path::new_(pathvec_std!(hash::Hash), None, vec![], PathKind::Std); + let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std); let typaram = sym::__H; @@ -26,16 +26,14 @@ pub fn expand_deriving_hash( path, additional_bounds: Vec::new(), generics: Bounds::empty(), - is_unsafe: false, supports_unions: false, methods: vec![MethodDef { name: sym::hash, generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] }, - explicit_self: borrowed_explicit_self(), - args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), sym::state)], - ret_ty: nil_ty(), + explicit_self: true, + args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)], + ret_ty: Unit, attributes: vec![], - is_unsafe: false, unify_fieldless_variants: true, combine_substructure: combine_substructure(Box::new(|a, b, c| { hash_substructure(a, b, c)