@@ -229,6 +229,34 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
229
229
( def_id, substs, Vec :: new ( ) )
230
230
} ;
231
231
232
+ // FIXME(eddyb) Detect ADT constructors more efficiently.
233
+ if let Some ( adt_def) = fn_ty. sig . skip_binder ( ) . output ( ) . ty_adt_def ( ) {
234
+ if let Some ( v) = adt_def. variants . iter ( ) . find ( |v| resolved_def_id == v. did ) {
235
+ // technically they can diverge, but only if one of their arguments diverges, so it doesn't matter
236
+ let ( lvalue, target) = destination. expect ( "tuple struct constructors can't diverge" ) ;
237
+ let dest_ty = self . tcx . item_type ( adt_def. did ) ;
238
+ let dest_layout = self . type_layout ( dest_ty) ?;
239
+ match * dest_layout {
240
+ Layout :: Univariant { ref variant, .. } => {
241
+ assert_eq ! ( v. disr_val. to_u64_unchecked( ) , 0 ) ;
242
+ let offsets = variant. offsets . iter ( ) . map ( |s| s. bytes ( ) ) ;
243
+
244
+ // FIXME: don't allocate for single or dual field structs
245
+ let dest = self . force_allocation ( lvalue) ?. to_ptr ( ) ;
246
+
247
+ for ( offset, ( value, value_ty) ) in offsets. into_iter ( ) . zip ( args) {
248
+ let field_dest = dest. offset ( offset) ;
249
+ self . write_value_to_ptr ( value, field_dest, value_ty) ?;
250
+ }
251
+ } ,
252
+ // FIXME: enum variant constructors
253
+ _ => bug ! ( "bad layout for tuple struct constructor: {:?}" , dest_layout) ,
254
+ }
255
+ self . goto_block ( target) ;
256
+ return Ok ( ( ) ) ;
257
+ }
258
+ }
259
+
232
260
let mir = self . load_mir ( resolved_def_id) ?;
233
261
let ( return_lvalue, return_to_block) = match destination {
234
262
Some ( ( lvalue, block) ) => ( lvalue, StackPopCleanup :: Goto ( block) ) ,
0 commit comments