syntax: Simplify deriving to handle classes that take generics, like Encodable
This commit is contained in:
parent
419f6acf0e
commit
f50a8e2833
4 changed files with 28 additions and 34 deletions
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue