diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 4b7706bac300f..b44738b795db3 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -124,7 +124,6 @@ macro_rules! array_impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(stage0)] impl Clone for [T; $N] { fn clone(&self) -> [T; $N] { *self diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 2dc51718b97b2..8856d0b8cb9de 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -88,7 +88,6 @@ /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(not(stage0), lang = "clone")] pub trait Clone : Sized { /// Returns a copy of the value. /// @@ -132,7 +131,6 @@ pub struct AssertParamIsClone { _field: ::marker::PhantomData pub struct AssertParamIsCopy { _field: ::marker::PhantomData } #[stable(feature = "rust1", since = "1.0.0")] -#[cfg(stage0)] impl<'a, T: ?Sized> Clone for &'a T { /// Returns a shallow copy of the reference. #[inline] @@ -142,7 +140,6 @@ impl<'a, T: ?Sized> Clone for &'a T { macro_rules! clone_impl { ($t:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(stage0)] impl Clone for $t { /// Returns a deep copy of the value. #[inline] diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 63e9373e93606..e35777d222c06 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -876,7 +876,6 @@ pub fn eq(a: *const T, b: *const T) -> bool { } #[stable(feature = "rust1", since = "1.0.0")] -#[cfg(stage0)] impl Clone for *const T { #[inline] fn clone(&self) -> *const T { @@ -885,7 +884,6 @@ impl Clone for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -#[cfg(stage0)] impl Clone for *mut T { #[inline] fn clone(&self) -> *mut T { @@ -897,7 +895,6 @@ impl Clone for *mut T { macro_rules! fnptr_impls_safety_abi { ($FnTy: ty, $($Arg: ident),*) => { #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(stage0)] impl Clone for $FnTy { #[inline] fn clone(&self) -> Self { diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 555843dba418e..47e9c7c903880 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -22,7 +22,6 @@ macro_rules! tuple_impls { )+) => { $( #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(stage0)] impl<$($T:Clone),+> Clone for ($($T,)+) { fn clone(&self) -> ($($T,)+) { ($(self.$idx.clone(),)+) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 5f51579945e33..45b2a4a1e9667 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -663,10 +663,6 @@ impl<'a, 'gcx, 'tcx> HashStable> for ty::In def_id.hash_stable(hcx, hasher); t.hash_stable(hcx, hasher); } - ty::InstanceDef::CloneShim(def_id, t) => { - def_id.hash_stable(hcx, hasher); - t.hash_stable(hcx, hasher); - } } } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 9ba4252b52e57..01ed79096b101 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -274,7 +274,6 @@ language_item_table! { SizedTraitLangItem, "sized", sized_trait; UnsizeTraitLangItem, "unsize", unsize_trait; CopyTraitLangItem, "copy", copy_trait; - CloneTraitLangItem, "clone", clone_trait; SyncTraitLangItem, "sync", sync_trait; FreezeTraitLangItem, "freeze", freeze_trait; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 46bdb1344b2fe..3e39d5921351f 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1296,14 +1296,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } else if self.tcx().lang_items.unsize_trait() == Some(def_id) { self.assemble_candidates_for_unsizing(obligation, &mut candidates); } else { - if self.tcx().lang_items.clone_trait() == Some(def_id) { - // Same builtin conditions as `Copy`, i.e. every type which has builtin support - // for `Copy` also has builtin support for `Clone`, + tuples and arrays of `Clone` - // types have builtin support for `Clone`. - let clone_conditions = self.copy_conditions(obligation); - self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates)?; - } - self.assemble_closure_candidates(obligation, &mut candidates)?; self.assemble_fn_pointer_candidates(obligation, &mut candidates)?; self.assemble_candidates_from_impls(obligation, &mut candidates)?; @@ -2172,8 +2164,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match candidate { BuiltinCandidate { has_nested } => { - let data = self.confirm_builtin_candidate(obligation, has_nested); - Ok(VtableBuiltin(data)) + Ok(VtableBuiltin( + self.confirm_builtin_candidate(obligation, has_nested))) } ParamCandidate(param) => { @@ -2279,9 +2271,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { _ if Some(trait_def) == self.tcx().lang_items.copy_trait() => { self.copy_conditions(obligation) } - _ if Some(trait_def) == self.tcx().lang_items.clone_trait() => { - self.copy_conditions(obligation) - } _ => bug!("unexpected builtin trait {:?}", trait_def) }; let nested = match conditions { @@ -2302,7 +2291,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("confirm_builtin_candidate: obligations={:?}", obligations); - VtableBuiltinData { nested: obligations } } @@ -2610,8 +2598,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn confirm_builtin_unsize_candidate(&mut self, obligation: &TraitObligation<'tcx>,) - -> Result>, SelectionError<'tcx>> - { + -> Result>, + SelectionError<'tcx>> { let tcx = self.tcx(); // assemble_candidates_for_unsizing should ensure there are no late bound diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index d913c76ec3c09..e80e82fa94ff6 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -300,7 +300,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { }) } traits::VtableParam(n) => Some(traits::VtableParam(n)), - traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)), + traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)), traits::VtableObject(traits::VtableObjectData { upcast_trait_ref, vtable_base, diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 7d543f689c24d..32063a2dda603 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -24,22 +24,15 @@ pub struct Instance<'tcx> { pub enum InstanceDef<'tcx> { Item(DefId), Intrinsic(DefId), - - /// ::call_* - /// def-id is FnTrait::call_* + // ::call_* + // def-id is FnTrait::call_* FnPtrShim(DefId, Ty<'tcx>), - - /// ::fn + // ::fn Virtual(DefId, usize), - - /// <[mut closure] as FnOnce>::call_once + // <[mut closure] as FnOnce>::call_once ClosureOnceShim { call_once: DefId }, - - /// drop_in_place::; None for empty drop glue. + // drop_in_place::; None for empty drop glue. DropGlue(DefId, Option>), - - /// Builtin method implementation, e.g. `Clone::clone`. - CloneShim(DefId, Ty<'tcx>), } impl<'tcx> InstanceDef<'tcx> { @@ -50,9 +43,9 @@ impl<'tcx> InstanceDef<'tcx> { InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id, ) | - InstanceDef::ClosureOnceShim { call_once: def_id } | - InstanceDef::DropGlue(def_id, _) | - InstanceDef::CloneShim(def_id, _) => def_id + InstanceDef::ClosureOnceShim { call_once: def_id } + => def_id, + InstanceDef::DropGlue(def_id, _) => def_id } } @@ -87,9 +80,6 @@ impl<'tcx> fmt::Display for Instance<'tcx> { InstanceDef::DropGlue(_, ty) => { write!(f, " - shim({:?})", ty) } - InstanceDef::CloneShim(_, ty) => { - write!(f, " - shim({:?})", ty) - } } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f9bbcc1bbe086..7e402075fcfea 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2232,8 +2232,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::Virtual(..) | ty::InstanceDef::ClosureOnceShim { .. } | - ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::CloneShim(..) => { + ty::InstanceDef::DropGlue(..) => { self.mir_shims(instance) } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 6bee1ceff89fb..6b4a8a2dcb7e4 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -17,7 +17,6 @@ use rustc::mir::transform::MirSource; use rustc::ty::{self, Ty}; use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::ty::maps::Providers; -use rustc_const_math::{ConstInt, ConstUsize}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -99,25 +98,14 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, ty::InstanceDef::DropGlue(def_id, ty) => { build_drop_shim(tcx, def_id, ty) } - ty::InstanceDef::CloneShim(def_id, ty) => { - let name = tcx.item_name(def_id).as_str(); - if name == "clone" { - build_clone_shim(tcx, def_id, ty) - } else if name == "clone_from" { - debug!("make_shim({:?}: using default trait implementation", instance); - return tcx.optimized_mir(def_id); - } else { - bug!("builtin clone shim {:?} not supported", instance) - } - } ty::InstanceDef::Intrinsic(_) => { bug!("creating shims from intrinsics ({:?}) is unsupported", instance) } }; - debug!("make_shim({:?}) = untransformed {:?}", instance, result); - no_landing_pads::no_landing_pads(tcx, &mut result); - simplify::simplify_cfg(&mut result); - add_call_guards::CriticalCallEdges.add_call_guards(&mut result); + debug!("make_shim({:?}) = untransformed {:?}", instance, result); + no_landing_pads::no_landing_pads(tcx, &mut result); + simplify::simplify_cfg(&mut result); + add_call_guards::CriticalCallEdges.add_call_guards(&mut result); debug!("make_shim({:?}) = {:?}", instance, result); tcx.alloc_mir(result) @@ -271,374 +259,6 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } } -/// Build a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`. -fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - self_ty: ty::Ty<'tcx>) - -> Mir<'tcx> -{ - debug!("build_clone_shim(def_id={:?})", def_id); - - let mut builder = CloneShimBuilder::new(tcx, def_id); - let is_copy = !self_ty.moves_by_default(tcx, tcx.param_env(def_id), builder.span); - - match self_ty.sty { - _ if is_copy => builder.copy_shim(), - ty::TyArray(ty, len) => builder.array_shim(ty, len), - ty::TyTuple(tys, _) => builder.tuple_shim(tys), - _ => { - bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty); - } - }; - - builder.into_mir() -} - -struct CloneShimBuilder<'a, 'tcx: 'a> { - tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - local_decls: IndexVec>, - blocks: IndexVec>, - span: Span, - sig: ty::FnSig<'tcx>, -} - -impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { - fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Self { - let sig = tcx.fn_sig(def_id); - let sig = tcx.erase_late_bound_regions(&sig); - let span = tcx.def_span(def_id); - - CloneShimBuilder { - tcx, - def_id, - local_decls: local_decls_for_sig(&sig, span), - blocks: IndexVec::new(), - span, - sig, - } - } - - fn into_mir(self) -> Mir<'tcx> { - Mir::new( - self.blocks, - IndexVec::from_elem_n( - VisibilityScopeData { span: self.span, parent_scope: None }, 1 - ), - IndexVec::new(), - self.sig.output(), - self.local_decls, - self.sig.inputs().len(), - vec![], - self.span - ) - } - - fn source_info(&self) -> SourceInfo { - SourceInfo { span: self.span, scope: ARGUMENT_VISIBILITY_SCOPE } - } - - fn block( - &mut self, - statements: Vec>, - kind: TerminatorKind<'tcx>, - is_cleanup: bool - ) -> BasicBlock { - let source_info = self.source_info(); - self.blocks.push(BasicBlockData { - statements, - terminator: Some(Terminator { source_info, kind }), - is_cleanup, - }) - } - - fn make_statement(&self, kind: StatementKind<'tcx>) -> Statement<'tcx> { - Statement { - source_info: self.source_info(), - kind, - } - } - - fn copy_shim(&mut self) { - let rcvr = Lvalue::Local(Local::new(1+0)).deref(); - let ret_statement = self.make_statement( - StatementKind::Assign( - Lvalue::Local(RETURN_POINTER), - Rvalue::Use(Operand::Consume(rcvr)) - ) - ); - self.block(vec![ret_statement], TerminatorKind::Return, false); - } - - fn make_lvalue(&mut self, mutability: Mutability, ty: ty::Ty<'tcx>) -> Lvalue<'tcx> { - let span = self.span; - Lvalue::Local( - self.local_decls.push(temp_decl(mutability, ty, span)) - ) - } - - fn make_clone_call( - &mut self, - ty: ty::Ty<'tcx>, - rcvr_field: Lvalue<'tcx>, - next: BasicBlock, - cleanup: BasicBlock - ) -> Lvalue<'tcx> { - let tcx = self.tcx; - - let substs = Substs::for_item( - tcx, - self.def_id, - |_, _| tcx.types.re_erased, - |_, _| ty - ); - - // `func == Clone::clone(&ty) -> ty` - let func = Operand::Constant(box Constant { - span: self.span, - ty: tcx.mk_fn_def(self.def_id, substs), - literal: Literal::Value { - value: ConstVal::Function(self.def_id, substs), - }, - }); - - let ref_loc = self.make_lvalue( - Mutability::Not, - tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut { - ty, - mutbl: hir::Mutability::MutImmutable, - }) - ); - - let loc = self.make_lvalue(Mutability::Not, ty); - - // `let ref_loc: &ty = &rcvr_field;` - let statement = self.make_statement( - StatementKind::Assign( - ref_loc.clone(), - Rvalue::Ref(tcx.types.re_erased, BorrowKind::Shared, rcvr_field) - ) - ); - - // `let loc = Clone::clone(ref_loc);` - self.block(vec![statement], TerminatorKind::Call { - func, - args: vec![Operand::Consume(ref_loc)], - destination: Some((loc.clone(), next)), - cleanup: Some(cleanup), - }, false); - - loc - } - - fn loop_header( - &mut self, - beg: Lvalue<'tcx>, - end: Lvalue<'tcx>, - loop_body: BasicBlock, - loop_end: BasicBlock, - is_cleanup: bool - ) { - let tcx = self.tcx; - - let cond = self.make_lvalue(Mutability::Mut, tcx.types.bool); - let compute_cond = self.make_statement( - StatementKind::Assign( - cond.clone(), - Rvalue::BinaryOp(BinOp::Ne, Operand::Consume(end), Operand::Consume(beg)) - ) - ); - - // `if end != beg { goto loop_body; } else { goto loop_end; }` - self.block( - vec![compute_cond], - TerminatorKind::if_(tcx, Operand::Consume(cond), loop_body, loop_end), - is_cleanup - ); - } - - fn make_usize(&self, value: usize) -> Box> { - let value = ConstUsize::new(value as u64, self.tcx.sess.target.uint_type).unwrap(); - box Constant { - span: self.span, - ty: self.tcx.types.usize, - literal: Literal::Value { - value: ConstVal::Integral(ConstInt::Usize(value)) - } - } - } - - fn array_shim(&mut self, ty: ty::Ty<'tcx>, len: usize) { - let tcx = self.tcx; - let rcvr = Lvalue::Local(Local::new(1+0)).deref(); - - let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize); - let end = self.make_lvalue(Mutability::Not, tcx.types.usize); - let ret = self.make_lvalue(Mutability::Mut, tcx.mk_array(ty, len)); - - // BB #0 - // `let mut beg = 0;` - // `let end = len;` - // `goto #1;` - let inits = vec![ - self.make_statement( - StatementKind::Assign( - beg.clone(), - Rvalue::Use(Operand::Constant(self.make_usize(0))) - ) - ), - self.make_statement( - StatementKind::Assign( - end.clone(), - Rvalue::Use(Operand::Constant(self.make_usize(len))) - ) - ) - ]; - self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false); - - // BB #1: loop { - // BB #2; - // BB #3; - // } - // BB #4; - self.loop_header(beg.clone(), end, BasicBlock::new(2), BasicBlock::new(4), false); - - // BB #2 - // `let cloned = Clone::clone(rcvr[beg])`; - // Goto #3 if ok, #5 if unwinding happens. - let rcvr_field = rcvr.clone().index(Operand::Consume(beg.clone())); - let cloned = self.make_clone_call(ty, rcvr_field, BasicBlock::new(3), BasicBlock::new(5)); - - // BB #3 - // `ret[beg] = cloned;` - // `beg = beg + 1;` - // `goto #1`; - let ret_field = ret.clone().index(Operand::Consume(beg.clone())); - let statements = vec![ - self.make_statement( - StatementKind::Assign( - ret_field, - Rvalue::Use(Operand::Consume(cloned)) - ) - ), - self.make_statement( - StatementKind::Assign( - beg.clone(), - Rvalue::BinaryOp( - BinOp::Add, - Operand::Consume(beg.clone()), - Operand::Constant(self.make_usize(1)) - ) - ) - ) - ]; - self.block(statements, TerminatorKind::Goto { target: BasicBlock::new(1) }, false); - - // BB #4 - // `return ret;` - let ret_statement = self.make_statement( - StatementKind::Assign( - Lvalue::Local(RETURN_POINTER), - Rvalue::Use(Operand::Consume(ret.clone())), - ) - ); - self.block(vec![ret_statement], TerminatorKind::Return, false); - - // BB #5 (cleanup) - // `let end = beg;` - // `let mut beg = 0;` - // goto #6; - let end = beg; - let beg = self.make_lvalue(Mutability::Mut, tcx.types.usize); - let init = self.make_statement( - StatementKind::Assign( - beg.clone(), - Rvalue::Use(Operand::Constant(self.make_usize(0))) - ) - ); - self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true); - - // BB #6 (cleanup): loop { - // BB #7; - // BB #8; - // } - // BB #9; - self.loop_header(beg.clone(), end, BasicBlock::new(7), BasicBlock::new(9), true); - - // BB #7 (cleanup) - // `drop(ret[beg])`; - self.block(vec![], TerminatorKind::Drop { - location: ret.index(Operand::Consume(beg.clone())), - target: BasicBlock::new(8), - unwind: None, - }, true); - - // BB #8 (cleanup) - // `beg = beg + 1;` - // `goto #6;` - let statement = self.make_statement( - StatementKind::Assign( - beg.clone(), - Rvalue::BinaryOp( - BinOp::Add, - Operand::Consume(beg.clone()), - Operand::Constant(self.make_usize(1)) - ) - ) - ); - self.block(vec![statement], TerminatorKind::Goto { target: BasicBlock::new(6) }, true); - - // BB #9 (resume) - self.block(vec![], TerminatorKind::Resume, true); - } - - fn tuple_shim(&mut self, tys: &ty::Slice>) { - let rcvr = Lvalue::Local(Local::new(1+0)).deref(); - - let mut returns = Vec::new(); - for (i, ity) in tys.iter().enumerate() { - let rcvr_field = rcvr.clone().field(Field::new(i), *ity); - - // BB #(2i) - // `returns[i] = Clone::clone(&rcvr.i);` - // Goto #(2i + 2) if ok, #(2i + 1) if unwinding happens. - returns.push( - self.make_clone_call( - *ity, - rcvr_field, - BasicBlock::new(2 * i + 2), - BasicBlock::new(2 * i + 1), - ) - ); - - // BB #(2i + 1) (cleanup) - if i == 0 { - // Nothing to drop, just resume. - self.block(vec![], TerminatorKind::Resume, true); - } else { - // Drop previous field and goto previous cleanup block. - self.block(vec![], TerminatorKind::Drop { - location: returns[i - 1].clone(), - target: BasicBlock::new(2 * i - 1), - unwind: None, - }, true); - } - } - - // `return (returns[0], returns[1], ..., returns[tys.len() - 1]);` - let ret_statement = self.make_statement( - StatementKind::Assign( - Lvalue::Local(RETURN_POINTER), - Rvalue::Aggregate( - box AggregateKind::Tuple, - returns.into_iter().map(Operand::Consume).collect() - ) - ) - ); - self.block(vec![ret_statement], TerminatorKind::Return, false); - } -} - /// Build a "call" shim for `def_id`. The shim calls the /// function specified by `call_kind`, first adjusting its first /// argument according to `rcvr_adjustment`. diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index c5de3a4ffb0fd..ae1b60ae7ba28 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -699,8 +699,7 @@ fn visit_instance_use<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, } ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Item(..) | - ty::InstanceDef::FnPtrShim(..) | - ty::InstanceDef::CloneShim(..) => { + ty::InstanceDef::FnPtrShim(..) => { output.push(create_fn_trans_item(instance)); } } @@ -717,8 +716,7 @@ fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instan ty::InstanceDef::Virtual(..) | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::Intrinsic(_) | - ty::InstanceDef::CloneShim(..) => return true + ty::InstanceDef::Intrinsic(_) => return true }; match tcx.hir.get_if_local(def_id) { Some(hir_map::NodeForeignItem(..)) => { diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index b0d8be23b0d96..1f6a262162d39 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -143,12 +143,6 @@ fn resolve_associated_item<'a, 'tcx>( substs: rcvr_substs } } - traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items.clone_trait() => { - Instance { - def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()), - substs: rcvr_substs - } - } _ => { bug!("static call to invalid vtable: {:?}", vtbl) } diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index 26256fa78dd4d..63c7b18e8d290 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -361,8 +361,7 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>, InstanceDef::Virtual(..) | InstanceDef::Intrinsic(..) | InstanceDef::ClosureOnceShim { .. } | - InstanceDef::DropGlue(..) | - InstanceDef::CloneShim(..) => { + InstanceDef::DropGlue(..) => { bug!("partitioning: Encountered unexpected root translation item: {:?}", trans_item) @@ -604,8 +603,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::DropGlue(..) | - ty::InstanceDef::Virtual(..) | - ty::InstanceDef::CloneShim(..) => return None + ty::InstanceDef::Virtual(..) => return None }; // If this is a method, we want to put it into the same module as diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 096b778cab2d3..4cb5eef456329 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -719,8 +719,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { continue; } - self.assemble_builtin_candidates(import_id, trait_def_id, item.clone()); - self.assemble_extension_candidates_for_trait_impls(import_id, trait_def_id, item.clone()); @@ -734,49 +732,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { Ok(()) } - fn assemble_builtin_candidates(&mut self, - import_id: Option, - trait_def_id: DefId, - item: ty::AssociatedItem) { - if Some(trait_def_id) == self.tcx.lang_items.clone_trait() { - self.assemble_builtin_clone_candidates(import_id, trait_def_id, item); - } - } - - fn assemble_builtin_clone_candidates(&mut self, - import_id: Option, - trait_def_id: DefId, - item: ty::AssociatedItem) { - for step in Rc::clone(&self.steps).iter() { - match step.self_ty.sty { - ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) | - ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar | - ty::TyRawPtr(..) | ty::TyError | ty::TyNever | - ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) | - ty::TyArray(..) | ty::TyTuple(..) => { - () - } - - _ => continue, - }; - - let substs = Substs::for_item(self.tcx, - trait_def_id, - |def, _| self.region_var_for_def(self.span, def), - |def, substs| { - if def.index == 0 { - step.self_ty - } else { - self.type_var_for_def(self.span, def, substs) - } - }); - - let xform_self_ty = self.xform_self_ty(&item, step.self_ty, substs); - self.push_inherent_candidate(xform_self_ty, item, TraitCandidate, import_id); - } - } - fn assemble_extension_candidates_for_trait_impls(&mut self, import_id: Option, trait_def_id: DefId, diff --git a/src/test/run-pass/builtin-clone-unwind.rs b/src/test/run-pass/builtin-clone-unwind.rs deleted file mode 100644 index 90a411352869c..0000000000000 --- a/src/test/run-pass/builtin-clone-unwind.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that builtin implementations of `Clone` cleanup everything -// in case of unwinding. - -use std::thread; -use std::rc::Rc; - -struct S(Rc<()>); - -impl Clone for S { - fn clone(&self) -> Self { - if Rc::strong_count(&self.0) == 7 { - panic!("oops"); - } - - S(self.0.clone()) - } -} - -fn main() { - let counter = Rc::new(()); - - // Unwinding with tuples... - let ccounter = counter.clone(); - let result = std::panic::catch_unwind(move || { - let _ = ( - S(ccounter.clone()), - S(ccounter.clone()), - S(ccounter.clone()), - S(ccounter) - ).clone(); - }); - - assert!(result.is_err()); - assert_eq!( - 1, - Rc::strong_count(&counter) - ); - - // ... and with arrays. - let ccounter = counter.clone(); - let child = std::panic::catch_unwind(move || { - let _ = [ - S(ccounter.clone()), - S(ccounter.clone()), - S(ccounter.clone()), - S(ccounter) - ].clone(); - }); - - assert!(result.is_err()); - assert_eq!( - 1, - Rc::strong_count(&counter) - ); -} diff --git a/src/test/run-pass/builtin-clone.rs b/src/test/run-pass/builtin-clone.rs deleted file mode 100644 index 95903610931b2..0000000000000 --- a/src/test/run-pass/builtin-clone.rs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that `Clone` is correctly implemented for builtin types. -// Also test that cloning an array or a tuple is done right, i.e. -// each component is cloned. - -fn test_clone(arg: T) { - let _ = arg.clone(); -} - -fn foo() { } - -#[derive(Debug, PartialEq, Eq)] -struct S(i32); - -impl Clone for S { - fn clone(&self) -> Self { - S(self.0 + 1) - } -} - -fn main() { - test_clone(foo); - test_clone([1; 56]); - test_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); - - let a = [S(0), S(1), S(2)]; - let b = [S(1), S(2), S(3)]; - assert_eq!(b, a.clone()); - - let a = ( - (S(1), S(0)), - ( - (S(0), S(0), S(1)), - S(0) - ) - ); - let b = ( - (S(2), S(1)), - ( - (S(1), S(1), S(2)), - S(1) - ) - ); - assert_eq!(b, a.clone()); -} diff --git a/src/test/run-pass/issue-37725.rs b/src/test/run-pass/issue-37725.rs index a8fb11f9c62bd..5ed1295c85c76 100644 --- a/src/test/run-pass/issue-37725.rs +++ b/src/test/run-pass/issue-37725.rs @@ -8,11 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait Foo { - fn foo(&self); -} - -fn foo<'a>(s: &'a mut ()) where &'a mut (): Foo { - s.foo(); +pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone { + s.clone(); } fn main() {}