rustc: Implement typechecking for tuple structs. r=nmatsakis
This commit is contained in:
parent
61bb3571a5
commit
4da58a5bd6
@ -1444,6 +1444,31 @@ enum struct_field_kind {
|
||||
unnamed_field // element of a tuple-like struct
|
||||
}
|
||||
|
||||
impl struct_field_kind : cmp::Eq {
|
||||
pure fn eq(other: &struct_field_kind) -> bool {
|
||||
match self {
|
||||
named_field(ident_a, class_mutability_a, visibility_a) => {
|
||||
match *other {
|
||||
named_field(ident_b, class_mutability_b, visibility_b)
|
||||
=> {
|
||||
ident_a == ident_b &&
|
||||
class_mutability_a == class_mutability_b &&
|
||||
visibility_a == visibility_b
|
||||
}
|
||||
unnamed_field => false
|
||||
}
|
||||
}
|
||||
unnamed_field => {
|
||||
match *other {
|
||||
named_field(*) => false,
|
||||
unnamed_field => true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pure fn ne(other: &struct_field_kind) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
#[auto_serialize]
|
||||
#[auto_deserialize]
|
||||
type struct_def = {
|
||||
@ -1452,7 +1477,10 @@ type struct_def = {
|
||||
methods: ~[@method], /* methods */
|
||||
/* (not including ctor or dtor) */
|
||||
/* dtor is optional */
|
||||
dtor: Option<class_dtor>
|
||||
dtor: Option<class_dtor>,
|
||||
/* ID of the constructor. This is only used for tuple- or enum-like
|
||||
* structs. */
|
||||
ctor_id: node_id
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -280,7 +280,8 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold)
|
||||
traits: vec::map(struct_def.traits, |p| fold_trait_ref(*p, fld)),
|
||||
fields: vec::map(struct_def.fields, |f| fold_struct_field(*f, fld)),
|
||||
methods: vec::map(struct_def.methods, |m| fld.fold_method(*m)),
|
||||
dtor: dtor
|
||||
dtor: dtor,
|
||||
ctor_id: fld.new_id(struct_def.ctor_id)
|
||||
};
|
||||
}
|
||||
|
||||
@ -563,7 +564,8 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|
||||
|f| fld.fold_struct_field(*f)),
|
||||
methods: vec::map(struct_def.methods,
|
||||
|m| fld.fold_method(*m)),
|
||||
dtor: dtor
|
||||
dtor: dtor,
|
||||
ctor_id: fld.new_id(struct_def.ctor_id)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2722,12 +2722,14 @@ impl Parser {
|
||||
self_id: self.get_id(),
|
||||
body: d_body},
|
||||
span: d_s}};
|
||||
let _ = self.get_id(); // XXX: Workaround for crazy bug.
|
||||
(class_name,
|
||||
item_class(@{
|
||||
traits: traits,
|
||||
fields: move fields,
|
||||
methods: move methods,
|
||||
dtor: actual_dtor
|
||||
dtor: actual_dtor,
|
||||
ctor_id: self.get_id()
|
||||
}, ty_params),
|
||||
None)
|
||||
}
|
||||
@ -3073,7 +3075,8 @@ impl Parser {
|
||||
traits: ~[],
|
||||
fields: move fields,
|
||||
methods: move methods,
|
||||
dtor: actual_dtor
|
||||
dtor: actual_dtor,
|
||||
ctor_id: self.get_id()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,7 @@ use middle::pat_util::{pat_bindings};
|
||||
use syntax::ast::{_mod, add, arm};
|
||||
use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
|
||||
use syntax::ast::{bitand, bitor, bitxor};
|
||||
use syntax::ast::{binding_mode, blk,
|
||||
capture_clause, class_ctor, class_dtor};
|
||||
use syntax::ast::{binding_mode, blk, capture_clause, class_ctor, class_dtor};
|
||||
use syntax::ast::{crate, crate_num, decl_item};
|
||||
use syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
|
||||
use syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod};
|
||||
@ -39,7 +38,7 @@ use syntax::ast::{trait_ref, tuple_variant_kind, Ty, ty_bool, ty_char};
|
||||
use syntax::ast::{ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16, ty_i32};
|
||||
use syntax::ast::{ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str, ty_u};
|
||||
use syntax::ast::{ty_u16, ty_u32, ty_u64, ty_u8, ty_uint, type_value_ns};
|
||||
use syntax::ast::{ty_param_bound};
|
||||
use syntax::ast::{ty_param_bound, unnamed_field};
|
||||
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
|
||||
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
|
||||
use syntax::ast::{view_path_simple, visibility, anonymous, named};
|
||||
@ -1179,12 +1178,22 @@ impl Resolver {
|
||||
}
|
||||
|
||||
// These items live in both the type and value namespaces.
|
||||
item_class(*) => {
|
||||
item_class(struct_def, _) => {
|
||||
let (name_bindings, new_parent) =
|
||||
self.add_child(ident, parent, ForbidDuplicateTypes, sp);
|
||||
|
||||
(*name_bindings).define_type
|
||||
(privacy, def_ty(local_def(item.id)), sp);
|
||||
name_bindings.define_type(
|
||||
privacy, def_ty(local_def(item.id)), sp);
|
||||
|
||||
// If this struct is tuple-like or enum-like, define a name
|
||||
// in the value namespace.
|
||||
if struct_def.fields.len() == 0 ||
|
||||
struct_def.fields[0].node.kind == unnamed_field {
|
||||
name_bindings.define_value(
|
||||
privacy,
|
||||
def_class(local_def(struct_def.ctor_id)),
|
||||
sp);
|
||||
}
|
||||
|
||||
// Record the def ID of this struct.
|
||||
self.structs.insert(local_def(item.id), ());
|
||||
|
@ -22,6 +22,7 @@ are represented as `ty_param()` instances.
|
||||
|
||||
use astconv::{ast_conv, ty_of_fn_decl, ty_of_arg, ast_ty_to_ty};
|
||||
use ast_util::trait_method_to_ty_method;
|
||||
use middle::ty::{FnMeta, FnSig, FnTyBase};
|
||||
use rscope::*;
|
||||
use ty::{FnTyBase, FnMeta, FnSig, InstantiatedTraitRef};
|
||||
use util::common::pluralize;
|
||||
@ -559,6 +560,39 @@ fn convert_struct(ccx: @crate_ctxt,
|
||||
write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
|
||||
tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
|
||||
}
|
||||
|
||||
// If this struct is enum-like or tuple-like, create the type of its
|
||||
// constructor.
|
||||
if struct_def.fields.len() == 0 {
|
||||
// Enum-like.
|
||||
write_ty_to_tcx(tcx, struct_def.ctor_id, selfty);
|
||||
tcx.tcache.insert(local_def(struct_def.ctor_id), tpt);
|
||||
} else if struct_def.fields[0].node.kind == ast::unnamed_field {
|
||||
// Tuple-like.
|
||||
let ctor_fn_ty = ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {
|
||||
purity: ast::pure_fn,
|
||||
proto: ty::proto_bare,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val,
|
||||
},
|
||||
sig: FnSig {
|
||||
inputs: do struct_def.fields.map |field| {
|
||||
{
|
||||
mode: ast::expl(ast::by_copy),
|
||||
ty: ccx.tcx.tcache.get(local_def(field.node.id)).ty
|
||||
}
|
||||
},
|
||||
output: selfty
|
||||
}
|
||||
});
|
||||
write_ty_to_tcx(tcx, struct_def.ctor_id, ctor_fn_ty);
|
||||
tcx.tcache.insert(local_def(struct_def.ctor_id), {
|
||||
bounds: tpt.bounds,
|
||||
region_param: tpt.region_param,
|
||||
ty: ctor_fn_ty
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
|
||||
|
Loading…
Reference in New Issue
Block a user