提交 4e3dbfe0 编写于 作者: P Patrick Walton

librustc: Remove structural record types from the compiler

上级 239e6424
......@@ -299,16 +299,6 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t {
let v = parse_vstore(st);
return ty::mk_estr(st.tcx, v);
}
'R' => {
assert (next(st) == '[');
let mut fields: ~[ty::field] = ~[];
while peek(st) != ']' {
let name = st.tcx.sess.ident_of(parse_str(st, '='));
fields.push(ty::field { ident: name, mt: parse_mt(st, conv) });
}
st.pos = st.pos + 1u;
return ty::mk_rec(st.tcx, fields);
}
'T' => {
assert (next(st) == '[');
let mut params = ~[];
......
......@@ -283,15 +283,6 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
enc_vstore(w, cx, v);
}
ty::ty_unboxed_vec(mt) => { w.write_char('U'); enc_mt(w, cx, mt); }
ty::ty_rec(fields) => {
w.write_str(&"R[");
for fields.each |field| {
w.write_str(*cx.tcx.sess.str_of(field.ident));
w.write_char('=');
enc_mt(w, cx, field.mt);
}
w.write_char(']');
}
ty::ty_closure(ref f) => {
w.write_char('f');
enc_closure_ty(w, cx, f);
......
......@@ -352,7 +352,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt,
-> Option<ctor> {
match ty::get(left_ty).sty {
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) | ty::ty_tup(_) |
ty::ty_rec(_) | ty::ty_struct(*) => {
ty::ty_struct(*) => {
for m.each |r| {
if !is_wild(cx, r[0]) { return None; }
}
......@@ -449,7 +449,6 @@ pub fn missing_ctor(cx: @MatchCheckCtxt,
pub fn ctor_arity(cx: @MatchCheckCtxt, ctor: ctor, ty: ty::t) -> uint {
match /*bad*/copy ty::get(ty).sty {
ty::ty_tup(fs) => fs.len(),
ty::ty_rec(fs) => fs.len(),
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_rptr(*) => 1u,
ty::ty_enum(eid, _) => {
let id = match ctor { variant(id) => id,
......@@ -548,19 +547,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
_ => None
}
}
pat_rec(ref flds, _) => {
let ty_flds = match /*bad*/copy ty::get(left_ty).sty {
ty::ty_rec(flds) => flds,
_ => fail!(~"bad type for pat_rec")
};
let args = vec::map(ty_flds, |ty_fld| {
match flds.find(|f| f.ident == ty_fld.ident) {
Some(f) => f.pat,
_ => wild()
}
});
Some(vec::append(args, vec::from_slice(r.tail())))
}
pat_rec(ref flds, _) => fail!(),
pat_struct(_, ref flds, _) => {
// Is this a struct or an enum variant?
match cx.tcx.def_map.get(&pat_id) {
......
......@@ -1114,15 +1114,8 @@ pub fn field_mutbl(tcx: ty::ctxt,
f_name: ast::ident,
node_id: ast::node_id)
-> Option<ast::mutability> {
// Need to refactor so that records/class fields can be treated uniformly.
// Need to refactor so that struct/enum fields can be treated uniformly.
match /*bad*/copy ty::get(base_ty).sty {
ty::ty_rec(fields) => {
for fields.each |f| {
if f.ident == f_name {
return Some(f.mt.mutbl);
}
}
}
ty::ty_struct(did, _) => {
for ty::lookup_struct_fields(tcx, did).each |fld| {
if fld.ident == f_name {
......
......@@ -480,7 +480,6 @@ fn use_expr(&self,
// then `with` is consumed, otherwise it is only read
let with_ty = ty::expr_ty(self.tcx, *with_expr);
let with_fields = match ty::get(with_ty).sty {
ty::ty_rec(ref f) => copy *f,
ty::ty_struct(did, ref substs) => {
ty::struct_fields(self.tcx, did, substs)
}
......
......@@ -729,12 +729,6 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
visit_mt(mt, cx, visitor);
}
ast::ty_rec(ref fields) => {
for (*fields).each |field| {
visit_mt(field.node.mt, cx, visitor);
}
}
ast::ty_path(path, _) => {
// type parameters are---for now, anyway---always invariant
do cx.with_ambient_variance(rv_invariant) {
......
......@@ -11,10 +11,10 @@
/*!
* # Representation of Algebraic Data Types
*
* This module determines how to represent enums, structs, tuples, and
* (deprecated) structural records based on their monomorphized types;
* it is responsible both for choosing a representation and
* translating basic operations on values of those types.
* This module determines how to represent enums, structs, and tuples
* based on their monomorphized types; it is responsible both for
* choosing a representation and translating basic operations on
* values of those types.
*
* Note that the interface treats everything as a general case of an
* enum, so structs/tuples/etc. have one pseudo-variant with
......@@ -131,11 +131,6 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
ty::ty_tup(ref elems) => {
Univariant(mk_struct(cx, *elems), NonStruct)
}
ty::ty_rec(ref fields) => {
// XXX: Are these in the right order?
Univariant(mk_struct(cx, fields.map(|f| f.mt.ty)),
StructWithoutDtor)
}
ty::ty_struct(def_id, ref substs) => {
let fields = ty::lookup_struct_fields(cx.tcx, def_id);
let dt = ty::ty_dtor(cx.tcx, def_id).is_present();
......
......@@ -639,7 +639,7 @@ fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef,
let mut cx = cx;
match /*bad*/copy ty::get(t).sty {
ty::ty_rec(*) | ty::ty_struct(*) => {
ty::ty_struct(*) => {
let repr = adt::represent_type(cx.ccx(), t);
do expr::with_field_tys(cx.tcx(), t, None) |discr, field_tys| {
for vec::eachi(field_tys) |i, field_ty| {
......
......@@ -473,33 +473,6 @@ fn add_member(cx: @mut StructCtxt,
cx.total_size += size * 8;
}
fn create_record(cx: @CrateContext, t: ty::t, fields: ~[ast::ty_field],
span: span) -> @Metadata<TyDescMetadata> {
let fname = filename_from_span(cx, span);
let file_node = create_file(cx, fname);
let scx = create_structure(file_node,
cx.sess.str_of(
((/*bad*/copy cx.dbg_cx).get().names)
(~"rec")),
line_from_span(cx.sess.codemap,
span) as int);
for fields.each |field| {
let field_t = ty::get_field(cx.tcx, t, field.node.ident).mt.ty;
let ty_md = create_ty(cx, field_t, field.node.mt.ty);
let (size, align) = size_and_align_of(cx, field_t);
add_member(scx, *cx.sess.str_of(field.node.ident),
line_from_span(cx.sess.codemap, field.span) as int,
size as int, align as int, ty_md.node);
}
let mdval = @Metadata {
node: finish_structure(scx),
data: TyDescMetadata {
hash: ty::type_id(t)
}
};
return mdval;
}
fn create_boxed_type(cx: @CrateContext, outer: ty::t, _inner: ty::t,
span: span, boxed: @Metadata<TyDescMetadata>)
-> @Metadata<TyDescMetadata> {
......@@ -628,16 +601,6 @@ fn t_to_ty(cx: CrateContext, t: ty::t, span: span) -> @ast::ty {
mutbl: mt.mutbl}) }
ty::ty_uniq(mt) { ast::ty_uniq({ty: t_to_ty(cx, mt.ty, span),
mutbl: mt.mutbl}) }
ty::ty_rec(fields) {
let fs = ~[];
for field in fields {
fs.push({node: {ident: field.ident,
mt: {ty: t_to_ty(cx, field.mt.ty, span),
mutbl: field.mt.mutbl}},
span: span});
}
ast::ty_rec(fs)
}
ty::ty_vec(mt) { ast::ty_vec({ty: t_to_ty(cx, mt.ty, span),
mutbl: mt.mutbl}) }
_ {
......@@ -673,10 +636,6 @@ fn t_to_ty(cx: CrateContext, t: ty::t, span: span) -> @ast::ty {
return create_ty(cx, t, inferred);
}
ast::ty_rec(fields) {
return create_record(cx, t, fields, ty.span);
}
ast::ty_vec(mt) {
let inner_t = ty::sequence_element_type(cx.tcx, t);
let inner_ast_t = t_to_ty(cx, inner_t, mt.ty.span);
......
......@@ -1141,10 +1141,6 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
node_id_opt: Option<ast::node_id>,
op: fn(int, (&[ty::field])) -> R) -> R {
match ty::get(ty).sty {
ty::ty_rec(ref fields) => {
op(0, *fields)
}
ty::ty_struct(did, ref substs) => {
op(0, struct_mutable_fields(tcx, did, substs))
}
......
......@@ -200,20 +200,6 @@ fn visit_ty(&mut self, t: ty::t) {
self.visit(~"rptr", extra)
}
ty::ty_rec(fields) => {
let extra = ~[self.c_uint(vec::len(fields))]
+ self.c_size_and_align(t);
do self.bracketed(~"rec", extra) |this| {
for fields.eachi |i, field| {
let extra = ~[this.c_uint(i),
this.c_slice(
bcx.ccx().sess.str_of(field.ident))]
+ this.c_mt(field.mt);
this.visit(~"rec_field", extra);
}
}
}
ty::ty_tup(tys) => {
let extra = ~[self.c_uint(vec::len(tys))]
+ self.c_size_and_align(t);
......
......@@ -142,8 +142,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_unboxed_vec(mt) => T_vec(cx, sizing_type_of(cx, mt.ty)),
ty::ty_tup(*) | ty::ty_rec(*) | ty::ty_struct(*)
| ty::ty_enum(*) => {
ty::ty_tup(*) | ty::ty_struct(*) | ty::ty_enum(*) => {
let repr = adt::represent_type(cx, t);
T_struct(adt::sizing_fields_of(cx, repr))
}
......@@ -240,7 +239,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
ty::ty_type => T_ptr(cx.tydesc_type),
ty::ty_tup(*) | ty::ty_rec(*) => {
ty::ty_tup(*) => {
let repr = adt::represent_type(cx, t);
T_struct(adt::fields_of(cx, repr))
}
......
......@@ -506,7 +506,6 @@ pub enum sty {
ty_evec(mt, vstore),
ty_ptr(mt),
ty_rptr(Region, mt),
ty_rec(~[field]),
ty_bare_fn(BareFnTy),
ty_closure(ClosureTy),
ty_trait(def_id, substs, vstore),
......@@ -899,7 +898,6 @@ fn sflags(substs: &substs) -> uint {
flags |= rflags(r);
flags |= get(m.ty).flags;
}
&ty_rec(ref flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; },
&ty_tup(ref ts) => for ts.each |tt| { flags |= get(*tt).flags; },
&ty_bare_fn(ref f) => {
for f.sig.inputs.each |a| { flags |= get(a.ty).flags; }
......@@ -1028,8 +1026,6 @@ pub fn mk_mut_unboxed_vec(cx: ctxt, ty: t) -> t {
mk_t(cx, ty_unboxed_vec(mt {ty: ty, mutbl: ast::m_imm}))
}
pub fn mk_rec(cx: ctxt, +fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) }
pub fn mk_tup(cx: ctxt, +ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
pub fn mk_closure(cx: ctxt, +fty: ClosureTy) -> t {
......@@ -1163,9 +1159,6 @@ pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
ty_trait(_, ref substs, _) => {
for (*substs).tps.each |subty| { maybe_walk_ty(*subty, f); }
}
ty_rec(fields) => {
for fields.each |fl| { maybe_walk_ty(fl.mt.ty, f); }
}
ty_tup(ts) => { for ts.each |tt| { maybe_walk_ty(*tt, f); } }
ty_bare_fn(ref ft) => {
for ft.sig.inputs.each |a| { maybe_walk_ty(a.ty, f); }
......@@ -1223,14 +1216,6 @@ fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
ty_trait(did, ref substs, vst) => {
ty_trait(did, fold_substs(substs, fldop), vst)
}
ty_rec(fields) => {
let new_fields = do vec::map(fields) |fl| {
let new_ty = fldop(fl.mt.ty);
let new_mt = mt { ty: new_ty, mutbl: fl.mt.mutbl };
field { ident: fl.ident, mt: new_mt }
};
ty_rec(new_fields)
}
ty_tup(ts) => {
let new_ts = vec::map(ts, |tt| fldop(*tt));
ty_tup(new_ts)
......@@ -1478,9 +1463,7 @@ pub fn type_is_bool(ty: t) -> bool { get(ty).sty == ty_bool }
pub fn type_is_structural(ty: t) -> bool {
match get(ty).sty {
ty_rec(_) | ty_struct(*) | ty_tup(_) | ty_enum(*) |
ty_closure(_) |
ty_trait(*) |
ty_struct(*) | ty_tup(_) | ty_enum(*) | ty_closure(_) | ty_trait(*) |
ty_evec(_, vstore_fixed(_)) | ty_estr(vstore_fixed(_)) |
ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_))
=> true,
......@@ -1513,7 +1496,6 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t {
pub fn get_element_type(ty: t, i: uint) -> t {
match /*bad*/copy get(ty).sty {
ty_rec(flds) => return flds[i].mt.ty,
ty_tup(ts) => return ts[i],
_ => fail!(~"get_element_type called on invalid type")
}
......@@ -1639,9 +1621,8 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
encountered_box = true;
true
}
ty_nil | ty_bot | ty_bool |
ty_int(_) | ty_uint(_) | ty_float(_) |
ty_rec(_) | ty_tup(_) | ty_ptr(_) => {
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_tup(_) | ty_ptr(_) => {
true
}
ty_enum(did, ref substs) => {
......@@ -1962,12 +1943,6 @@ fn tc_ty(cx: ctxt,
TC_NONE
}
ty_rec(ref flds) => {
flds.foldl(
TC_NONE,
|tc, f| tc + tc_mt(cx, f.mt, cache))
}
ty_struct(did, ref substs) => {
let flds = struct_fields(cx, did, substs);
let flds_tc = flds.foldl(
......@@ -2151,10 +2126,6 @@ fn type_size(cx: ctxt, ty: t) -> uint {
n
}
ty_rec(flds) => {
flds.foldl(0, |s, f| *s + type_size(cx, f.mt.ty))
}
ty_struct(did, ref substs) => {
let flds = struct_fields(cx, did, substs);
flds.foldl(0, |s, f| *s + type_size(cx, f.mt.ty))
......@@ -2253,12 +2224,6 @@ fn subtypes_require(cx: ctxt, seen: @mut ~[def_id],
false // unsafe ptrs can always be NULL
}
ty_rec(fields) => {
do vec::any(fields) |field| {
type_requires(cx, seen, r_ty, field.mt.ty)
}
}
ty_trait(_, _, _) => {
false
}
......@@ -2327,14 +2292,6 @@ pub fn type_structurally_contains(cx: ctxt,
}
return false;
}
ty_rec(fields) => {
for fields.each |field| {
if type_structurally_contains(cx, field.mt.ty, test) {
return true;
}
}
return false;
}
ty_struct(did, ref substs) => {
for lookup_struct_fields(cx, did).each |field| {
let ft = lookup_field_type(cx, did, field.id, substs);
......@@ -2423,11 +2380,6 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
if !type_is_pod(cx, tup_ty) { result = false; }
}
}
ty_rec(flds) => {
for flds.each |f| {
if !type_is_pod(cx, f.mt.ty) { result = false; }
}
}
ty_tup(elts) => {
for elts.each |elt| { if !type_is_pod(cx, *elt) { result = false; } }
}
......@@ -2675,9 +2627,6 @@ impl to_bytes::IterBytes for sty {
ty_tup(ref ts) =>
to_bytes::iter_bytes_2(&10u8, ts, lsb0, f),
ty_rec(ref fs) =>
to_bytes::iter_bytes_2(&11u8, fs, lsb0, f),
ty_bare_fn(ref ft) =>
to_bytes::iter_bytes_2(&12u8, ft, lsb0, f),
......@@ -3220,23 +3169,6 @@ pub fn field_idx_strict(tcx: ty::ctxt, id: ast::ident, fields: &[field])
fields.map(|f| tcx.sess.str_of(f.ident))));
}
pub fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field {
match vec::find(get_fields(rec_ty), |f| f.ident == id) {
Some(f) => f,
// Do we only call this when we know the field is legit?
None => fail!(fmt!("get_field: ty doesn't have a field %s",
*tcx.sess.str_of(id)))
}
}
pub fn get_fields(rec_ty:t) -> ~[field] {
match /*bad*/copy get(rec_ty).sty {
ty_rec(fields) => fields,
// Can we check at the caller?
_ => fail!(~"get_fields: not a record type")
}
}
pub fn method_idx(id: ast::ident, meths: &[method]) -> Option<uint> {
let mut i = 0u;
for meths.each |m| { if m.ident == id { return Some(i); } i += 1u; }
......@@ -3376,7 +3308,6 @@ pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
ty_unboxed_vec(_) => ~"unboxed vector",
ty_ptr(_) => ~"*-ptr",
ty_rptr(_, _) => ~"&-ptr",
ty_rec(_) => ~"record",
ty_bare_fn(_) => ~"extern fn",
ty_closure(_) => ~"fn",
ty_trait(id, _, _) => fmt!("trait %s", item_path_str(cx, id)),
......@@ -4141,7 +4072,7 @@ fn tycat(ty: t) -> int {
ty_bool => tycat_bool,
ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
ty_rec(_) | ty_tup(_) | ty_enum(_, _) => tycat_struct,
ty_tup(_) | ty_enum(_, _) => tycat_struct,
ty_bot => tycat_bot,
_ => tycat_other
}
......
......@@ -336,13 +336,6 @@ fn check_path_args(tcx: ty::ctxt,
let flds = vec::map(fields, |t| ast_ty_to_ty(self, rscope, *t));
ty::mk_tup(tcx, flds)
}
ast::ty_rec(ref fields) => {
let flds = do (*fields).map |f| {
let tm = ast_mt_to_mt(self, rscope, f.node.mt);
field {ident: f.node.ident, mt: tm}
};
ty::mk_rec(tcx, flds)
}
ast::ty_bare_fn(ref bf) => {
ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity,
bf.abi, &bf.decl))
......
......@@ -415,39 +415,10 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
check_pat_variant(pcx, pat, path, subpats, expected);
}
ast::pat_rec(fields, etc) => {
let ex_fields = match structure_of(fcx, pat.span, expected) {
ty::ty_rec(fields) => fields,
_ => {
tcx.sess.span_fatal
(pat.span,
fmt!("mismatched types: expected `%s` but found record",
fcx.infcx().ty_to_str(expected)));
}
};
let f_count = vec::len(fields);
let ex_f_count = vec::len(ex_fields);
if ex_f_count < f_count || !etc && ex_f_count > f_count {
tcx.sess.span_fatal
(pat.span, fmt!("mismatched types: expected a record \
with %u fields, found one with %u \
fields",
ex_f_count, f_count));
}
for fields.each |f| {
match vec::find(ex_fields, |a| f.ident == a.ident) {
Some(field) => {
check_pat(pcx, f.pat, field.mt.ty);
}
None => {
tcx.sess.span_fatal(pat.span,
fmt!("mismatched types: did not \
expect a record with a field `%s`",
*tcx.sess.str_of(f.ident)));
}
}
}
fcx.write_ty(pat.id, expected);
tcx.sess.span_fatal
(pat.span,
fmt!("mismatched types: expected `%s` but found record",
fcx.infcx().ty_to_str(expected)));
}
ast::pat_struct(path, fields, etc) => {
// Grab the class data that we care about.
......
......@@ -907,9 +907,8 @@ fn search_for_autoptrd_method(
ty_infer(FloatVar(_)) |
ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool |
ty_int(*) | ty_uint(*) |
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_rec(*) |
ty_struct(*) | ty_tup(*) | ty_estr(*) | ty_evec(*) |
ty_trait(*) | ty_closure(*) => {
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_struct(*) | ty_tup(*) |
ty_estr(*) | ty_evec(*) | ty_trait(*) | ty_closure(*) => {
self.search_for_some_kind_of_autorefd_method(
AutoPtr, autoderefs, [m_const, m_imm, m_mutbl],
|m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m}))
......
......@@ -606,14 +606,6 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
ast::item_ty(t, ref generics) => {
let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty);
// If this is a record ty, check for duplicate fields
match t.node {
ast::ty_rec(ref fields) => {
check_no_duplicate_fields(ccx.tcx, (*fields).map(|f|
(f.node.ident, f.span)));
}
_ => ()
}
}
ast::item_foreign_mod(m) => {
if syntax::attr::foreign_abi(it.attrs) ==
......@@ -1698,22 +1690,6 @@ fn check_field(fcx: @mut FnCtxt,
let n_tys = tys.len();
match structure_of(fcx, expr.span, base_t) {
ty::ty_rec(fields) => {
match ty::field_idx(field, fields) {
Some(ix) => {
if n_tys > 0 {
tcx.sess.span_err(
expr.span,
~"can't provide type parameters \
to a field access");
}
fcx.write_ty(expr.id, fields[ix].mt.ty);
fcx.write_autoderef_adjustment(base.id, derefs);
return bot;
}
_ => ()
}
}
ty::ty_struct(base_id, ref substs) => {
// This is just for fields -- the same code handles
// methods in both classes and traits
......@@ -2533,71 +2509,7 @@ fn types_compatible(fcx: @mut FnCtxt, sp: span, t1: ty::t,
fcx.write_ty(id, typ);
}
ast::expr_rec(ref fields, base) => {
for base.each |b| { check_expr_with_opt_hint(fcx, *b, expected); }
let expected = option::or(expected,
base.map(|b| fcx.expr_ty(*b)));
let flds = unpack_expected(fcx, expected, |sty|
match *sty {
ty::ty_rec(ref flds) => Some(copy *flds),
_ => None
}
);
let fields_t = fields.map(|f| {
let hint_mt =
flds.chain_ref(
|flds| vec::find(*flds, |tf| tf.ident == f.node.ident));
let hint = hint_mt.map(|tf| tf.mt.ty);
bot |= check_expr_with_opt_hint(fcx, f.node.expr, hint);
let expr_t = fcx.expr_ty(f.node.expr);
let expr_mt = ty::mt {ty: expr_t, mutbl: f.node.mutbl};
// for the most precise error message,
// should be f.node.expr.span, not f.span
respan(f.node.expr.span, field {ident: f.node.ident, mt: expr_mt})
});
match base {
None => {
fn get_node(f: &spanned<field>) -> field { f.node }
let typ = ty::mk_rec(tcx, vec::map(fields_t, get_node));
fcx.write_ty(id, typ);
/* Check for duplicate fields */
/* Only do this check if there's no base expr -- the reason is
that we're extending a record we know has no dup fields, and
it would be ill-typed anyway if we duplicated one of its
fields */
check_no_duplicate_fields(tcx, (*fields).map(|f|
(f.node.ident, f.span)));
}
Some(bexpr) => {
let bexpr_t = fcx.expr_ty(bexpr);
let base_fields = match structure_of(fcx, expr.span, bexpr_t) {
ty::ty_rec(flds) => flds,
_ => {
fcx.type_error_message(expr.span, |_actual| {
~"record update has non-record base"
}, bexpr_t, None);
fcx.write_ty(id, ty::mk_err(tcx));
return true;
}
};
fcx.write_ty(id, bexpr_t);
for fields_t.each |f| {
let mut found = false;
for base_fields.each |bf| {
if f.node.ident == bf.ident {
demand::suptype(fcx, f.span, bf.mt.ty, f.node.mt.ty);
found = true;
}
}
if !found {
tcx.sess.span_err(f.span,
~"unknown field in record update: " +
*tcx.sess.str_of(f.node.ident));
fcx.write_ty(id, ty::mk_err(tcx));
return true;
}
}
}
}
fail!()
}
ast::expr_struct(path, ref fields, base_expr) => {
// Resolve the path.
......
......@@ -28,7 +28,7 @@
use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err};
use middle::ty::{ty_estr, ty_evec, ty_float, ty_infer, ty_int, ty_nil};
use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr};
use middle::ty::{ty_rec, ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure};
use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec};
use middle::ty::{type_is_ty_var};
......@@ -103,9 +103,8 @@ pub fn get_base_type(inference_context: @mut InferCtxt,
}
ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | ty_float(*) |
ty_estr(*) | ty_evec(*) | ty_rec(*) |
ty_bare_fn(*) | ty_closure(*) | ty_tup(*) | ty_infer(*) |
ty_param(*) | ty_self | ty_type | ty_opaque_box |
ty_estr(*) | ty_evec(*) | ty_bare_fn(*) | ty_closure(*) | ty_tup(*) |
ty_infer(*) | ty_param(*) | ty_self | ty_type | ty_opaque_box |
ty_opaque_closure_ptr(*) | ty_unboxed_vec(*) | ty_err => {
debug!("(getting base type) no base type; found %?",
get(original_type).sty);
......
......@@ -546,17 +546,6 @@ pub fn super_tys<C:Combine>(
}
}
(ty::ty_rec(as_), ty::ty_rec(bs)) => {
if vec::same_length(as_, bs) {
map_vec2(as_, bs, |a,b| {
self.flds(*a, *b)
}).chain(|flds| Ok(ty::mk_rec(tcx, flds)) )
} else {
Err(ty::terr_record_size(expected_found(self, as_.len(),
bs.len())))
}
}
(ty::ty_tup(as_), ty::ty_tup(bs)) => {
if vec::same_length(as_, bs) {
map_vec2(as_, bs, |a, b| self.tys(*a, *b) )
......
......@@ -22,9 +22,8 @@
use middle::ty::{ty_err, ty_estr, ty_evec, ty_float, ty_bare_fn, ty_closure};
use middle::ty::{ty_trait, ty_int};
use middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
use middle::ty::{ty_ptr, ty_rec, ty_rptr, ty_self, ty_tup};
use middle::ty::{ty_type, ty_uniq, ty_uint, ty_infer};
use middle::ty::{ty_unboxed_vec};
use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer};
use metadata::encoder;
use syntax::codemap::span;
use syntax::print::pprust;
......@@ -414,10 +413,6 @@ fn field_to_str(cx: ctxt, f: field) -> ~str {
}
ty_unboxed_vec(tm) => { ~"unboxed_vec<" + mt_to_str(cx, tm) + ~">" }
ty_type => ~"type",
ty_rec(elems) => {
let strs = elems.map(|fld| field_to_str(cx, *fld));
~"{" + str::connect(strs, ~",") + ~"}"
}
ty_tup(elems) => {
let strs = elems.map(|elem| ty_to_str(cx, *elem));
~"(" + str::connect(strs, ~",") + ~")"
......
......@@ -935,7 +935,6 @@ pub enum ty_ {
ty_fixed_length_vec(mt, uint),
ty_ptr(mt),
ty_rptr(@region, mt),
ty_rec(~[ty_field]),
ty_closure(@TyClosure),
ty_bare_fn(@TyBareFn),
ty_tup(~[@Ty]),
......
......@@ -613,7 +613,6 @@ fn fold_field(f: ty_field, fld: @ast_fold) -> ty_field {
ty_vec(ref mt) => ty_vec(fold_mt(mt, fld)),
ty_ptr(ref mt) => ty_ptr(fold_mt(mt, fld)),
ty_rptr(region, ref mt) => ty_rptr(region, fold_mt(mt, fld)),
ty_rec(ref fields) => ty_rec(fields.map(|f| fold_field(*f, fld))),
ty_closure(ref f) => {
ty_closure(@TyClosure {
sigil: f.sigil,
......
......@@ -51,7 +51,7 @@
use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn};
use ast::{ty_infer, ty_mac, ty_method};
use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rec, ty_rptr};
use ast::{ty_nil, TyParam, TyParamBound, ty_path, ty_ptr, ty_rptr};
use ast::{ty_tup, ty_u32, ty_uniq, ty_vec, type_value_ns, uniq};
use ast::{unnamed_field, unsafe_blk, unsafe_fn, variant, view_item};
use ast::{view_item_, view_item_extern_mod, view_item_use};
......@@ -659,7 +659,7 @@ fn parse_ty(&self, colons_before_params: bool) -> @Ty {
self.unexpected_last(&token::RBRACE);
}
self.obsolete(*self.last_span, ObsoleteRecordType);
ty_rec(elems)
ty_nil
} else if *self.token == token::LBRACKET {
self.expect(&token::LBRACKET);
let mt = self.parse_mt();
......
......@@ -402,20 +402,6 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) {
print_region(s, ~"&", region, ~"/");
print_mt(s, mt);
}
ast::ty_rec(ref fields) => {
word(s.s, ~"{");
fn print_field(s: @ps, f: ast::ty_field) {
cbox(s, indent_unit);
print_mutability(s, f.node.mt.mutbl);
print_ident(s, f.node.ident);
word_space(s, ~":");
print_type(s, f.node.mt.ty);
end(s);
}
fn get_span(f: ast::ty_field) -> codemap::span { return f.span; }
commasep_cmnt(s, consistent, (*fields), print_field, get_span);
word(s.s, ~",}");
}
ast::ty_tup(elts) => {
popen(s);
commasep(s, inconsistent, elts, print_type);
......
......@@ -232,11 +232,6 @@ pub fn visit_ty<E>(t: @Ty, e: E, v: vt<E>) {
ty_vec(mt) | ty_ptr(mt) | ty_rptr(_, mt) => {
(v.visit_ty)(mt.ty, e, v);
},
ty_rec(ref flds) => {
for flds.each |f| {
(v.visit_ty)(f.node.mt.ty, e, v);
}
},
ty_tup(ref ts) => {
for ts.each |tt| {
(v.visit_ty)(*tt, e, v);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册