@@ -5,6 +5,7 @@ use rustc_index::vec::Idx;
5
5
use crate :: build:: expr:: as_place:: PlaceBase ;
6
6
use crate :: build:: expr:: category:: { Category , RvalueFunc } ;
7
7
use crate :: build:: { BlockAnd , BlockAndExtension , Builder } ;
8
+ use rustc_hir:: lang_items:: LangItem ;
8
9
use rustc_middle:: middle:: region;
9
10
use rustc_middle:: mir:: AssertKind ;
10
11
use rustc_middle:: mir:: Place ;
@@ -88,6 +89,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
88
89
}
89
90
ExprKind :: Box { value } => {
90
91
let value = & this. thir [ value] ;
92
+ let tcx = this. tcx ;
93
+
94
+ let u8_ptr = tcx. mk_mut_ptr ( tcx. mk_mach_uint ( ty:: UintTy :: U8 ) ) ;
95
+ let storage = this. local_decls . push ( LocalDecl :: new ( u8_ptr, expr_span) . internal ( ) ) ;
96
+ this. cfg . push (
97
+ block,
98
+ Statement { source_info, kind : StatementKind :: StorageLive ( storage) } ,
99
+ ) ;
100
+
101
+ let box_new = tcx. require_lang_item ( LangItem :: BoxNew , Some ( source_info. span ) ) ;
102
+ let box_new = Operand :: function_handle (
103
+ tcx,
104
+ box_new,
105
+ tcx. mk_substs ( [ value. ty . into ( ) ] . iter ( ) ) ,
106
+ source_info. span ,
107
+ ) ;
108
+
109
+ let success = this. cfg . start_new_block ( ) ;
110
+ this. cfg . terminate (
111
+ block,
112
+ source_info,
113
+ TerminatorKind :: Call {
114
+ func : box_new,
115
+ args : Vec :: new ( ) ,
116
+ destination : Some ( ( Place :: from ( storage) , success) ) ,
117
+ cleanup : None ,
118
+ from_hir_call : false ,
119
+ fn_span : source_info. span ,
120
+ } ,
121
+ ) ;
122
+ this. diverge_from ( block) ;
123
+ block = success;
124
+
91
125
// The `Box<T>` temporary created here is not a part of the HIR,
92
126
// and therefore is not considered during generator auto-trait
93
127
// determination. See the comment about `box` at `yield_in_scope`.
@@ -102,7 +136,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
102
136
}
103
137
104
138
// malloc some memory of suitable type (thus far, uninitialized):
105
- let box_ = Rvalue :: NullaryOp ( NullOp :: Box , value. ty ) ;
139
+ let box_ = Rvalue :: InitBox ( Operand :: Move ( Place :: from ( storage ) ) , value. ty ) ;
106
140
this. cfg . push_assign ( block, source_info, Place :: from ( result) , box_) ;
107
141
108
142
// initialize the box contents:
0 commit comments