@@ -1023,6 +1023,25 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
1023
1023
bcx
1024
1024
}
1025
1025
1026
+ // Sets each dropflag hint (if any) for bindings to `dropflag_hint_val`.
1027
+ fn set_lllocals_hints < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
1028
+ bindings_map : & BindingsMap < ' tcx > ,
1029
+ drop_flag_hint_value : u8 )
1030
+ -> Block < ' blk , ' tcx > {
1031
+ let lllocals = bcx. fcx . lllocals . borrow ( ) ;
1032
+ for ( & ident, & binding_info) in bindings_map {
1033
+ let datum = lllocals. get ( & binding_info. id ) . unwrap ( ) ;
1034
+ if let Some ( hint) = datum. kind . dropflag_hint ( bcx) {
1035
+ let hint_value = drop_flag_hint_value;
1036
+ debug ! ( "set_lllocals_hints store hint_value={} for hint={:?} ident={}" ,
1037
+ hint_value, hint, ident) ;
1038
+ Store ( bcx, C_u8 ( bcx. fcx . ccx , hint_value) , hint. to_value ( ) . value ( ) ) ;
1039
+ }
1040
+ }
1041
+
1042
+ bcx
1043
+ }
1044
+
1026
1045
fn compile_guard < ' a , ' p , ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
1027
1046
guard_expr : & ast:: Expr ,
1028
1047
data : & ArmData < ' p , ' blk , ' tcx > ,
@@ -1633,6 +1652,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
1633
1652
// insert bindings into the lllocals map and add cleanups
1634
1653
let cs = fcx. push_custom_cleanup_scope ( ) ;
1635
1654
bcx = insert_lllocals ( bcx, & arm_data. bindings_map , Some ( cleanup:: CustomScope ( cs) ) ) ;
1655
+ bcx = set_lllocals_hints ( bcx, & arm_data. bindings_map , adt:: DTOR_NEEDED_HINT ) ;
1636
1656
bcx = expr:: trans_into ( bcx, & * arm_data. arm . body , dest) ;
1637
1657
bcx = fcx. pop_and_trans_custom_cleanup_scope ( bcx, cs) ;
1638
1658
arm_cxs. push ( bcx) ;
@@ -1664,16 +1684,10 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1664
1684
bcx = mk_binding_alloca (
1665
1685
bcx, p_id, path1. node . name , scope, ( ) ,
1666
1686
"_match::store_local::create_dummy_locals" ,
1687
+ // Dummy-locals start out uninitialized, so set their
1688
+ // drop-flag hints (if any) to "moved."
1689
+ adt:: DTOR_MOVED_HINT ,
1667
1690
|( ) , bcx, Datum { val : llval, ty, kind } | {
1668
- // Dummy-locals start out uninitialized, so set their
1669
- // drop-flag hints (if any) to "moved."
1670
- if let Some ( hint) = kind. dropflag_hint ( bcx) {
1671
- let moved_hint = adt:: DTOR_MOVED_HINT ;
1672
- debug ! ( "store moved_hint={} for hint={:?}, uninitialized dummy" ,
1673
- moved_hint, hint) ;
1674
- Store ( bcx, C_u8 ( bcx. fcx . ccx , moved_hint) , hint. to_value ( ) . value ( ) ) ;
1675
- }
1676
-
1677
1691
if kind. drop_flag_info . must_zero ( ) {
1678
1692
// if no drop-flag hint, or the hint requires
1679
1693
// we maintain the embedded drop-flag, then
@@ -1705,6 +1719,9 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1705
1719
return mk_binding_alloca (
1706
1720
bcx, pat. id , ident. name , var_scope, ( ) ,
1707
1721
"_match::store_local" ,
1722
+ // Issue #27401: `let x = expr;` means drop
1723
+ // flag hint needs to be (re-)initialized.
1724
+ adt:: DTOR_NEEDED_HINT ,
1708
1725
|( ) , bcx, Datum { val : v, .. } | expr:: trans_into ( bcx, & * * init_expr,
1709
1726
expr:: SaveIn ( v) ) ) ;
1710
1727
}
@@ -1733,6 +1750,7 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
1733
1750
cleanup_scope : cleanup:: ScopeId ,
1734
1751
arg : A ,
1735
1752
caller_name : & ' static str ,
1753
+ drop_flag_hint_value : u8 ,
1736
1754
populate : F )
1737
1755
-> Block < ' blk , ' tcx > where
1738
1756
F : FnOnce ( A , Block < ' blk , ' tcx > , Datum < ' tcx , Lvalue > ) -> Block < ' blk , ' tcx > ,
@@ -1747,6 +1765,15 @@ fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
1747
1765
// Subtle: be sure that we *populate* the memory *before*
1748
1766
// we schedule the cleanup.
1749
1767
let bcx = populate ( arg, bcx, datum) ;
1768
+
1769
+ // Set the drop-flag hint, if any, to the value provided by context
1770
+ if let Some ( hint) = datum. kind . dropflag_hint ( bcx) {
1771
+ let hint_value = drop_flag_hint_value;
1772
+ debug ! ( "mk_binding_alloca store hint_value={} for hint={:?}, name={}" ,
1773
+ hint_value, hint, name) ;
1774
+ Store ( bcx, C_u8 ( bcx. fcx . ccx , hint_value) , hint. to_value ( ) . value ( ) ) ;
1775
+ }
1776
+
1750
1777
bcx. fcx . schedule_lifetime_end ( cleanup_scope, llval) ;
1751
1778
bcx. fcx . schedule_drop_mem ( cleanup_scope, llval, var_ty, lvalue. dropflag_hint ( bcx) ) ;
1752
1779
@@ -1797,6 +1824,10 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1797
1824
bcx = mk_binding_alloca (
1798
1825
bcx, pat. id , path1. node . name , cleanup_scope, ( ) ,
1799
1826
"_match::bind_irrefutable_pat" ,
1827
+ // Issue #27401: `match ... { PAT[x] => ... }`
1828
+ // means drop flag hint for `x` needs to be
1829
+ // (re-)initialized.
1830
+ adt:: DTOR_NEEDED_HINT ,
1800
1831
|( ) , bcx, Datum { val : llval, ty, kind : _ } | {
1801
1832
match pat_binding_mode {
1802
1833
ast:: BindByValue ( _) => {
0 commit comments