rustc: Implement "for" over interior vectors
This commit is contained in:
parent
23d6a6bde1
commit
062c6b946b
3 changed files with 41 additions and 15 deletions
|
@ -335,7 +335,11 @@ fn check_for(&ctx cx, &@ast::local local, &@ast::expr seq, &ast::block block,
|
|||
case (ty::ty_vec(?mt)) {
|
||||
if (mt.mut != ast::imm) { unsafe = [seq_t]; }
|
||||
}
|
||||
case (ty::ty_str) { }
|
||||
case (ty::ty_str) { /* no-op */ }
|
||||
case (ty::ty_ivec(?mt)) {
|
||||
if (mt.mut != ast::imm) { unsafe = [seq_t]; }
|
||||
}
|
||||
case (ty::ty_istr) { /* no-op */ }
|
||||
}
|
||||
auto new_sc =
|
||||
@rec(root_vars=root_def,
|
||||
|
|
|
@ -2691,15 +2691,24 @@ fn iter_sequence_inner(&@block_ctxt cx, ValueRef src,
|
|||
fn iter_sequence(@block_ctxt cx, ValueRef v, &ty::t t, &val_and_ty_fn f) ->
|
||||
result {
|
||||
fn iter_sequence_body(@block_ctxt cx, ValueRef v, &ty::t elt_ty,
|
||||
&val_and_ty_fn f, bool trailing_null) -> result {
|
||||
auto p0 = cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_data)]);
|
||||
auto lenptr = cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_fill)]);
|
||||
auto llunit_ty;
|
||||
if (ty::type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, elt_ty)) {
|
||||
llunit_ty = T_i8();
|
||||
} else { llunit_ty = type_of(cx.fcx.lcx.ccx, cx.sp, elt_ty); }
|
||||
auto bcx = cx;
|
||||
auto len = bcx.build.Load(lenptr);
|
||||
&val_and_ty_fn f, bool trailing_null, bool interior)
|
||||
-> result {
|
||||
auto p0;
|
||||
auto len;
|
||||
auto bcx;
|
||||
if (!interior) {
|
||||
p0 = cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_data)]);
|
||||
auto lp = cx.build.GEP(v, [C_int(0), C_int(abi::vec_elt_fill)]);
|
||||
len = cx.build.Load(lp);
|
||||
bcx = cx;
|
||||
} else {
|
||||
auto len_and_data_rslt = ivec::get_len_and_data(cx, v, elt_ty);
|
||||
len = len_and_data_rslt._0;
|
||||
p0 = len_and_data_rslt._1;
|
||||
bcx = len_and_data_rslt._2;
|
||||
}
|
||||
|
||||
auto llunit_ty = type_of_or_i8(cx, elt_ty);
|
||||
if (trailing_null) {
|
||||
auto unit_sz = size_of(bcx, elt_ty);
|
||||
bcx = unit_sz.bcx;
|
||||
|
@ -2709,13 +2718,21 @@ fn iter_sequence(@block_ctxt cx, ValueRef v, &ty::t t, &val_and_ty_fn f) ->
|
|||
vi2p(bcx, bcx.build.Add(vp2i(bcx, p0), len), T_ptr(llunit_ty));
|
||||
ret iter_sequence_inner(bcx, p0, p1, elt_ty, f);
|
||||
}
|
||||
|
||||
alt (ty::struct(cx.fcx.lcx.ccx.tcx, t)) {
|
||||
case (ty::ty_vec(?elt)) {
|
||||
ret iter_sequence_body(cx, v, elt.ty, f, false);
|
||||
ret iter_sequence_body(cx, v, elt.ty, f, false, false);
|
||||
}
|
||||
case (ty::ty_str) {
|
||||
auto et = ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8);
|
||||
ret iter_sequence_body(cx, v, et, f, true);
|
||||
ret iter_sequence_body(cx, v, et, f, true, false);
|
||||
}
|
||||
case (ty::ty_ivec(?elt)) {
|
||||
ret iter_sequence_body(cx, v, elt.ty, f, false, true);
|
||||
}
|
||||
case (ty::ty_istr) {
|
||||
auto et = ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8);
|
||||
ret iter_sequence_body(cx, v, et, f, true, true);
|
||||
}
|
||||
case (_) {
|
||||
cx.fcx.lcx.ccx.sess.bug("unexpected type in " +
|
||||
|
|
|
@ -1683,15 +1683,20 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
|||
case (ast::expr_for(?decl, ?seq, ?body, ?id)) {
|
||||
check_expr(fcx, seq);
|
||||
auto elt_ty;
|
||||
alt (structure_of(fcx, expr.span, expr_ty(fcx.ccx.tcx, seq))) {
|
||||
auto ety = expr_ty(fcx.ccx.tcx, seq);
|
||||
alt (structure_of(fcx, expr.span, ety)) {
|
||||
case (ty::ty_vec(?vec_elt_ty)) { elt_ty = vec_elt_ty.ty; }
|
||||
case (ty::ty_str) {
|
||||
elt_ty = ty::mk_mach(fcx.ccx.tcx, util::common::ty_u8);
|
||||
}
|
||||
case (ty::ty_ivec(?vec_elt_ty)) { elt_ty = vec_elt_ty.ty; }
|
||||
case (ty::ty_istr) {
|
||||
elt_ty = ty::mk_mach(fcx.ccx.tcx, util::common::ty_u8);
|
||||
}
|
||||
case (_) {
|
||||
fcx.ccx.tcx.sess.span_fatal(expr.span,
|
||||
"type of for loop iterator \
|
||||
is not a vector or string");
|
||||
"mismatched types: expected vector or string but " +
|
||||
"found " + ty_to_str(fcx.ccx.tcx, ety));
|
||||
}
|
||||
}
|
||||
check_for_or_for_each(fcx, decl, elt_ty, body, id);
|
||||
|
|
Loading…
Reference in a new issue