diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2024-12-11 18:00:56 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2025-03-06 17:58:32 -0300 |
| commit | dcdfd551f05073ececfa437be002ce7804b31c91 (patch) | |
| tree | 813604b622c9bb09c15e1724a6cebfd9d340b53d /compiler | |
| parent | 57cb498989ac29fbe9938ed2f4a31a3eab6850dc (diff) | |
| download | rust-dcdfd551f05073ececfa437be002ce7804b31c91.tar.gz rust-dcdfd551f05073ececfa437be002ce7804b31c91.zip | |
Add UseCloned trait related code
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir/src/lang_items.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/builder/expr/into.rs | 72 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/infer.rs | 10 |
4 files changed, 58 insertions, 26 deletions
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index f5626937ec4..2c73ea6a11a 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -171,6 +171,7 @@ language_item_table! { Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0); Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None; CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; + UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None; Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0); DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None; /// The associated item of the `DiscriminantKind` trait. diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index d89f3773e4a..333e69475c5 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -11,6 +11,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::{CanonicalUserTypeAnnotation, Ty}; use rustc_span::DUMMY_SP; use rustc_span::source_map::Spanned; +use rustc_trait_selection::infer::InferCtxtExt; use tracing::{debug, instrument}; use crate::builder::expr::category::{Category, RvalueFunc}; @@ -295,33 +296,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let place = unpack!(block = this.as_place(block, expr)); let ty = place.ty(&this.local_decls, this.tcx).ty; - // Convert `expr.use` to a call like `Clone::clone(&expr)` - let success = this.cfg.start_new_block(); - let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); - let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; - let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); - let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); - let ref_place = this.temp(ref_ty, span); - this.cfg.push_assign( - block, - source_info, - ref_place, - Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place), - ); - this.cfg.terminate( - block, - source_info, - TerminatorKind::Call { - func, - args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }].into(), + if this.tcx.type_is_copy_modulo_regions(this.infcx.typing_env(this.param_env), ty) { + this.cfg.push_assign( + block, + source_info, destination, - target: Some(success), - unwind: UnwindAction::Unreachable, - call_source: CallSource::Misc, - fn_span: expr_span, - }, - ); - success.unit() + Rvalue::Use(Operand::Copy(place)), + ); + block.unit() + } else if this.infcx.type_is_use_cloned_modulo_regions(this.param_env, ty) { + // Convert `expr.use` to a call like `Clone::clone(&expr)` + let success = this.cfg.start_new_block(); + let clone_trait = this.tcx.require_lang_item(LangItem::Clone, None); + let clone_fn = this.tcx.associated_item_def_ids(clone_trait)[0]; + let func = Operand::function_handle(this.tcx, clone_fn, [ty.into()], expr_span); + let ref_ty = Ty::new_imm_ref(this.tcx, this.tcx.lifetimes.re_erased, ty); + let ref_place = this.temp(ref_ty, span); + this.cfg.push_assign( + block, + source_info, + ref_place, + Rvalue::Ref(this.tcx.lifetimes.re_erased, BorrowKind::Shared, place), + ); + this.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func, + args: [Spanned { node: Operand::Move(ref_place), span: DUMMY_SP }] + .into(), + destination, + target: Some(success), + unwind: UnwindAction::Unreachable, + call_source: CallSource::Misc, + fn_span: expr_span, + }, + ); + success.unit() + } else { + this.cfg.push_assign( + block, + source_info, + destination, + Rvalue::Use(Operand::Move(place)), + ); + block.unit() + } } ExprKind::Use { source } => this.expr_into_dest(destination, block, source), ExprKind::Borrow { arg, borrow_kind } => { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3357e085a7d..a8c38d8244d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2182,6 +2182,7 @@ symbols! { unwrap, unwrap_binder, unwrap_or, + use_cloned, use_extern_macros, use_nested_groups, used, diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index f373706b296..5cf0600ade8 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -53,6 +53,16 @@ impl<'tcx> InferCtxt<'tcx> { traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, clone_def_id) } + fn type_is_use_cloned_modulo_regions( + &self, + param_env: ty::ParamEnv<'tcx>, + ty: Ty<'tcx>, + ) -> bool { + let ty = self.resolve_vars_if_possible(ty); + let use_cloned_def_id = self.tcx.require_lang_item(LangItem::UseCloned, None); + traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, use_cloned_def_id) + } + fn type_is_sized_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); traits::type_known_to_meet_bound_modulo_regions(self, param_env, ty, lang_item) |
