@@ -205,7 +205,7 @@ use trans::build::{AddCase, And, Br, CondBr, GEPi, InBoundsGEP, Load, PointerCas
205
205
use trans:: build:: { Not , Store , Sub , add_comment} ;
206
206
use trans:: build;
207
207
use trans:: callee;
208
- use trans:: cleanup:: { self , CleanupMethods } ;
208
+ use trans:: cleanup:: { self , CleanupMethods , DropHintMethods } ;
209
209
use trans:: common:: * ;
210
210
use trans:: consts;
211
211
use trans:: datum:: * ;
@@ -947,14 +947,14 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
947
947
TrByCopy ( llbinding) |
948
948
TrByMoveIntoCopy ( llbinding) => {
949
949
let llval = Load ( bcx, binding_info. llmatch ) ;
950
- let lval = match binding_info. trmode {
950
+ let lvalue = match binding_info. trmode {
951
951
TrByCopy ( ..) =>
952
952
Lvalue :: new ( "_match::insert_lllocals" ) ,
953
953
TrByMoveIntoCopy ( ..) =>
954
954
Lvalue :: match_input ( "_match::insert_lllocals" , bcx, binding_info. id ) ,
955
955
_ => unreachable ! ( ) ,
956
956
} ;
957
- let datum = Datum :: new ( llval, binding_info. ty , lval ) ;
957
+ let datum = Datum :: new ( llval, binding_info. ty , lvalue ) ;
958
958
call_lifetime_start ( bcx, llbinding) ;
959
959
bcx = datum. store_to ( bcx, llbinding) ;
960
960
if let Some ( cs) = cs {
@@ -971,14 +971,15 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
971
971
TrByRef => ( binding_info. llmatch , true ) ,
972
972
} ;
973
973
974
- let lval = Lvalue :: local ( "_match::insert_lllocals" ,
975
- bcx,
976
- binding_info. id ,
977
- aliases_other_state) ;
978
- let datum = Datum :: new ( llval, binding_info. ty , lval ) ;
974
+ let lvalue = Lvalue :: local ( "_match::insert_lllocals" ,
975
+ bcx,
976
+ binding_info. id ,
977
+ aliases_other_state) ;
978
+ let datum = Datum :: new ( llval, binding_info. ty , lvalue ) ;
979
979
if let Some ( cs) = cs {
980
+ let opt_datum = lvalue. dropflag_hint ( bcx) ;
980
981
bcx. fcx . schedule_lifetime_end ( cs, binding_info. llmatch ) ;
981
- bcx. fcx . schedule_drop_and_fill_mem ( cs, llval, binding_info. ty ) ;
982
+ bcx. fcx . schedule_drop_and_fill_mem ( cs, llval, binding_info. ty , opt_datum ) ;
982
983
}
983
984
984
985
debug ! ( "binding {} to {}" , binding_info. id, bcx. val_to_string( llval) ) ;
@@ -1505,13 +1506,13 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
1505
1506
// but during matching we need to store a *T as explained
1506
1507
// above
1507
1508
llmatch = alloca_no_lifetime ( bcx,
1508
- llvariable_ty. ptr_to ( ) ,
1509
- & bcx. name ( name) ) ;
1509
+ llvariable_ty. ptr_to ( ) ,
1510
+ & bcx. name ( name) ) ;
1510
1511
trmode = TrByMoveRef ;
1511
1512
}
1512
1513
ast:: BindByRef ( _) => {
1513
1514
llmatch = alloca_no_lifetime ( bcx,
1514
- llvariable_ty,
1515
+ llvariable_ty,
1515
1516
& bcx. name ( name) ) ;
1516
1517
trmode = TrByRef ;
1517
1518
}
@@ -1631,7 +1632,25 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1631
1632
bcx = mk_binding_alloca (
1632
1633
bcx, p_id, path1. node . name , scope, ( ) ,
1633
1634
"_match::store_local::create_dummy_locals" ,
1634
- |( ) , bcx, llval, ty| { drop_done_fill_mem ( bcx, llval, ty) ; bcx } ) ;
1635
+ |( ) , bcx, Datum { val : llval, ty, kind } | {
1636
+ // Dummy-locals start out uninitialized, so set their
1637
+ // drop-flag hints (if any) to "moved."
1638
+ if let Some ( hint) = kind. dropflag_hint ( bcx) {
1639
+ let moved_hint = adt:: DTOR_MOVED_HINT as usize ;
1640
+ debug ! ( "store moved_hint={} for hint={:?}, uninitialized dummy" ,
1641
+ moved_hint, hint) ;
1642
+ Store ( bcx, C_u8 ( bcx. fcx . ccx , moved_hint) , hint. to_value ( ) . value ( ) ) ;
1643
+ }
1644
+
1645
+ if kind. drop_flag_info . must_zero ( ) {
1646
+ // if no drop-flag hint, or the hint requires
1647
+ // we maintain the embedded drop-flag, then
1648
+ // mark embedded drop-flag(s) as moved
1649
+ // (i.e. "already dropped").
1650
+ drop_done_fill_mem ( bcx, llval, ty) ;
1651
+ }
1652
+ bcx
1653
+ } ) ;
1635
1654
} ) ;
1636
1655
bcx
1637
1656
}
@@ -1654,8 +1673,8 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1654
1673
return mk_binding_alloca (
1655
1674
bcx, pat. id , ident. name , var_scope, ( ) ,
1656
1675
"_match::store_local" ,
1657
- |( ) , bcx, v, _ | expr:: trans_into ( bcx, & * * init_expr,
1658
- expr:: SaveIn ( v) ) ) ;
1676
+ |( ) , bcx, Datum { val : v, .. } | expr:: trans_into ( bcx, & * * init_expr,
1677
+ expr:: SaveIn ( v) ) ) ;
1659
1678
}
1660
1679
1661
1680
None => { }
@@ -1684,23 +1703,23 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
1684
1703
caller_name : & ' static str ,
1685
1704
populate : F )
1686
1705
-> Block < ' blk , ' tcx > where
1687
- F : FnOnce ( A , Block < ' blk , ' tcx > , ValueRef , Ty < ' tcx > ) -> Block < ' blk , ' tcx > ,
1706
+ F : FnOnce ( A , Block < ' blk , ' tcx > , Datum < ' tcx , Lvalue > ) -> Block < ' blk , ' tcx > ,
1688
1707
{
1689
1708
let var_ty = node_id_type ( bcx, p_id) ;
1690
1709
1691
1710
// Allocate memory on stack for the binding.
1692
1711
let llval = alloc_ty ( bcx, var_ty, & bcx. name ( name) ) ;
1712
+ let lvalue = Lvalue :: binding ( caller_name, bcx, p_id, name) ;
1713
+ let datum = Datum :: new ( llval, var_ty, lvalue) ;
1693
1714
1694
1715
// Subtle: be sure that we *populate* the memory *before*
1695
1716
// we schedule the cleanup.
1696
- let bcx = populate ( arg, bcx, llval , var_ty ) ;
1717
+ let bcx = populate ( arg, bcx, datum ) ;
1697
1718
bcx. fcx . schedule_lifetime_end ( cleanup_scope, llval) ;
1698
- bcx. fcx . schedule_drop_mem ( cleanup_scope, llval, var_ty) ;
1719
+ bcx. fcx . schedule_drop_mem ( cleanup_scope, llval, var_ty, lvalue . dropflag_hint ( bcx ) ) ;
1699
1720
1700
1721
// Now that memory is initialized and has cleanup scheduled,
1701
- // create the datum and insert into the local variable map.
1702
- let lval = Lvalue :: binding ( caller_name, bcx, p_id, name) ;
1703
- let datum = Datum :: new ( llval, var_ty, lval) ;
1722
+ // insert datum into the local variable map.
1704
1723
bcx. fcx . lllocals . borrow_mut ( ) . insert ( p_id, datum) ;
1705
1724
bcx
1706
1725
}
@@ -1746,7 +1765,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1746
1765
bcx = mk_binding_alloca (
1747
1766
bcx, pat. id , path1. node . name , cleanup_scope, ( ) ,
1748
1767
"_match::bind_irrefutable_pat" ,
1749
- |( ) , bcx, llval, ty| {
1768
+ |( ) , bcx, Datum { val : llval, ty, kind : _ } | {
1750
1769
match pat_binding_mode {
1751
1770
ast:: BindByValue ( _) => {
1752
1771
// By value binding: move the value that `val`
@@ -1854,10 +1873,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1854
1873
ast:: PatBox ( ref inner) => {
1855
1874
let llbox = Load ( bcx, val. val ) ;
1856
1875
bcx = bind_irrefutable_pat (
1857
- bcx,
1858
- & * * inner,
1859
- MatchInput :: from_val ( llbox) ,
1860
- cleanup_scope) ;
1876
+ bcx, & * * inner, MatchInput :: from_val ( llbox) , cleanup_scope) ;
1861
1877
}
1862
1878
ast:: PatRegion ( ref inner, _) => {
1863
1879
let loaded_val = Load ( bcx, val. val ) ;
@@ -1884,13 +1900,13 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1884
1900
. chain ( slice. iter ( ) )
1885
1901
. chain ( after. iter ( ) )
1886
1902
. zip ( extracted. vals )
1887
- . fold ( bcx, |bcx, ( inner, elem) |
1903
+ . fold ( bcx, |bcx, ( inner, elem) | {
1888
1904
bind_irrefutable_pat (
1889
1905
bcx,
1890
1906
& * * inner,
1891
1907
MatchInput :: from_val ( elem) ,
1892
1908
cleanup_scope)
1893
- ) ;
1909
+ } ) ;
1894
1910
}
1895
1911
ast:: PatMac ( ..) => {
1896
1912
bcx. sess ( ) . span_bug ( pat. span , "unexpanded macro" ) ;
0 commit comments