Skip to content

Commit 0c3ac64

Browse files
committed
Make Clone a lang item and generate builtin impls.
Fixes #28229. Fixes #24000.
1 parent b1ff235 commit 0c3ac64

File tree

17 files changed

+313
-32
lines changed

17 files changed

+313
-32
lines changed

src/libcore/array.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ macro_rules! array_impls {
124124
}
125125

126126
#[stable(feature = "rust1", since = "1.0.0")]
127+
#[cfg(stage0)]
127128
impl<T:Copy> Clone for [T; $N] {
128129
fn clone(&self) -> [T; $N] {
129130
*self

src/libcore/clone.rs

+3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
/// }
8989
/// ```
9090
#[stable(feature = "rust1", since = "1.0.0")]
91+
#[cfg_attr(not(stage0), lang = "clone")]
9192
pub trait Clone : Sized {
9293
/// Returns a copy of the value.
9394
///
@@ -131,6 +132,7 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: ::marker::PhantomData
131132
pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T> }
132133

133134
#[stable(feature = "rust1", since = "1.0.0")]
135+
#[cfg(stage0)]
134136
impl<'a, T: ?Sized> Clone for &'a T {
135137
/// Returns a shallow copy of the reference.
136138
#[inline]
@@ -140,6 +142,7 @@ impl<'a, T: ?Sized> Clone for &'a T {
140142
macro_rules! clone_impl {
141143
($t:ty) => {
142144
#[stable(feature = "rust1", since = "1.0.0")]
145+
#[cfg(stage0)]
143146
impl Clone for $t {
144147
/// Returns a deep copy of the value.
145148
#[inline]

src/libcore/ptr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
876876
}
877877

878878
#[stable(feature = "rust1", since = "1.0.0")]
879+
#[cfg(stage0)]
879880
impl<T: ?Sized> Clone for *const T {
880881
#[inline]
881882
fn clone(&self) -> *const T {
@@ -884,6 +885,7 @@ impl<T: ?Sized> Clone for *const T {
884885
}
885886

886887
#[stable(feature = "rust1", since = "1.0.0")]
888+
#[cfg(stage0)]
887889
impl<T: ?Sized> Clone for *mut T {
888890
#[inline]
889891
fn clone(&self) -> *mut T {
@@ -895,6 +897,7 @@ impl<T: ?Sized> Clone for *mut T {
895897
macro_rules! fnptr_impls_safety_abi {
896898
($FnTy: ty, $($Arg: ident),*) => {
897899
#[stable(feature = "rust1", since = "1.0.0")]
900+
#[cfg(stage0)]
898901
impl<Ret, $($Arg),*> Clone for $FnTy {
899902
#[inline]
900903
fn clone(&self) -> Self {

src/libcore/tuple.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ macro_rules! tuple_impls {
2222
)+) => {
2323
$(
2424
#[stable(feature = "rust1", since = "1.0.0")]
25+
#[cfg(stage0)]
2526
impl<$($T:Clone),+> Clone for ($($T,)+) {
2627
fn clone(&self) -> ($($T,)+) {
2728
($(self.$idx.clone(),)+)

src/librustc/ich/impls_ty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::In
721721
def_id.hash_stable(hcx, hasher);
722722
t.hash_stable(hcx, hasher);
723723
}
724+
ty::InstanceDef::BuiltinShim(def_id, t) => {
725+
def_id.hash_stable(hcx, hasher);
726+
t.hash_stable(hcx, hasher);
727+
}
724728
}
725729
}
726730
}

src/librustc/middle/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ language_item_table! {
274274
SizedTraitLangItem, "sized", sized_trait;
275275
UnsizeTraitLangItem, "unsize", unsize_trait;
276276
CopyTraitLangItem, "copy", copy_trait;
277+
CloneTraitLangItem, "clone", clone_trait;
277278
SyncTraitLangItem, "sync", sync_trait;
278279
FreezeTraitLangItem, "freeze", freeze_trait;
279280

@@ -320,6 +321,9 @@ language_item_table! {
320321

321322
StrEqFnLangItem, "str_eq", str_eq_fn;
322323

324+
CloneMethodLangItem, "clone_method", clone_method;
325+
CloneFromMethodLangItem, "clone_from_method", clone_from_method;
326+
323327
// A number of panic-related lang items. The `panic` item corresponds to
324328
// divide-by-zero and various panic cases with `match`. The
325329
// `panic_bounds_check` item is for indexing arrays.

src/librustc/traits/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ pub enum Vtable<'tcx, N> {
301301
VtableObject(VtableObjectData<'tcx, N>),
302302

303303
/// Successful resolution for a builtin trait.
304-
VtableBuiltin(VtableBuiltinData<N>),
304+
VtableBuiltin(VtableBuiltinData<'tcx, N>),
305305

306306
/// Vtable automatically generated for a closure. The def ID is the ID
307307
/// of the closure expression. This is a `VtableImpl` in spirit, but the
@@ -345,7 +345,9 @@ pub struct VtableDefaultImplData<N> {
345345
}
346346

347347
#[derive(Clone)]
348-
pub struct VtableBuiltinData<N> {
348+
pub struct VtableBuiltinData<'tcx, N> {
349+
/// `ty` can be used for generating shim for builtin implementations like `Clone::clone`.
350+
pub ty: ty::Ty<'tcx>,
349351
pub nested: Vec<N>
350352
}
351353

@@ -769,6 +771,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
769771
}),
770772
VtableParam(n) => VtableParam(n.into_iter().map(f).collect()),
771773
VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData {
774+
ty: i.ty,
772775
nested: i.nested.into_iter().map(f).collect(),
773776
}),
774777
VtableObject(o) => VtableObject(VtableObjectData {

src/librustc/traits/select.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12961296
} else if self.tcx().lang_items.unsize_trait() == Some(def_id) {
12971297
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
12981298
} else {
1299+
if self.tcx().lang_items.clone_trait() == Some(def_id) {
1300+
// Same builtin conditions as `Copy`, i.e. every type which has builtin support
1301+
// for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone`
1302+
// types have builtin support for `Clone`.
1303+
let clone_conditions = self.copy_conditions(obligation);
1304+
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates)?;
1305+
}
1306+
12991307
self.assemble_closure_candidates(obligation, &mut candidates)?;
13001308
self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
13011309
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
@@ -2164,8 +2172,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
21642172

21652173
match candidate {
21662174
BuiltinCandidate { has_nested } => {
2167-
Ok(VtableBuiltin(
2168-
self.confirm_builtin_candidate(obligation, has_nested)))
2175+
let data = self.confirm_builtin_candidate(obligation, has_nested);
2176+
Ok(VtableBuiltin(data))
21692177
}
21702178

21712179
ParamCandidate(param) => {
@@ -2257,7 +2265,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22572265
fn confirm_builtin_candidate(&mut self,
22582266
obligation: &TraitObligation<'tcx>,
22592267
has_nested: bool)
2260-
-> VtableBuiltinData<PredicateObligation<'tcx>>
2268+
-> VtableBuiltinData<'tcx, PredicateObligation<'tcx>>
22612269
{
22622270
debug!("confirm_builtin_candidate({:?}, {:?})",
22632271
obligation, has_nested);
@@ -2271,6 +2279,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22712279
_ if Some(trait_def) == self.tcx().lang_items.copy_trait() => {
22722280
self.copy_conditions(obligation)
22732281
}
2282+
_ if Some(trait_def) == self.tcx().lang_items.clone_trait() => {
2283+
self.copy_conditions(obligation)
2284+
}
22742285
_ => bug!("unexpected builtin trait {:?}", trait_def)
22752286
};
22762287
let nested = match conditions {
@@ -2291,7 +2302,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22912302

22922303
debug!("confirm_builtin_candidate: obligations={:?}",
22932304
obligations);
2294-
VtableBuiltinData { nested: obligations }
2305+
2306+
let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
2307+
VtableBuiltinData { ty: self_ty, nested: obligations }
22952308
}
22962309

22972310
/// This handles the case where a `impl Foo for ..` impl is being used.
@@ -2598,8 +2611,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25982611

25992612
fn confirm_builtin_unsize_candidate(&mut self,
26002613
obligation: &TraitObligation<'tcx>,)
2601-
-> Result<VtableBuiltinData<PredicateObligation<'tcx>>,
2602-
SelectionError<'tcx>> {
2614+
-> Result<VtableBuiltinData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
2615+
{
26032616
let tcx = self.tcx();
26042617

26052618
// assemble_candidates_for_unsizing should ensure there are no late bound
@@ -2801,7 +2814,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
28012814
_ => bug!()
28022815
};
28032816

2804-
Ok(VtableBuiltinData { nested: nested })
2817+
Ok(VtableBuiltinData { ty: source, nested: nested })
28052818
}
28062819

28072820
///////////////////////////////////////////////////////////////////////////

src/librustc/traits/structural_impls.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
8686
}
8787
}
8888

89-
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
89+
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<'tcx, N> {
9090
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91-
write!(f, "VtableBuiltin(nested={:?})", self.nested)
91+
write!(f, "VtableBuiltin(ty={:?}, nested={:?})", self.ty, self.nested)
9292
}
9393
}
9494

@@ -300,7 +300,14 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
300300
})
301301
}
302302
traits::VtableParam(n) => Some(traits::VtableParam(n)),
303-
traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)),
303+
traits::VtableBuiltin(traits::VtableBuiltinData { ty, nested }) => {
304+
tcx.lift(&ty).map(|ty| {
305+
traits::VtableBuiltin(traits::VtableBuiltinData {
306+
ty,
307+
nested,
308+
})
309+
})
310+
}
304311
traits::VtableObject(traits::VtableObjectData {
305312
upcast_trait_ref,
306313
vtable_base,
@@ -378,9 +385,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultIm
378385
}
379386
}
380387

381-
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
388+
impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<'tcx, N> {
382389
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
383390
traits::VtableBuiltinData {
391+
ty: self.ty.fold_with(folder),
384392
nested: self.nested.fold_with(folder),
385393
}
386394
}

src/librustc/ty/instance.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,22 @@ pub struct Instance<'tcx> {
2424
pub enum InstanceDef<'tcx> {
2525
Item(DefId),
2626
Intrinsic(DefId),
27-
// <fn() as FnTrait>::call_*
28-
// def-id is FnTrait::call_*
27+
28+
/// <fn() as FnTrait>::call_*
29+
/// def-id is FnTrait::call_*
2930
FnPtrShim(DefId, Ty<'tcx>),
30-
// <Trait as Trait>::fn
31+
32+
/// <Trait as Trait>::fn
3133
Virtual(DefId, usize),
32-
// <[mut closure] as FnOnce>::call_once
34+
35+
/// <[mut closure] as FnOnce>::call_once
3336
ClosureOnceShim { call_once: DefId },
34-
// drop_in_place::<T>; None for empty drop glue.
37+
38+
/// drop_in_place::<T>; None for empty drop glue.
3539
DropGlue(DefId, Option<Ty<'tcx>>),
40+
41+
/// Builtin method implementation, e.g. `Clone::clone`.
42+
BuiltinShim(DefId, Ty<'tcx>),
3643
}
3744

3845
impl<'tcx> InstanceDef<'tcx> {
@@ -43,9 +50,9 @@ impl<'tcx> InstanceDef<'tcx> {
4350
InstanceDef::FnPtrShim(def_id, _) |
4451
InstanceDef::Virtual(def_id, _) |
4552
InstanceDef::Intrinsic(def_id, ) |
46-
InstanceDef::ClosureOnceShim { call_once: def_id }
47-
=> def_id,
48-
InstanceDef::DropGlue(def_id, _) => def_id
53+
InstanceDef::ClosureOnceShim { call_once: def_id } |
54+
InstanceDef::DropGlue(def_id, _) |
55+
InstanceDef::BuiltinShim(def_id, _) => def_id
4956
}
5057
}
5158

@@ -80,6 +87,9 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
8087
InstanceDef::DropGlue(_, ty) => {
8188
write!(f, " - shim({:?})", ty)
8289
}
90+
InstanceDef::BuiltinShim(_, ty) => {
91+
write!(f, " - shim({:?})", ty)
92+
}
8393
}
8494
}
8595
}

src/librustc/ty/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2227,7 +2227,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
22272227
ty::InstanceDef::FnPtrShim(..) |
22282228
ty::InstanceDef::Virtual(..) |
22292229
ty::InstanceDef::ClosureOnceShim { .. } |
2230-
ty::InstanceDef::DropGlue(..) => {
2230+
ty::InstanceDef::DropGlue(..) |
2231+
ty::InstanceDef::BuiltinShim(..) => {
22312232
self.mir_shims(instance)
22322233
}
22332234
}

0 commit comments

Comments
 (0)