@@ -2662,7 +2662,8 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
2662
2662
[ C_int ( 0 ) , C_uint ( abi:: ivec_elt_len) ] ) ) ;
2663
2663
auto stack_elem = bcx. build . GEP ( v, [ C_int ( 0 ) ,
2664
2664
C_uint ( abi:: ivec_elt_elems) ] ) ;
2665
- stack_elem = bcx. build . PointerCast ( stack_elem, T_ptr ( llunitty) ) ;
2665
+ stack_elem = bcx. build . PointerCast ( stack_elem,
2666
+ T_ptr ( T_array ( llunitty, 0 u) ) ) ;
2666
2667
2667
2668
auto on_heap = bcx. build . ICmp ( lib:: llvm:: LLVMIntEQ , stack_len, C_int ( 0 ) ) ;
2668
2669
@@ -2690,21 +2691,21 @@ fn get_ivec_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
2690
2691
// Technically this context is unnecessary, but it makes this function
2691
2692
// clearer.
2692
2693
auto zero_len = C_int ( 0 ) ;
2693
- auto zero_elem = C_null ( T_ptr ( llunitty) ) ;
2694
+ auto zero_elem = C_null ( T_ptr ( T_array ( llunitty, 0 u ) ) ) ;
2694
2695
zero_len_cx. build . Br ( next_cx. llbb ) ;
2695
2696
2696
2697
// If we're here, then we actually have a heapified vector.
2697
2698
auto heap_len = nonzero_len_cx. build . Load ( nonzero_len_cx. build . GEP (
2698
2699
heap_ptr, [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_len) ] ) ) ;
2699
2700
auto heap_elem = nonzero_len_cx. build . GEP ( heap_ptr,
2700
- [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) , C_int ( 0 ) ] ) ;
2701
+ [ C_int ( 0 ) , C_uint ( abi:: ivec_heap_elt_elems) ] ) ;
2701
2702
nonzero_len_cx. build . Br ( next_cx. llbb ) ;
2702
2703
2703
2704
// Now we can figure out the length of `v` and get a pointer to its first
2704
2705
// element.
2705
2706
auto len = next_cx. build . Phi ( T_int ( ) , [ stack_len, zero_len, heap_len] ,
2706
2707
[ bcx. llbb , zero_len_cx. llbb , nonzero_len_cx. llbb ] ) ;
2707
- auto elem = next_cx. build . Phi ( T_ptr ( llunitty) ,
2708
+ auto elem = next_cx. build . Phi ( T_ptr ( T_array ( llunitty, 0 u ) ) ,
2708
2709
[ stack_elem, zero_elem, heap_elem] ,
2709
2710
[ bcx. llbb , zero_len_cx. llbb , nonzero_len_cx. llbb ] ) ;
2710
2711
ret tup( len, elem, next_cx) ;
@@ -4743,8 +4744,21 @@ fn trans_field(&@block_ctxt cx, &span sp, ValueRef v, &ty::t t0,
4743
4744
fn trans_index( & @block_ctxt cx, & span sp, & @ast:: expr base,
4744
4745
& @ast:: expr idx, & ast:: ann ann) -> lval_result {
4745
4746
4747
+ // Is this an interior vector?
4748
+ auto base_ty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, base) ;
4749
+ auto base_ty_no_boxes = ty:: strip_boxes( cx. fcx. lcx. ccx. tcx, base_ty) ;
4750
+
4751
+ auto is_interior;
4752
+ alt ( ty:: struct( cx. fcx. lcx. ccx. tcx, base_ty_no_boxes) ) {
4753
+ // TODO: Or-patterns
4754
+ case ( ty:: ty_vec( _) ) { is_interior = false; }
4755
+ case ( ty:: ty_str) { is_interior = false ; }
4756
+ case ( ty:: ty_ivec( _) ) { is_interior = true ; }
4757
+ case ( ty:: ty_istr) { is_interior = true ; }
4758
+ } ;
4759
+
4746
4760
auto lv = trans_expr( cx, base) ;
4747
- lv = autoderef( lv. bcx, lv. val, ty : : expr_ty ( cx . fcx . lcx . ccx . tcx , base ) ) ;
4761
+ lv = autoderef( lv. bcx, lv. val, base_ty ) ;
4748
4762
auto ix = trans_expr( lv. bcx, idx) ;
4749
4763
auto v = lv. val;
4750
4764
auto bcx = ix. bcx;
@@ -4769,8 +4783,23 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
4769
4783
auto scaled_ix = bcx. build . Mul ( ix_val, unit_sz. val ) ;
4770
4784
maybe_name_value ( cx. fcx . lcx . ccx , scaled_ix, "scaled_ix" ) ;
4771
4785
4772
- auto lim = bcx. build . GEP ( v, [ C_int ( 0 ) , C_int ( abi:: vec_elt_fill) ] ) ;
4773
- lim = bcx. build . Load ( lim) ;
4786
+ auto interior_len_and_data;
4787
+ if ( is_interior) {
4788
+ auto rslt = get_ivec_len_and_data ( bcx, v, unit_ty) ;
4789
+ interior_len_and_data = some ( tup ( rslt. _0 , rslt. _1 ) ) ;
4790
+ bcx = rslt. _2 ;
4791
+ } else {
4792
+ interior_len_and_data = none;
4793
+ }
4794
+
4795
+ auto lim;
4796
+ alt ( interior_len_and_data) {
4797
+ case ( some ( ?lad) ) { lim = lad. _0 ; }
4798
+ case ( none) {
4799
+ lim = bcx. build . GEP ( v, [ C_int ( 0 ) , C_int ( abi:: vec_elt_fill) ] ) ;
4800
+ lim = bcx. build . Load ( lim) ;
4801
+ }
4802
+ }
4774
4803
4775
4804
auto bounds_check = bcx. build . ICmp ( lib:: llvm:: LLVMIntULT ,
4776
4805
scaled_ix, lim) ;
@@ -4783,7 +4812,14 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base,
4783
4812
auto fail_res = trans_fail ( fail_cx, some[ common:: span] ( sp) ,
4784
4813
"bounds check" ) ;
4785
4814
4786
- auto body = next_cx. build . GEP ( v, [ C_int ( 0 ) , C_int ( abi:: vec_elt_data) ] ) ;
4815
+ auto body;
4816
+ alt ( interior_len_and_data) {
4817
+ case ( some ( ?lad) ) { body = lad. _1 ; }
4818
+ case ( none) {
4819
+ body = next_cx. build . GEP ( v, [ C_int ( 0 ) , C_int ( abi:: vec_elt_data) ] ) ;
4820
+ }
4821
+ }
4822
+
4787
4823
auto elt;
4788
4824
if ( ty:: type_has_dynamic_size ( cx. fcx . lcx . ccx . tcx , unit_ty) ) {
4789
4825
body = next_cx. build . PointerCast ( body, T_ptr ( T_array ( T_i8 ( ) , 0 u) ) ) ;
0 commit comments