syntax: Move the AST from @T to Gc<T>
This commit is contained in:
parent
531ed3d599
commit
53ad426e92
41 changed files with 1269 additions and 1158 deletions
|
@ -178,6 +178,7 @@ StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span
|
|||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
|
||||
use ast;
|
||||
use ast::{P, EnumDef, Expr, Ident, Generics, StructDef};
|
||||
|
@ -248,9 +249,9 @@ pub struct Substructure<'a> {
|
|||
/// ident of the method
|
||||
pub method_ident: Ident,
|
||||
/// dereferenced access to any Self or Ptr(Self, _) arguments
|
||||
pub self_args: &'a [@Expr],
|
||||
pub self_args: &'a [Gc<Expr>],
|
||||
/// verbatim access to any other arguments
|
||||
pub nonself_args: &'a [@Expr],
|
||||
pub nonself_args: &'a [Gc<Expr>],
|
||||
pub fields: &'a SubstructureFields<'a>
|
||||
}
|
||||
|
||||
|
@ -262,42 +263,43 @@ pub struct FieldInfo {
|
|||
pub name: Option<Ident>,
|
||||
/// The expression corresponding to this field of `self`
|
||||
/// (specifically, a reference to it).
|
||||
pub self_: @Expr,
|
||||
pub self_: Gc<Expr>,
|
||||
/// The expressions corresponding to references to this field in
|
||||
/// the other Self arguments.
|
||||
pub other: Vec<@Expr>,
|
||||
pub other: Vec<Gc<Expr>>,
|
||||
}
|
||||
|
||||
/// Fields for a static method
|
||||
pub enum StaticFields {
|
||||
/// Tuple structs/enum variants like this
|
||||
Unnamed(Vec<Span> ),
|
||||
Unnamed(Vec<Span>),
|
||||
/// Normal structs/struct variants.
|
||||
Named(Vec<(Ident, Span)> )
|
||||
Named(Vec<(Ident, Span)>),
|
||||
}
|
||||
|
||||
/// A summary of the possible sets of fields. See above for details
|
||||
/// and examples
|
||||
pub enum SubstructureFields<'a> {
|
||||
Struct(Vec<FieldInfo> ),
|
||||
Struct(Vec<FieldInfo>),
|
||||
/**
|
||||
Matching variants of the enum: variant index, ast::Variant,
|
||||
fields: the field name is only non-`None` in the case of a struct
|
||||
variant.
|
||||
*/
|
||||
EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo> ),
|
||||
EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo>),
|
||||
|
||||
/**
|
||||
non-matching variants of the enum, [(variant index, ast::Variant,
|
||||
[field span, field ident, fields])] \(i.e. all fields for self are in the
|
||||
first tuple, for other1 are in the second tuple, etc.)
|
||||
*/
|
||||
EnumNonMatching(&'a [(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )]),
|
||||
EnumNonMatching(&'a [(uint, P<ast::Variant>,
|
||||
Vec<(Span, Option<Ident>, Gc<Expr>)>)]),
|
||||
|
||||
/// A static method where Self is a struct.
|
||||
StaticStruct(&'a ast::StructDef, StaticFields),
|
||||
/// A static method where Self is an enum.
|
||||
StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)> )
|
||||
StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,7 +309,7 @@ Combine the values of all the fields together. The last argument is
|
|||
all the fields of all the structures, see above for details.
|
||||
*/
|
||||
pub type CombineSubstructureFunc<'a> =
|
||||
|&mut ExtCtxt, Span, &Substructure|: 'a -> @Expr;
|
||||
|&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
|
||||
|
||||
/**
|
||||
Deal with non-matching enum variants, the arguments are a list
|
||||
|
@ -317,9 +319,9 @@ representing each variant: (variant index, ast::Variant instance,
|
|||
pub type EnumNonMatchFunc<'a> =
|
||||
|&mut ExtCtxt,
|
||||
Span,
|
||||
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )],
|
||||
&[@Expr]|: 'a
|
||||
-> @Expr;
|
||||
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
|
||||
&[Gc<Expr>]|: 'a
|
||||
-> Gc<Expr>;
|
||||
|
||||
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
|
||||
-> RefCell<CombineSubstructureFunc<'a>> {
|
||||
|
@ -330,13 +332,13 @@ pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
|
|||
impl<'a> TraitDef<'a> {
|
||||
pub fn expand(&self,
|
||||
cx: &mut ExtCtxt,
|
||||
_mitem: @ast::MetaItem,
|
||||
item: @ast::Item,
|
||||
push: |@ast::Item|) {
|
||||
_mitem: Gc<ast::MetaItem>,
|
||||
item: Gc<ast::Item>,
|
||||
push: |Gc<ast::Item>|) {
|
||||
let newitem = match item.node {
|
||||
ast::ItemStruct(struct_def, ref generics) => {
|
||||
ast::ItemStruct(ref struct_def, ref generics) => {
|
||||
self.expand_struct_def(cx,
|
||||
struct_def,
|
||||
&**struct_def,
|
||||
item.ident,
|
||||
generics)
|
||||
}
|
||||
|
@ -357,7 +359,7 @@ impl<'a> TraitDef<'a> {
|
|||
_ => false,
|
||||
}
|
||||
}).map(|a| a.clone()));
|
||||
push(@ast::Item {
|
||||
push(box(GC) ast::Item {
|
||||
attrs: attrs,
|
||||
..(*newitem).clone()
|
||||
})
|
||||
|
@ -379,7 +381,7 @@ impl<'a> TraitDef<'a> {
|
|||
cx: &mut ExtCtxt,
|
||||
type_ident: Ident,
|
||||
generics: &Generics,
|
||||
methods: Vec<@ast::Method> ) -> @ast::Item {
|
||||
methods: Vec<Gc<ast::Method>> ) -> Gc<ast::Item> {
|
||||
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
|
||||
|
||||
let Generics { mut lifetimes, ty_params } =
|
||||
|
@ -435,7 +437,7 @@ impl<'a> TraitDef<'a> {
|
|||
// Just mark it now since we know that it'll end up used downstream
|
||||
attr::mark_used(&attr);
|
||||
let opt_trait_ref = Some(trait_ref);
|
||||
let ident = ast_util::impl_pretty_name(&opt_trait_ref, self_type);
|
||||
let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
|
||||
cx.item(
|
||||
self.span,
|
||||
ident,
|
||||
|
@ -448,7 +450,7 @@ impl<'a> TraitDef<'a> {
|
|||
cx: &mut ExtCtxt,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics) -> @ast::Item {
|
||||
generics: &Generics) -> Gc<ast::Item> {
|
||||
let methods = self.methods.iter().map(|method_def| {
|
||||
let (explicit_self, self_args, nonself_args, tys) =
|
||||
method_def.split_self_nonself_args(
|
||||
|
@ -484,7 +486,7 @@ impl<'a> TraitDef<'a> {
|
|||
cx: &mut ExtCtxt,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics) -> @ast::Item {
|
||||
generics: &Generics) -> Gc<ast::Item> {
|
||||
let methods = self.methods.iter().map(|method_def| {
|
||||
let (explicit_self, self_args, nonself_args, tys) =
|
||||
method_def.split_self_nonself_args(cx, self,
|
||||
|
@ -522,10 +524,10 @@ impl<'a> MethodDef<'a> {
|
|||
cx: &mut ExtCtxt,
|
||||
trait_: &TraitDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr],
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>],
|
||||
fields: &SubstructureFields)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
let substructure = Substructure {
|
||||
type_ident: type_ident,
|
||||
method_ident: cx.ident_of(self.name),
|
||||
|
@ -556,7 +558,8 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
type_ident: Ident,
|
||||
generics: &Generics)
|
||||
-> (ast::ExplicitSelf, Vec<@Expr> , Vec<@Expr> , Vec<(Ident, P<ast::Ty>)> ) {
|
||||
-> (ast::ExplicitSelf, Vec<Gc<Expr>>, Vec<Gc<Expr>>,
|
||||
Vec<(Ident, P<ast::Ty>)>) {
|
||||
|
||||
let mut self_args = Vec::new();
|
||||
let mut nonself_args = Vec::new();
|
||||
|
@ -608,7 +611,7 @@ impl<'a> MethodDef<'a> {
|
|||
generics: &Generics,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
arg_types: Vec<(Ident, P<ast::Ty>)> ,
|
||||
body: @Expr) -> @ast::Method {
|
||||
body: Gc<Expr>) -> Gc<ast::Method> {
|
||||
// create the generics that aren't for Self
|
||||
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
|
||||
|
||||
|
@ -630,7 +633,7 @@ impl<'a> MethodDef<'a> {
|
|||
let body_block = cx.block_expr(body);
|
||||
|
||||
// Create the method.
|
||||
@ast::Method {
|
||||
box(GC) ast::Method {
|
||||
ident: method_ident,
|
||||
attrs: self.attributes.clone(),
|
||||
generics: fn_generics,
|
||||
|
@ -670,9 +673,9 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
|
||||
let mut raw_fields = Vec::new(); // ~[[fields of self],
|
||||
// [fields of next Self arg], [etc]]
|
||||
|
@ -737,9 +740,9 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
struct_def: &StructDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let summary = trait_.summarise_struct(cx, struct_def);
|
||||
|
||||
self.call_substructure_method(cx,
|
||||
|
@ -780,9 +783,9 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let mut matches = Vec::new();
|
||||
self.build_enum_match(cx, trait_, enum_def, type_ident,
|
||||
self_args, nonself_args,
|
||||
|
@ -816,12 +819,12 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr],
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>],
|
||||
matching: Option<uint>,
|
||||
matches_so_far: &mut Vec<(uint, P<ast::Variant>,
|
||||
Vec<(Span, Option<Ident>, @Expr)> )> ,
|
||||
match_count: uint) -> @Expr {
|
||||
Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
|
||||
match_count: uint) -> Gc<Expr> {
|
||||
if match_count == self_args.len() {
|
||||
// we've matched against all arguments, so make the final
|
||||
// expression at the bottom of the match tree
|
||||
|
@ -871,7 +874,7 @@ impl<'a> MethodDef<'a> {
|
|||
other: (*other).clone()
|
||||
}
|
||||
}).collect();
|
||||
EnumMatching(variant_index, variant, field_tuples)
|
||||
EnumMatching(variant_index, &*variant, field_tuples)
|
||||
}
|
||||
None => {
|
||||
EnumNonMatching(matches_so_far.as_slice())
|
||||
|
@ -905,7 +908,7 @@ impl<'a> MethodDef<'a> {
|
|||
let variant = *enum_def.variants.get(index);
|
||||
let (pattern, idents) = trait_.create_enum_variant_pattern(
|
||||
cx,
|
||||
variant,
|
||||
&*variant,
|
||||
current_match_str.as_slice(),
|
||||
ast::MutImmutable);
|
||||
|
||||
|
@ -938,7 +941,7 @@ impl<'a> MethodDef<'a> {
|
|||
let (pattern, idents) =
|
||||
trait_.create_enum_variant_pattern(
|
||||
cx,
|
||||
variant,
|
||||
&*variant,
|
||||
current_match_str.as_slice(),
|
||||
ast::MutImmutable);
|
||||
|
||||
|
@ -974,17 +977,17 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef,
|
||||
enum_def: &EnumDef,
|
||||
type_ident: Ident,
|
||||
self_args: &[@Expr],
|
||||
nonself_args: &[@Expr])
|
||||
-> @Expr {
|
||||
self_args: &[Gc<Expr>],
|
||||
nonself_args: &[Gc<Expr>])
|
||||
-> Gc<Expr> {
|
||||
let summary = enum_def.variants.iter().map(|v| {
|
||||
let ident = v.node.name;
|
||||
let summary = match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
Unnamed(args.iter().map(|va| trait_.set_expn_info(cx, va.ty.span)).collect())
|
||||
}
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
trait_.summarise_struct(cx, struct_def)
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
trait_.summarise_struct(cx, &**struct_def)
|
||||
}
|
||||
};
|
||||
(ident, v.span, summary)
|
||||
|
@ -1009,7 +1012,7 @@ impl<'a> TraitDef<'a> {
|
|||
None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"),
|
||||
Some(name) => *name
|
||||
};
|
||||
to_set.expn_info = Some(@codemap::ExpnInfo {
|
||||
to_set.expn_info = Some(box(GC) codemap::ExpnInfo {
|
||||
call_site: to_set,
|
||||
callee: codemap::NameAndSpan {
|
||||
name: format!("deriving({})", trait_name).to_string(),
|
||||
|
@ -1048,7 +1051,7 @@ impl<'a> TraitDef<'a> {
|
|||
cx: &mut ExtCtxt,
|
||||
field_paths: Vec<ast::Path> ,
|
||||
mutbl: ast::Mutability)
|
||||
-> Vec<@ast::Pat> {
|
||||
-> Vec<Gc<ast::Pat>> {
|
||||
field_paths.iter().map(|path| {
|
||||
cx.pat(path.span,
|
||||
ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None))
|
||||
|
@ -1061,7 +1064,7 @@ impl<'a> TraitDef<'a> {
|
|||
struct_def: &StructDef,
|
||||
prefix: &str,
|
||||
mutbl: ast::Mutability)
|
||||
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) {
|
||||
-> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)>) {
|
||||
if struct_def.fields.is_empty() {
|
||||
return (
|
||||
cx.pat_ident_binding_mode(
|
||||
|
@ -1126,7 +1129,7 @@ impl<'a> TraitDef<'a> {
|
|||
variant: &ast::Variant,
|
||||
prefix: &str,
|
||||
mutbl: ast::Mutability)
|
||||
-> (@ast::Pat, Vec<(Span, Option<Ident>, @Expr)> ) {
|
||||
-> (Gc<ast::Pat>, Vec<(Span, Option<Ident>, Gc<Expr>)> ) {
|
||||
let variant_ident = variant.node.name;
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref variant_args) => {
|
||||
|
@ -1159,8 +1162,8 @@ impl<'a> TraitDef<'a> {
|
|||
(cx.pat_enum(variant.span, matching_path, subpats),
|
||||
ident_expr)
|
||||
}
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
self.create_struct_pattern(cx, variant_ident, struct_def,
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
self.create_struct_pattern(cx, variant_ident, &**struct_def,
|
||||
prefix, mutbl)
|
||||
}
|
||||
}
|
||||
|
@ -1174,13 +1177,13 @@ Fold the fields. `use_foldl` controls whether this is done
|
|||
left-to-right (`true`) or right-to-left (`false`).
|
||||
*/
|
||||
pub fn cs_fold(use_foldl: bool,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr, &[@Expr]| -> @Expr,
|
||||
base: @Expr,
|
||||
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
|
||||
base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
if use_foldl {
|
||||
|
@ -1221,12 +1224,12 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
|
|||
~~~
|
||||
*/
|
||||
#[inline]
|
||||
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<@Expr> | -> @Expr,
|
||||
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
match *substructure.fields {
|
||||
EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
|
||||
// call self_n.method(other_1_n, other_2_n, ...)
|
||||
|
@ -1257,13 +1260,13 @@ fields. `use_foldl` controls whether this is done left-to-right
|
|||
*/
|
||||
#[inline]
|
||||
pub fn cs_same_method_fold(use_foldl: bool,
|
||||
f: |&mut ExtCtxt, Span, @Expr, @Expr| -> @Expr,
|
||||
base: @Expr,
|
||||
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
|
||||
base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt,
|
||||
trait_span: Span,
|
||||
substructure: &Substructure)
|
||||
-> @Expr {
|
||||
-> Gc<Expr> {
|
||||
cs_same_method(
|
||||
|cx, span, vals| {
|
||||
if use_foldl {
|
||||
|
@ -1285,10 +1288,10 @@ Use a given binop to combine the result of calling the derived method
|
|||
on all the fields.
|
||||
*/
|
||||
#[inline]
|
||||
pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
||||
pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
|
||||
enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, trait_span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_same_method_fold(
|
||||
true, // foldl is good enough
|
||||
|cx, span, old, new| {
|
||||
|
@ -1306,7 +1309,7 @@ pub fn cs_binop(binop: ast::BinOp, base: @Expr,
|
|||
#[inline]
|
||||
pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_binop(ast::BiOr, cx.expr_bool(span, false),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
|
@ -1316,7 +1319,7 @@ pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
|
|||
#[inline]
|
||||
pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
|
||||
cx: &mut ExtCtxt, span: Span,
|
||||
substructure: &Substructure) -> @Expr {
|
||||
substructure: &Substructure) -> Gc<Expr> {
|
||||
cs_binop(ast::BiAnd, cx.expr_bool(span, true),
|
||||
enum_nonmatch_f,
|
||||
cx, span, substructure)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue