Skip to content

Commit c5e262c

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 ba97294 commit c5e262c

File tree

9 files changed

+28
-4
lines changed

9 files changed

+28
-4
lines changed

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ language_item_table! {
172172
Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None;
173173
CloneFn, sym::clone_fn, clone_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
174174
UseCloned, sym::use_cloned, use_cloned_trait, Target::Trait, GenericRequirement::None;
175+
TrivialClone, sym::trivial_clone, trivial_clone_trait, Target::Trait, GenericRequirement::None;
175176
Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0);
176177
DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None;
177178
/// The associated item of the `DiscriminantKind` trait.

compiler/rustc_middle/src/ty/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ bidirectional_lang_item_map! {
719719
Poll,
720720
Sized,
721721
TransmuteTrait,
722+
TrivialClone,
722723
Tuple,
723724
Unpin,
724725
Unsize,

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,11 @@ where
397397
} else {
398398
match cx.as_lang_item(trait_def_id) {
399399
Some(TraitSolverLangItem::Sized) => G::consider_builtin_sized_candidate(self, goal),
400-
Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => {
401-
G::consider_builtin_copy_clone_candidate(self, goal)
402-
}
400+
Some(
401+
TraitSolverLangItem::Copy
402+
| TraitSolverLangItem::Clone
403+
| TraitSolverLangItem::TrivialClone,
404+
) => G::consider_builtin_copy_clone_candidate(self, goal),
403405
Some(TraitSolverLangItem::Fn) => {
404406
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
405407
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2082,6 +2082,7 @@ symbols! {
20822082
transparent_enums,
20832083
transparent_unions,
20842084
trivial_bounds,
2085+
trivial_clone,
20852086
truncf128,
20862087
truncf16,
20872088
truncf32,

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
108108
&mut candidates,
109109
);
110110
} else {
111-
if tcx.is_lang_item(def_id, LangItem::Clone) {
111+
if tcx.is_lang_item(def_id, LangItem::Clone)
112+
|| tcx.is_lang_item(def_id, LangItem::TrivialClone)
113+
{
112114
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
113115
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
114116
// types have builtin support for `Clone`.

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

+2
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
261261
self.copy_clone_conditions(obligation)
262262
} else if tcx.is_lang_item(trait_def, LangItem::Clone) {
263263
self.copy_clone_conditions(obligation)
264+
} else if tcx.is_lang_item(trait_def, LangItem::TrivialClone) {
265+
self.copy_clone_conditions(obligation)
264266
} else if tcx.is_lang_item(trait_def, LangItem::FusedIterator) {
265267
self.fused_iterator_conditions(obligation)
266268
} else {

compiler/rustc_type_ir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub enum TraitSolverLangItem {
3636
Poll,
3737
Sized,
3838
TransmuteTrait,
39+
TrivialClone,
3940
Tuple,
4041
Unpin,
4142
Unsize,

library/core/src/clone.rs

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ pub trait Clone: Sized {
194194
reason = "this isn't part of any API guarantee",
195195
issue = "none"
196196
)]
197+
#[cfg_attr(not(bootstrap), lang = "trivial_clone")]
197198
// SAFETY:
198199
// It is sound to specialize on this because the `clone` implementation cannot be
199200
// lifetime-dependent. Therefore, if `TrivialClone` is implemented for any lifetime,
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)