Simplify pointer handling.
The existing derive code allows for various possibilities that aren't needed in practice, which complicates the code. There are only a few auto-derived traits and new ones are unlikely, so this commit simplifies things. - `PtrTy` has been eliminated. The `Raw` variant was never used, and the lifetime for the `Borrowed` variant was always `None`. That left just the mutability field, which has been inlined as necessary. - `MethodDef::explicit_self` was a confusing `Option<Option<PtrTy>>`. Indicating either `&self` or nothing. It's now a `bool`. - `borrowed_self` is renamed as `self_ref`. - `Ty::Ptr` is renamed to `Ty::Ref`.
This commit is contained in:
parent
78ec19ffe6
commit
b94246693a
12 changed files with 43 additions and 100 deletions
|
@ -79,7 +79,7 @@ pub fn expand_deriving_clone(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: sym::clone,
|
name: sym::clone,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: Vec::new(),
|
args: Vec::new(),
|
||||||
ret_ty: Self_,
|
ret_ty: Self_,
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn expand_deriving_eq(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: sym::assert_receiver_is_total_eq,
|
name: sym::assert_receiver_is_total_eq,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![],
|
args: vec![],
|
||||||
ret_ty: nil_ty(),
|
ret_ty: nil_ty(),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
|
|
|
@ -27,8 +27,8 @@ pub fn expand_deriving_ord(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: sym::cmp,
|
name: sym::cmp,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(borrowed_self(), sym::other)],
|
args: vec![(self_ref(), sym::other)],
|
||||||
ret_ty: Literal(path_std!(cmp::Ordering)),
|
ret_ty: Literal(path_std!(cmp::Ordering)),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
unify_fieldless_variants: true,
|
unify_fieldless_variants: true,
|
||||||
|
|
|
@ -69,8 +69,8 @@ pub fn expand_deriving_partial_eq(
|
||||||
MethodDef {
|
MethodDef {
|
||||||
name: $name,
|
name: $name,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(borrowed_self(), sym::other)],
|
args: vec![(self_ref(), sym::other)],
|
||||||
ret_ty: Literal(path_local!(bool)),
|
ret_ty: Literal(path_local!(bool)),
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
unify_fieldless_variants: true,
|
unify_fieldless_variants: true,
|
||||||
|
|
|
@ -29,8 +29,8 @@ pub fn expand_deriving_partial_ord(
|
||||||
let partial_cmp_def = MethodDef {
|
let partial_cmp_def = MethodDef {
|
||||||
name: sym::partial_cmp,
|
name: sym::partial_cmp,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(borrowed_self(), sym::other)],
|
args: vec![(self_ref(), sym::other)],
|
||||||
ret_ty,
|
ret_ty,
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
unify_fieldless_variants: true,
|
unify_fieldless_variants: true,
|
||||||
|
|
|
@ -16,8 +16,7 @@ pub fn expand_deriving_debug(
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
// &mut ::std::fmt::Formatter
|
// &mut ::std::fmt::Formatter
|
||||||
let fmtr =
|
let fmtr = Ref(Box::new(Literal(path_std!(fmt::Formatter))), ast::Mutability::Mut);
|
||||||
Ptr(Box::new(Literal(path_std!(fmt::Formatter))), Borrowed(None, ast::Mutability::Mut));
|
|
||||||
|
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
|
@ -29,7 +28,7 @@ pub fn expand_deriving_debug(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: sym::fmt,
|
name: sym::fmt,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(fmtr, sym::f)],
|
args: vec![(fmtr, sym::f)],
|
||||||
ret_ty: Literal(path_std!(fmt::Result)),
|
ret_ty: Literal(path_std!(fmt::Result)),
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
|
|
|
@ -35,11 +35,8 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)],
|
vec![Path::new_(vec![krate, sym::Decoder], None, vec![], PathKind::Global)],
|
||||||
)],
|
)],
|
||||||
},
|
},
|
||||||
explicit_self: None,
|
explicit_self: false,
|
||||||
args: vec![(
|
args: vec![(Ref(Box::new(Literal(Path::new_local(typaram))), Mutability::Mut), sym::d)],
|
||||||
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
|
||||||
sym::d,
|
|
||||||
)],
|
|
||||||
ret_ty: Literal(Path::new_(
|
ret_ty: Literal(Path::new_(
|
||||||
pathvec_std!(result::Result),
|
pathvec_std!(result::Result),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub fn expand_deriving_default(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: kw::Default,
|
name: kw::Default,
|
||||||
generics: Bounds::empty(),
|
generics: Bounds::empty(),
|
||||||
explicit_self: None,
|
explicit_self: false,
|
||||||
args: Vec::new(),
|
args: Vec::new(),
|
||||||
ret_ty: Self_,
|
ret_ty: Self_,
|
||||||
attributes: attrs,
|
attributes: attrs,
|
||||||
|
|
|
@ -120,11 +120,8 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)],
|
vec![Path::new_(vec![krate, sym::Encoder], None, vec![], PathKind::Global)],
|
||||||
)],
|
)],
|
||||||
},
|
},
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(
|
args: vec![(Ref(Box::new(Literal(Path::new_local(typaram))), Mutability::Mut), sym::s)],
|
||||||
Ptr(Box::new(Literal(Path::new_local(typaram))), Borrowed(None, Mutability::Mut)),
|
|
||||||
sym::s,
|
|
||||||
)],
|
|
||||||
ret_ty: Literal(Path::new_(
|
ret_ty: Literal(Path::new_(
|
||||||
pathvec_std!(result::Result),
|
pathvec_std!(result::Result),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -188,7 +188,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use ty::{Bounds, Path, Ptr, PtrTy, Self_, Ty};
|
use ty::{Bounds, Path, Ref, Self_, Ty};
|
||||||
|
|
||||||
use crate::deriving;
|
use crate::deriving;
|
||||||
|
|
||||||
|
@ -224,10 +224,8 @@ pub struct MethodDef<'a> {
|
||||||
/// List of generics, e.g., `R: rand::Rng`
|
/// List of generics, e.g., `R: rand::Rng`
|
||||||
pub generics: Bounds,
|
pub generics: Bounds,
|
||||||
|
|
||||||
/// Whether there is a self argument (outer Option) i.e., whether
|
/// Is there is a `&self` argument? If not, it is a static function.
|
||||||
/// this is a static function, and whether it is a pointer (inner
|
pub explicit_self: bool,
|
||||||
/// Option)
|
|
||||||
pub explicit_self: Option<Option<PtrTy>>,
|
|
||||||
|
|
||||||
/// Arguments other than the self argument
|
/// Arguments other than the self argument
|
||||||
pub args: Vec<(Ty, Symbol)>,
|
pub args: Vec<(Ty, Symbol)>,
|
||||||
|
@ -844,7 +842,7 @@ impl<'a> MethodDef<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_static(&self) -> bool {
|
fn is_static(&self) -> bool {
|
||||||
self.explicit_self.is_none()
|
!self.explicit_self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_self_nonself_args(
|
fn split_self_nonself_args(
|
||||||
|
@ -857,17 +855,15 @@ impl<'a> MethodDef<'a> {
|
||||||
let mut self_args = Vec::new();
|
let mut self_args = Vec::new();
|
||||||
let mut nonself_args = Vec::new();
|
let mut nonself_args = Vec::new();
|
||||||
let mut arg_tys = Vec::new();
|
let mut arg_tys = Vec::new();
|
||||||
let mut nonstatic = false;
|
|
||||||
let span = trait_.span;
|
let span = trait_.span;
|
||||||
|
|
||||||
let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| {
|
let ast_explicit_self = if self.explicit_self {
|
||||||
let (self_expr, explicit_self) = ty::get_explicit_self(cx, span, self_ptr);
|
let (self_expr, explicit_self) = ty::get_explicit_self(cx, span);
|
||||||
|
|
||||||
self_args.push(self_expr);
|
self_args.push(self_expr);
|
||||||
nonstatic = true;
|
Some(explicit_self)
|
||||||
|
} else {
|
||||||
explicit_self
|
None
|
||||||
});
|
};
|
||||||
|
|
||||||
for (ty, name) in self.args.iter() {
|
for (ty, name) in self.args.iter() {
|
||||||
let ast_ty = ty.to_ty(cx, span, type_ident, generics);
|
let ast_ty = ty.to_ty(cx, span, type_ident, generics);
|
||||||
|
@ -879,10 +875,10 @@ impl<'a> MethodDef<'a> {
|
||||||
match *ty {
|
match *ty {
|
||||||
// for static methods, just treat any Self
|
// for static methods, just treat any Self
|
||||||
// arguments as a normal arg
|
// arguments as a normal arg
|
||||||
Self_ if nonstatic => {
|
Self_ if !self.is_static() => {
|
||||||
self_args.push(arg_expr);
|
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))
|
self_args.push(cx.expr_deref(span, arg_expr))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
|
//! 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.
|
//! when specifying impls to be derived.
|
||||||
|
|
||||||
pub use PtrTy::*;
|
|
||||||
pub use Ty::*;
|
pub use Ty::*;
|
||||||
|
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
@ -11,16 +10,6 @@ use rustc_span::source_map::{respan, DUMMY_SP};
|
||||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
/// The types of pointers
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum PtrTy {
|
|
||||||
/// &'lifetime mut
|
|
||||||
Borrowed(Option<Ident>, ast::Mutability),
|
|
||||||
/// *mut
|
|
||||||
#[allow(dead_code)]
|
|
||||||
Raw(ast::Mutability),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
|
/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
|
||||||
/// for type parameters and a lifetime.
|
/// for type parameters and a lifetime.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -92,8 +81,8 @@ impl Path {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Ty {
|
pub enum Ty {
|
||||||
Self_,
|
Self_,
|
||||||
/// &/Box/ Ty
|
/// A reference.
|
||||||
Ptr(Box<Ty>, PtrTy),
|
Ref(Box<Ty>, ast::Mutability),
|
||||||
/// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
|
/// `mod::mod::Type<[lifetime], [Params...]>`, including a plain type
|
||||||
/// parameter, and things like `i32`
|
/// parameter, and things like `i32`
|
||||||
Literal(Path),
|
Literal(Path),
|
||||||
|
@ -101,19 +90,8 @@ pub enum Ty {
|
||||||
Tuple(Vec<Ty>),
|
Tuple(Vec<Ty>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn borrowed_ptrty() -> PtrTy {
|
pub fn self_ref() -> Ty {
|
||||||
Borrowed(None, ast::Mutability::Not)
|
Ref(Box::new(Self_), ast::Mutability::Not)
|
||||||
}
|
|
||||||
pub fn borrowed(ty: Box<Ty>) -> Ty {
|
|
||||||
Ptr(ty, borrowed_ptrty())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
|
|
||||||
Some(Some(borrowed_ptrty()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn borrowed_self() -> Ty {
|
|
||||||
borrowed(Box::new(Self_))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nil_ty() -> Ty {
|
pub fn nil_ty() -> Ty {
|
||||||
|
@ -136,20 +114,14 @@ impl Ty {
|
||||||
self_ty: Ident,
|
self_ty: Ident,
|
||||||
self_generics: &Generics,
|
self_generics: &Generics,
|
||||||
) -> P<ast::Ty> {
|
) -> P<ast::Ty> {
|
||||||
match *self {
|
match self {
|
||||||
Ptr(ref ty, ref ptr) => {
|
Ref(ty, mutbl) => {
|
||||||
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
|
let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
|
||||||
match *ptr {
|
cx.ty_rptr(span, raw_ty, None, *mutbl)
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Literal(ref p) => p.to_ty(cx, span, self_ty, self_generics),
|
Literal(p) => p.to_ty(cx, span, self_ty, self_generics),
|
||||||
Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
|
Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
|
||||||
Tuple(ref fields) => {
|
Tuple(fields) => {
|
||||||
let ty = ast::TyKind::Tup(
|
let ty = ast::TyKind::Tup(
|
||||||
fields.iter().map(|f| f.to_ty(cx, span, self_ty, self_generics)).collect(),
|
fields.iter().map(|f| f.to_ty(cx, span, self_ty, self_generics)).collect(),
|
||||||
);
|
);
|
||||||
|
@ -186,7 +158,7 @@ impl Ty {
|
||||||
cx.path_all(span, false, vec![self_ty], params)
|
cx.path_all(span, false, vec![self_ty], params)
|
||||||
}
|
}
|
||||||
Literal(ref p) => p.to_path(cx, span, self_ty, generics),
|
Literal(ref p) => p.to_path(cx, span, self_ty, generics),
|
||||||
Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
|
Ref(..) => cx.span_bug(span, "ref in a path in generic `derive`"),
|
||||||
Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
|
Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,28 +217,10 @@ impl Bounds {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_explicit_self(
|
pub fn get_explicit_self(cx: &ExtCtxt<'_>, span: Span) -> (P<Expr>, ast::ExplicitSelf) {
|
||||||
cx: &ExtCtxt<'_>,
|
|
||||||
span: Span,
|
|
||||||
self_ptr: &Option<PtrTy>,
|
|
||||||
) -> (P<Expr>, ast::ExplicitSelf) {
|
|
||||||
// this constructs a fresh `self` path
|
// this constructs a fresh `self` path
|
||||||
let self_path = cx.expr_self(span);
|
let self_path = cx.expr_self(span);
|
||||||
match *self_ptr {
|
let self_ty = respan(span, SelfKind::Region(None, ast::Mutability::Not));
|
||||||
None => (self_path, respan(span, SelfKind::Value(ast::Mutability::Not))),
|
let self_expr = cx.expr_deref(span, self_path);
|
||||||
Some(ref ptr) => {
|
(self_expr, self_ty)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ pub fn expand_deriving_hash(
|
||||||
methods: vec![MethodDef {
|
methods: vec![MethodDef {
|
||||||
name: sym::hash,
|
name: sym::hash,
|
||||||
generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
|
generics: Bounds { bounds: vec![(typaram, vec![path_std!(hash::Hasher)])] },
|
||||||
explicit_self: borrowed_explicit_self(),
|
explicit_self: true,
|
||||||
args: vec![(Ptr(Box::new(Literal(arg)), Borrowed(None, Mutability::Mut)), sym::state)],
|
args: vec![(Ref(Box::new(Literal(arg)), Mutability::Mut), sym::state)],
|
||||||
ret_ty: nil_ty(),
|
ret_ty: nil_ty(),
|
||||||
attributes: vec![],
|
attributes: vec![],
|
||||||
unify_fieldless_variants: true,
|
unify_fieldless_variants: true,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue