syntax: Simplify deriving to handle classes that take generics, like Encodable

This commit is contained in:
Erick Tryzelaar 2013-04-08 09:02:36 -07:00
parent 419f6acf0e
commit f50a8e2833
4 changed files with 28 additions and 34 deletions

View file

@ -17,6 +17,7 @@ use ext::build;
use ext::deriving::*;
use codemap::{span, spanned};
use ast_util;
use opt_vec;
use core::uint;
@ -48,12 +49,13 @@ fn create_derived_clone_impl(cx: @ext_ctxt,
method: @method)
-> @item {
let methods = [ method ];
let trait_path = [
let trait_path = ~[
cx.ident_of(~"core"),
cx.ident_of(~"clone"),
cx.ident_of(~"Clone"),
];
create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
let trait_path = build::mk_raw_path_global(span, trait_path);
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty)
}
// Creates a method from the given expression conforming to the signature of
// the `clone` method.

View file

@ -17,6 +17,7 @@ use ext::build;
use ext::deriving::*;
use codemap::{span, spanned};
use ast_util;
use opt_vec;
use core::uint;
@ -124,12 +125,13 @@ fn create_derived_eq_impl(cx: @ext_ctxt,
ne_method: @method)
-> @item {
let methods = [ eq_method, ne_method ];
let trait_path = [
let trait_path = ~[
cx.ident_of(~"core"),
cx.ident_of(~"cmp"),
cx.ident_of(~"Eq")
];
create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
let trait_path = build::mk_raw_path_global(span, trait_path);
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty)
}
fn call_substructure_eq_method(cx: @ext_ctxt,

View file

@ -17,6 +17,7 @@ use ext::build;
use ext::deriving::*;
use codemap::{span, spanned};
use ast_util;
use opt_vec;
use core::uint;
@ -49,12 +50,13 @@ fn create_derived_iter_bytes_impl(cx: @ext_ctxt,
method: @method)
-> @item {
let methods = [ method ];
let trait_path = [
let trait_path = ~[
cx.ident_of(~"core"),
cx.ident_of(~"to_bytes"),
cx.ident_of(~"IterBytes")
];
create_derived_impl(cx, span, type_ident, generics, methods, trait_path)
let trait_path = build::mk_raw_path_global(span, trait_path);
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty)
}
// Creates a method from the given set of statements conforming to the

View file

@ -14,7 +14,7 @@
use core::prelude::*;
use ast;
use ast::{TraitTyParamBound, Ty, bind_by_ref, deref, enum_def};
use ast::{Ty, bind_by_ref, deref, enum_def};
use ast::{expr, expr_match, ident, item, item_};
use ast::{item_enum, item_impl, item_struct, Generics};
use ast::{m_imm, meta_item, method};
@ -153,12 +153,13 @@ pub fn create_self_type_with_params(cx: @ext_ctxt,
}
pub fn create_derived_impl(cx: @ext_ctxt,
span: span,
type_ident: ident,
generics: &Generics,
methods: &[@method],
trait_path: &[ident])
-> @item {
span: span,
type_ident: ident,
generics: &Generics,
methods: &[@method],
trait_path: @ast::Path,
mut impl_ty_params: opt_vec::OptVec<ast::TyParam>)
-> @item {
/*!
*
* Given that we are deriving a trait `Tr` for a type `T<'a, ...,
@ -175,29 +176,16 @@ pub fn create_derived_impl(cx: @ext_ctxt,
build::mk_lifetime(cx, l.span, l.ident)
});
// Create the type parameters.
let impl_ty_params = generics.ty_params.map(|ty_param| {
let bound = build::mk_trait_ref_global(cx,
span,
trait_path.map(|x| *x));
let bounds = @opt_vec::with(TraitTyParamBound(bound));
build::mk_ty_param(cx, ty_param.ident, bounds)
});
// Create the reference to the trait.
let trait_path = ast::Path {
span: span,
global: true,
idents: trait_path.map(|x| *x),
rp: None,
types: ~[]
let trait_ref = build::mk_trait_ref_(cx, trait_path);
// Create the type parameters.
for generics.ty_params.each |ty_param| {
let bounds = @opt_vec::with(
build::mk_trait_ty_param_bound_(cx, trait_path)
);
impl_ty_params.push(build::mk_ty_param(cx, ty_param.ident, bounds));
};
let trait_path = @trait_path;
let trait_ref = ast::trait_ref {
path: trait_path,
ref_id: cx.next_id()
};
let trait_ref = @trait_ref;
// Create the type of `self`.
let self_type = create_self_type_with_params(cx,