@@ -11,6 +11,7 @@ use rustc_middle::thir::*;
11
11
use rustc_middle:: ty:: { CanonicalUserTypeAnnotation , Ty } ;
12
12
use rustc_span:: DUMMY_SP ;
13
13
use rustc_span:: source_map:: Spanned ;
14
+ use rustc_trait_selection:: infer:: InferCtxtExt ;
14
15
use tracing:: { debug, instrument} ;
15
16
16
17
use crate :: builder:: expr:: category:: { Category , RvalueFunc } ;
@@ -287,28 +288,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
287
288
let place = unpack ! ( block = this. as_place( block, expr) ) ;
288
289
let ty = place. ty ( & this. local_decls , this. tcx ) . ty ;
289
290
290
- let success = this. cfg . start_new_block ( ) ;
291
- let clone_trait = this. tcx . require_lang_item ( LangItem :: Clone , None ) ;
292
- let clone_fn = this. tcx . associated_item_def_ids ( clone_trait) [ 0 ] ;
293
- let func = Operand :: function_handle ( this. tcx , clone_fn, [ ty. into ( ) ] , expr_span) ;
294
- let ref_ty = Ty :: new_imm_ref ( this. tcx , this. tcx . lifetimes . re_erased , ty) ;
295
- let ref_place = this. temp ( ref_ty, span) ;
296
- this. cfg . push_assign (
297
- block,
298
- source_info,
299
- ref_place,
300
- Rvalue :: Ref ( this. tcx . lifetimes . re_erased , BorrowKind :: Shared , place) ,
301
- ) ;
302
- this. cfg . terminate ( block, source_info, TerminatorKind :: Call {
303
- func,
304
- args : [ Spanned { node : Operand :: Move ( ref_place) , span : DUMMY_SP } ] . into ( ) ,
305
- destination,
306
- target : Some ( success) ,
307
- unwind : UnwindAction :: Unreachable ,
308
- call_source : CallSource :: Misc ,
309
- fn_span : expr_span,
310
- } ) ;
311
- success. unit ( )
291
+ if this. tcx . type_is_copy_modulo_regions ( this. infcx . typing_env ( this. param_env ) , ty) {
292
+ this. cfg . push_assign (
293
+ block,
294
+ source_info,
295
+ destination,
296
+ Rvalue :: Use ( Operand :: Copy ( place) ) ,
297
+ ) ;
298
+ block. unit ( )
299
+ } else if this. infcx . type_is_use_cloned_modulo_regions ( this. param_env , ty) {
300
+ let success = this. cfg . start_new_block ( ) ;
301
+ let clone_trait = this. tcx . require_lang_item ( LangItem :: Clone , None ) ;
302
+ let clone_fn = this. tcx . associated_item_def_ids ( clone_trait) [ 0 ] ;
303
+ let func = Operand :: function_handle ( this. tcx , clone_fn, [ ty. into ( ) ] , expr_span) ;
304
+ let ref_ty = Ty :: new_imm_ref ( this. tcx , this. tcx . lifetimes . re_erased , ty) ;
305
+ let ref_place = this. temp ( ref_ty, span) ;
306
+ this. cfg . push_assign (
307
+ block,
308
+ source_info,
309
+ ref_place,
310
+ Rvalue :: Ref ( this. tcx . lifetimes . re_erased , BorrowKind :: Shared , place) ,
311
+ ) ;
312
+ this. cfg . terminate ( block, source_info, TerminatorKind :: Call {
313
+ func,
314
+ args : [ Spanned { node : Operand :: Move ( ref_place) , span : DUMMY_SP } ] . into ( ) ,
315
+ destination,
316
+ target : Some ( success) ,
317
+ unwind : UnwindAction :: Unreachable ,
318
+ call_source : CallSource :: Misc ,
319
+ fn_span : expr_span,
320
+ } ) ;
321
+ success. unit ( )
322
+ } else {
323
+ this. cfg . push_assign (
324
+ block,
325
+ source_info,
326
+ destination,
327
+ Rvalue :: Use ( Operand :: Move ( place) ) ,
328
+ ) ;
329
+ block. unit ( )
330
+ }
312
331
}
313
332
ExprKind :: Use { source } => this. expr_into_dest ( destination, block, source) ,
314
333
ExprKind :: Borrow { arg, borrow_kind } => {
0 commit comments