@@ -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 } ;
@@ -295,33 +296,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
295296 let place = unpack ! ( block = this. as_place( block, expr) ) ;
296297 let ty = place. ty ( & this. local_decls , this. tcx ) . ty ;
297298
298- // Convert `expr.use` to a call like `Clone::clone(&expr)`
299- let success = this. cfg . start_new_block ( ) ;
300- let clone_trait = this. tcx . require_lang_item ( LangItem :: Clone , None ) ;
301- let clone_fn = this. tcx . associated_item_def_ids ( clone_trait) [ 0 ] ;
302- let func = Operand :: function_handle ( this. tcx , clone_fn, [ ty. into ( ) ] , expr_span) ;
303- let ref_ty = Ty :: new_imm_ref ( this. tcx , this. tcx . lifetimes . re_erased , ty) ;
304- let ref_place = this. temp ( ref_ty, span) ;
305- this. cfg . push_assign (
306- block,
307- source_info,
308- ref_place,
309- Rvalue :: Ref ( this. tcx . lifetimes . re_erased , BorrowKind :: Shared , place) ,
310- ) ;
311- this. cfg . terminate (
312- block,
313- source_info,
314- TerminatorKind :: Call {
315- func,
316- args : [ Spanned { node : Operand :: Move ( ref_place) , span : DUMMY_SP } ] . into ( ) ,
299+ if this. tcx . type_is_copy_modulo_regions ( this. infcx . typing_env ( this. param_env ) , ty) {
300+ this. cfg . push_assign (
301+ block,
302+ source_info,
317303 destination,
318- target : Some ( success) ,
319- unwind : UnwindAction :: Unreachable ,
320- call_source : CallSource :: Misc ,
321- fn_span : expr_span,
322- } ,
323- ) ;
324- success. unit ( )
304+ Rvalue :: Use ( Operand :: Copy ( place) ) ,
305+ ) ;
306+ block. unit ( )
307+ } else if this. infcx . type_is_use_cloned_modulo_regions ( this. param_env , ty) {
308+ // Convert `expr.use` to a call like `Clone::clone(&expr)`
309+ let success = this. cfg . start_new_block ( ) ;
310+ let clone_trait = this. tcx . require_lang_item ( LangItem :: Clone , None ) ;
311+ let clone_fn = this. tcx . associated_item_def_ids ( clone_trait) [ 0 ] ;
312+ let func = Operand :: function_handle ( this. tcx , clone_fn, [ ty. into ( ) ] , expr_span) ;
313+ let ref_ty = Ty :: new_imm_ref ( this. tcx , this. tcx . lifetimes . re_erased , ty) ;
314+ let ref_place = this. temp ( ref_ty, span) ;
315+ this. cfg . push_assign (
316+ block,
317+ source_info,
318+ ref_place,
319+ Rvalue :: Ref ( this. tcx . lifetimes . re_erased , BorrowKind :: Shared , place) ,
320+ ) ;
321+ this. cfg . terminate (
322+ block,
323+ source_info,
324+ TerminatorKind :: Call {
325+ func,
326+ args : [ Spanned { node : Operand :: Move ( ref_place) , span : DUMMY_SP } ]
327+ . into ( ) ,
328+ destination,
329+ target : Some ( success) ,
330+ unwind : UnwindAction :: Unreachable ,
331+ call_source : CallSource :: Misc ,
332+ fn_span : expr_span,
333+ } ,
334+ ) ;
335+ success. unit ( )
336+ } else {
337+ this. cfg . push_assign (
338+ block,
339+ source_info,
340+ destination,
341+ Rvalue :: Use ( Operand :: Move ( place) ) ,
342+ ) ;
343+ block. unit ( )
344+ }
325345 }
326346 ExprKind :: Use { source } => this. expr_into_dest ( destination, block, source) ,
327347 ExprKind :: Borrow { arg, borrow_kind } => {
0 commit comments