Skip to content

Commit 7c430e7

Browse files
committed
automatically implement TrivialClone for closures and tuples
If each of the component types is `TrivialClone`, the closure/tuple itself can be trivially cloned.
1 parent 7b72cc6 commit 7c430e7

File tree

9 files changed

+27
-5
lines changed

9 files changed

+27
-5
lines changed

compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ language_item_table! {
176176
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
177177
CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
178178
UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None;
179+
TrivialClone, sym::trivial_clone, trivial_clone_trait, Target::Trait, GenericRequirement::None;
179180
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
180181
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
181182
/// The associated item of the `DiscriminantKind` trait.

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,7 @@ bidirectional_lang_item_map! {
856856
PointeeTrait,
857857
Sized,
858858
TransmuteTrait,
859+
TrivialClone,
859860
Tuple,
860861
Unpin,
861862
Unsize,

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,11 @@ where
547547
Some(SolverTraitLangItem::PointeeSized) => {
548548
unreachable!("`PointeeSized` is removed during lowering");
549549
}
550-
Some(SolverTraitLangItem::Copy | SolverTraitLangItem::Clone) => {
551-
G::consider_builtin_copy_clone_candidate(self, goal)
552-
}
550+
Some(
551+
SolverTraitLangItem::Copy
552+
| SolverTraitLangItem::Clone
553+
| SolverTraitLangItem::TrivialClone,
554+
) => G::consider_builtin_copy_clone_candidate(self, goal),
553555
Some(SolverTraitLangItem::Fn) => {
554556
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
555557
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,7 @@ symbols! {
22712271
transparent_enums,
22722272
transparent_unions,
22732273
trivial_bounds,
2274+
trivial_clone,
22742275
truncf16,
22752276
truncf32,
22762277
truncf64,

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6767

6868
let lang_item = tcx.as_lang_item(def_id);
6969
match lang_item {
70-
Some(LangItem::Copy | LangItem::Clone) => {
70+
Some(LangItem::Copy | LangItem::Clone | LangItem::TrivialClone) => {
7171
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
7272

7373
// User-defined copy impls are permitted, but only for

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
249249
Some(LangItem::PointeeSized) => {
250250
bug!("`PointeeSized` is removing during lowering");
251251
}
252-
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty),
252+
Some(LangItem::Copy | LangItem::Clone | LangItem::TrivialClone) => {
253+
self.copy_clone_conditions(self_ty)
254+
}
253255
Some(LangItem::FusedIterator) => {
254256
if self.coroutine_is_gen(self_ty) {
255257
ty::Binder::dummy(vec![])

compiler/rustc_type_ir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub enum SolverTraitLangItem {
4848
PointeeTrait,
4949
Sized,
5050
TransmuteTrait,
51+
TrivialClone,
5152
Tuple,
5253
Unpin,
5354
Unsize,

library/core/src/clone.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ pub const trait Clone: Sized {
269269
issue = "none"
270270
)]
271271
#[rustc_const_unstable(feature = "const_clone", issue = "142757")]
272+
#[lang = "trivial_clone"]
272273
// SAFETY:
273274
// It is sound to specialize on this because the `clone` implementation cannot be
274275
// lifetime-dependent. Therefore, if `TrivialClone` is implemented for any lifetime,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ run-pass
2+
// Check that closures implement `TrivialClone`.
3+
4+
#![feature(trivial_clone)]
5+
6+
use std::clone::TrivialClone;
7+
8+
fn require_trivial_clone<T: TrivialClone>(_t: T) {}
9+
10+
fn main() {
11+
let some_trivial_clone_value = 42i32;
12+
require_trivial_clone(move || some_trivial_clone_value);
13+
}

0 commit comments

Comments
 (0)