@@ -11,6 +11,7 @@ use rustc_middle::thir::*;
1111use rustc_middle:: ty:: { CanonicalUserTypeAnnotation , Ty } ;
1212use rustc_span:: DUMMY_SP ;
1313use rustc_span:: source_map:: Spanned ;
14+ use rustc_trait_selection:: infer:: InferCtxtExt ;
1415use tracing:: { debug, instrument} ;
1516
1617use crate :: builder:: expr:: category:: { Category , RvalueFunc } ;
@@ -287,28 +288,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
287288 let place = unpack ! ( block = this. as_place( block, expr) ) ;
288289 let ty = place. ty ( & this. local_decls , this. tcx ) . ty ;
289290
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+ }
312331 }
313332 ExprKind :: Use { source } => this. expr_into_dest ( destination, block, source) ,
314333 ExprKind :: Borrow { arg, borrow_kind } => {
0 commit comments