Handle record update in typeck.
This commit is contained in:
parent
7a02798d1b
commit
370c1ad00e
2 changed files with 81 additions and 14 deletions
|
@ -553,6 +553,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
|
||||||
bad-expr-path.rs \
|
bad-expr-path.rs \
|
||||||
bad-expr-path2.rs \
|
bad-expr-path2.rs \
|
||||||
bogus-tag.rs \
|
bogus-tag.rs \
|
||||||
|
fru-extra-field.rs \
|
||||||
import.rs \
|
import.rs \
|
||||||
import2.rs \
|
import2.rs \
|
||||||
import3.rs \
|
import3.rs \
|
||||||
|
|
|
@ -912,23 +912,48 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
|
||||||
}
|
}
|
||||||
case (ast.expr_rec(?fields_0, ?base_0, ?ann)) {
|
case (ast.expr_rec(?fields_0, ?base_0, ?ann)) {
|
||||||
|
|
||||||
// FIXME: handle presence of a nonempty base.
|
|
||||||
check (base_0 == none[@ast.expr]);
|
|
||||||
auto base_1 = base_0;
|
auto base_1 = base_0;
|
||||||
|
|
||||||
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
|
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
|
||||||
let vec[ast.field] fields_1 = vec();
|
let vec[ast.field] fields_1 = vec();
|
||||||
alt (t.struct) {
|
alt (t.struct) {
|
||||||
case (ty.ty_rec(?field_tys)) {
|
case (ty.ty_rec(?field_tys)) {
|
||||||
auto i = 0u;
|
alt (base_0) {
|
||||||
for (ast.field field_0 in fields_0) {
|
case (none[@ast.expr]) {
|
||||||
check (_str.eq(field_0.ident, field_tys.(i).ident));
|
auto i = 0u;
|
||||||
auto e_1 = demand_expr(fcx, field_tys.(i).ty,
|
for (ast.field field_0 in fields_0) {
|
||||||
field_0.expr);
|
check (_str.eq(field_0.ident,
|
||||||
fields_1 += vec(rec(mut=field_0.mut,
|
field_tys.(i).ident));
|
||||||
ident=field_0.ident,
|
auto e_1 = demand_expr(fcx,
|
||||||
expr=e_1));
|
field_tys.(i).ty,
|
||||||
i += 1u;
|
field_0.expr);
|
||||||
|
fields_1 += vec(rec(mut=field_0.mut,
|
||||||
|
ident=field_0.ident,
|
||||||
|
expr=e_1));
|
||||||
|
i += 1u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case (some[@ast.expr](?bx)) {
|
||||||
|
|
||||||
|
base_1 =
|
||||||
|
some[@ast.expr](demand_expr(fcx, t, bx));
|
||||||
|
|
||||||
|
let vec[field] base_fields = vec();
|
||||||
|
|
||||||
|
for (ast.field field_0 in fields_0) {
|
||||||
|
|
||||||
|
for (ty.field ft in field_tys) {
|
||||||
|
if (_str.eq(field_0.ident, ft.ident)) {
|
||||||
|
auto e_1 = demand_expr(fcx, ft.ty,
|
||||||
|
field_0.expr);
|
||||||
|
fields_1 +=
|
||||||
|
vec(rec(mut=field_0.mut,
|
||||||
|
ident=field_0.ident,
|
||||||
|
expr=e_1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
|
@ -1708,8 +1733,6 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||||
|
|
||||||
case (ast.expr_rec(?fields, ?base, _)) {
|
case (ast.expr_rec(?fields, ?base, _)) {
|
||||||
|
|
||||||
// FIXME: handle presence of a nonempty base.
|
|
||||||
check (base == none[@ast.expr]);
|
|
||||||
auto base_1 = base;
|
auto base_1 = base;
|
||||||
|
|
||||||
let vec[ast.field] fields_1 = vec();
|
let vec[ast.field] fields_1 = vec();
|
||||||
|
@ -1725,7 +1748,50 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||||
append[field](fields_t, rec(ident=f.ident, ty=expr_t));
|
append[field](fields_t, rec(ident=f.ident, ty=expr_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t)));
|
auto ann = ast.ann_none;
|
||||||
|
|
||||||
|
alt (base) {
|
||||||
|
case (none[@ast.expr]) {
|
||||||
|
ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
case (some[@ast.expr](?bexpr)) {
|
||||||
|
auto bexpr_1 = check_expr(fcx, bexpr);
|
||||||
|
auto bexpr_t = expr_ty(bexpr_1);
|
||||||
|
|
||||||
|
let vec[field] base_fields = vec();
|
||||||
|
|
||||||
|
alt (bexpr_t.struct) {
|
||||||
|
case (ty.ty_rec(?flds)) {
|
||||||
|
base_fields = flds;
|
||||||
|
}
|
||||||
|
case (_) {
|
||||||
|
fcx.ccx.sess.span_err
|
||||||
|
(expr.span,
|
||||||
|
"record update non-record base");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ann = ast.ann_type(bexpr_t);
|
||||||
|
|
||||||
|
for (ty.field f in fields_t) {
|
||||||
|
auto found = false;
|
||||||
|
for (ty.field bf in base_fields) {
|
||||||
|
if (_str.eq(f.ident, bf.ident)) {
|
||||||
|
demand(fcx, expr.span, f.ty, bf.ty);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
fcx.ccx.sess.span_err
|
||||||
|
(expr.span,
|
||||||
|
"unknown field in record update: "
|
||||||
|
+ f.ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret @fold.respan[ast.expr_](expr.span,
|
ret @fold.respan[ast.expr_](expr.span,
|
||||||
ast.expr_rec(fields_1, base_1, ann));
|
ast.expr_rec(fields_1, base_1, ann));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue