@@ -313,8 +313,8 @@ fn shared_malloc(cx: block, llptr_ty: TypeRef, llsize: ValueRef)
313
313
//
314
314
// The runtime equivalent is box_body() in "rust_internal.h".
315
315
fn opaque_box_body ( bcx : block ,
316
- body_t : ty:: t ,
317
- boxptr : ValueRef ) -> ValueRef {
316
+ body_t : ty:: t ,
317
+ boxptr : ValueRef ) -> ValueRef {
318
318
let _icx = bcx. insn_ctxt ( "opaque_box_body" ) ;
319
319
let ccx = bcx. ccx ( ) ;
320
320
let boxptr = PointerCast ( bcx, boxptr, T_ptr ( T_box_header ( ccx) ) ) ;
@@ -2323,6 +2323,10 @@ fn trans_index(cx: block, ex: @ast::expr, base: @ast::expr,
2323
2323
ret lval_owned( bcx, PointerCast ( bcx, elt, T_ptr ( llunitty) ) ) ;
2324
2324
}
2325
2325
2326
+ fn expr_is_borrowed ( bcx : block , e : @ast:: expr ) -> bool {
2327
+ bcx. tcx ( ) . borrowings . contains_key ( e. id )
2328
+ }
2329
+
2326
2330
fn expr_is_lval ( bcx : block , e : @ast:: expr ) -> bool {
2327
2331
let ccx = bcx. ccx ( ) ;
2328
2332
ty:: expr_is_lval ( ccx. maps . method_map , e)
@@ -2553,6 +2557,7 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
2553
2557
}
2554
2558
none { trans_temp_lval( cx, e) }
2555
2559
} ;
2560
+ let lv = adapt_borrowed_value ( lv, arg, e) ;
2556
2561
let mut bcx = lv. bcx ;
2557
2562
let mut val = lv. val ;
2558
2563
let arg_mode = ty:: resolved_mode ( ccx. tcx , arg. mode ) ;
@@ -2611,6 +2616,58 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
2611
2616
ret rslt( bcx, val) ;
2612
2617
}
2613
2618
2619
+ fn adapt_borrowed_value ( lv : lval_result , arg : ty:: arg ,
2620
+ e : @ast:: expr ) -> lval_result {
2621
+ let bcx = lv. bcx ;
2622
+ if !expr_is_borrowed ( bcx, e) { ret lv; }
2623
+
2624
+ let e_ty = expr_ty ( bcx, e) ;
2625
+ alt ty:: get ( e_ty) . struct {
2626
+ ty:: ty_box ( mt) {
2627
+ let box_ptr = {
2628
+ alt lv. kind {
2629
+ temporary { lv. val }
2630
+ owned { Load ( bcx, lv. val ) }
2631
+ owned_imm { lv. val }
2632
+ }
2633
+ } ;
2634
+ let body_ptr = GEPi ( bcx, box_ptr, [ 0 , abi:: box_field_body] ) ;
2635
+ ret lval_temp( bcx, body_ptr) ;
2636
+ }
2637
+
2638
+ ty:: ty_uniq ( _) {
2639
+ ret lv; // no change needed at runtime (I think)
2640
+ }
2641
+
2642
+ ty:: ty_estr ( ty:: vstore_box) |
2643
+ ty:: ty_evec ( _, ty:: vstore_box) {
2644
+ bcx. tcx ( ) . sess . span_unimpl (
2645
+ e. span , #fmt[ "borrowing a value of type %s" ,
2646
+ ty_to_str ( bcx. tcx ( ) , e_ty) ] ) ;
2647
+ }
2648
+
2649
+ ty:: ty_estr ( ty:: vstore_uniq) |
2650
+ ty:: ty_evec ( _, ty:: vstore_uniq) {
2651
+ bcx. tcx ( ) . sess . span_unimpl (
2652
+ e. span , #fmt[ "borrowing a value of type %s" ,
2653
+ ty_to_str ( bcx. tcx ( ) , e_ty) ] ) ;
2654
+ }
2655
+
2656
+ ty:: ty_estr ( ty:: vstore_fixed ( _) ) |
2657
+ ty:: ty_evec ( _, ty:: vstore_fixed ( _) ) {
2658
+ bcx. tcx ( ) . sess . span_unimpl (
2659
+ e. span , #fmt[ "borrowing a value of type %s" ,
2660
+ ty_to_str ( bcx. tcx ( ) , e_ty) ] ) ;
2661
+ }
2662
+
2663
+ _ {
2664
+ bcx. tcx ( ) . sess . span_bug (
2665
+ e. span , #fmt[ "cannot borrow a value of type %s" ,
2666
+ ty_to_str ( bcx. tcx ( ) , e_ty) ] ) ;
2667
+ }
2668
+ }
2669
+ }
2670
+
2614
2671
enum call_args {
2615
2672
arg_exprs( [ @ast:: expr ] ) ,
2616
2673
arg_vals( [ ValueRef ] )
@@ -3006,7 +3063,12 @@ fn trans_expr_save_in(bcx: block, e: @ast::expr, dest: ValueRef)
3006
3063
fn trans_temp_lval ( bcx : block , e : @ast:: expr ) -> lval_result {
3007
3064
let _icx = bcx. insn_ctxt ( "trans_temp_lval" ) ;
3008
3065
let mut bcx = bcx;
3009
- if expr_is_lval ( bcx, e) {
3066
+ if expr_is_lval ( bcx, e) && !expr_is_borrowed ( bcx, e) {
3067
+ // if the expression is borrowed, then are not actually passing the
3068
+ // lvalue itself, but rather an adaptation of it. This is a bit of a
3069
+ // hack, though, but it only needs to exist so long as we have
3070
+ // reference modes and the like---otherwise, all potentially borrowed
3071
+ // things will go directly through trans_expr() as they ought to.
3010
3072
ret trans_lval ( bcx, e) ;
3011
3073
} else {
3012
3074
let ty = expr_ty ( bcx, e) ;
@@ -3047,12 +3109,6 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
3047
3109
let tcx = bcx. tcx ( ) ;
3048
3110
debuginfo:: update_source_pos ( bcx, e. span ) ;
3049
3111
3050
- #debug[ "trans_expr(e=%s,e.id=%d,dest=%s,ty=%s)" ,
3051
- expr_to_str ( e) ,
3052
- e. id ,
3053
- dest_str ( bcx. ccx ( ) , dest) ,
3054
- ty_to_str ( tcx, expr_ty ( bcx, e) ) ] ;
3055
-
3056
3112
if expr_is_lval ( bcx, e) {
3057
3113
ret lval_to_dps ( bcx, e, dest) ;
3058
3114
}
@@ -3264,9 +3320,10 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
3264
3320
let bcx = trans_expr ( bcx, val, save_in ( ptr_val) ) ;
3265
3321
store_in_dest ( bcx, ptr_val, dest)
3266
3322
}
3267
- _ { bcx. tcx ( ) . sess . span_bug ( e. span , "trans_expr reached \
3268
- fall-through case") ; }
3269
-
3323
+ _ {
3324
+ bcx. tcx ( ) . sess . span_bug ( e. span , "trans_expr reached \
3325
+ fall-through case") ;
3326
+ }
3270
3327
}
3271
3328
}
3272
3329
0 commit comments