@@ -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 } ;
@@ -295,33 +296,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
295
296
let place = unpack ! ( block = this. as_place( block, expr) ) ;
296
297
let ty = place. ty ( & this. local_decls , this. tcx ) . ty ;
297
298
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,
317
303
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
+ }
325
345
}
326
346
ExprKind :: Use { source } => this. expr_into_dest ( destination, block, source) ,
327
347
ExprKind :: Borrow { arg, borrow_kind } => {
0 commit comments