diff options
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/ich/impls_ty.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/lang_items.rs | 4 | ||||
| -rw-r--r-- | src/librustc/traits/mod.rs | 7 | ||||
| -rw-r--r-- | src/librustc/traits/select.rs | 27 | ||||
| -rw-r--r-- | src/librustc/traits/structural_impls.rs | 16 | ||||
| -rw-r--r-- | src/librustc/ty/instance.rs | 26 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 3 | 
7 files changed, 65 insertions, 22 deletions
| diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 8a37d7bab44..5b75ce7864f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -721,6 +721,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::In def_id.hash_stable(hcx, hasher); t.hash_stable(hcx, hasher); } + ty::InstanceDef::BuiltinShim(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 01ed79096b1..8cee88bd39b 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -274,6 +274,7 @@ 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; @@ -320,6 +321,9 @@ language_item_table! { StrEqFnLangItem, "str_eq", str_eq_fn; + CloneMethodLangItem, "clone_method", clone_method; + CloneFromMethodLangItem, "clone_from_method", clone_from_method; + // A number of panic-related lang items. The `panic` item corresponds to // divide-by-zero and various panic cases with `match`. The // `panic_bounds_check` item is for indexing arrays. diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index d1938197e65..1c6d75ace52 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -301,7 +301,7 @@ pub enum Vtable<'tcx, N> { VtableObject(VtableObjectData<'tcx, N>), /// Successful resolution for a builtin trait. - VtableBuiltin(VtableBuiltinData<N>), + VtableBuiltin(VtableBuiltinData<'tcx, N>), /// Vtable automatically generated for a closure. The def ID is the ID /// of the closure expression. This is a `VtableImpl` in spirit, but the @@ -345,7 +345,9 @@ pub struct VtableDefaultImplData<N> { } #[derive(Clone)] -pub struct VtableBuiltinData<N> { +pub struct VtableBuiltinData<'tcx, N> { + /// `ty` can be used for generating shim for builtin implementations like `Clone::clone`. + pub ty: ty::Ty<'tcx>, pub nested: Vec<N> } @@ -769,6 +771,7 @@ impl<'tcx, N> Vtable<'tcx, N> { }), VtableParam(n) => VtableParam(n.into_iter().map(f).collect()), VtableBuiltin(i) => VtableBuiltin(VtableBuiltinData { + ty: i.ty, nested: i.nested.into_iter().map(f).collect(), }), VtableObject(o) => VtableObject(VtableObjectData { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 3e39d592135..88cca70993e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1296,6 +1296,14 @@ 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)?; @@ -2164,8 +2172,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match candidate { BuiltinCandidate { has_nested } => { - Ok(VtableBuiltin( - self.confirm_builtin_candidate(obligation, has_nested))) + let data = self.confirm_builtin_candidate(obligation, has_nested); + Ok(VtableBuiltin(data)) } ParamCandidate(param) => { @@ -2257,7 +2265,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn confirm_builtin_candidate(&mut self, obligation: &TraitObligation<'tcx>, has_nested: bool) - -> VtableBuiltinData<PredicateObligation<'tcx>> + -> VtableBuiltinData<'tcx, PredicateObligation<'tcx>> { debug!("confirm_builtin_candidate({:?}, {:?})", obligation, has_nested); @@ -2271,6 +2279,9 @@ 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 { @@ -2291,7 +2302,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("confirm_builtin_candidate: obligations={:?}", obligations); - VtableBuiltinData { nested: obligations } + + let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty()); + VtableBuiltinData { ty: self_ty, nested: obligations } } /// 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> { fn confirm_builtin_unsize_candidate(&mut self, obligation: &TraitObligation<'tcx>,) - -> Result<VtableBuiltinData<PredicateObligation<'tcx>>, - SelectionError<'tcx>> { + -> Result<VtableBuiltinData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> + { let tcx = self.tcx(); // assemble_candidates_for_unsizing should ensure there are no late bound @@ -2801,7 +2814,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { _ => bug!() }; - Ok(VtableBuiltinData { nested: nested }) + Ok(VtableBuiltinData { ty: source, nested: nested }) } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index f1c176561ea..a83849898f5 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -86,9 +86,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> { } } -impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> { +impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<'tcx, N> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "VtableBuiltin(nested={:?})", self.nested) + write!(f, "VtableBuiltin(ty={:?}, nested={:?})", self.ty, self.nested) } } @@ -300,7 +300,14 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> { }) } traits::VtableParam(n) => Some(traits::VtableParam(n)), - traits::VtableBuiltin(d) => Some(traits::VtableBuiltin(d)), + traits::VtableBuiltin(traits::VtableBuiltinData { ty, nested }) => { + tcx.lift(&ty).map(|ty| { + traits::VtableBuiltin(traits::VtableBuiltinData { + ty, + nested, + }) + }) + } traits::VtableObject(traits::VtableObjectData { upcast_trait_ref, vtable_base, @@ -378,9 +385,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultIm } } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> { +impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<'tcx, N> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { traits::VtableBuiltinData { + ty: self.ty.fold_with(folder), nested: self.nested.fold_with(folder), } } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 32063a2dda6..e8daf7c09f4 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -24,15 +24,22 @@ pub struct Instance<'tcx> { pub enum InstanceDef<'tcx> { Item(DefId), Intrinsic(DefId), - // <fn() as FnTrait>::call_* - // def-id is FnTrait::call_* + + /// <fn() as FnTrait>::call_* + /// def-id is FnTrait::call_* FnPtrShim(DefId, Ty<'tcx>), - // <Trait as Trait>::fn + + /// <Trait as Trait>::fn Virtual(DefId, usize), - // <[mut closure] as FnOnce>::call_once + + /// <[mut closure] as FnOnce>::call_once ClosureOnceShim { call_once: DefId }, - // drop_in_place::<T>; None for empty drop glue. + + /// drop_in_place::<T>; None for empty drop glue. DropGlue(DefId, Option<Ty<'tcx>>), + + /// Builtin method implementation, e.g. `Clone::clone`. + BuiltinShim(DefId, Ty<'tcx>), } impl<'tcx> InstanceDef<'tcx> { @@ -43,9 +50,9 @@ impl<'tcx> InstanceDef<'tcx> { InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id, ) | - InstanceDef::ClosureOnceShim { call_once: def_id } - => def_id, - InstanceDef::DropGlue(def_id, _) => def_id + InstanceDef::ClosureOnceShim { call_once: def_id } | + InstanceDef::DropGlue(def_id, _) | + InstanceDef::BuiltinShim(def_id, _) => def_id } } @@ -80,6 +87,9 @@ impl<'tcx> fmt::Display for Instance<'tcx> { InstanceDef::DropGlue(_, ty) => { write!(f, " - shim({:?})", ty) } + InstanceDef::BuiltinShim(_, ty) => { + write!(f, " - shim({:?})", ty) + } } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 28a73f4a4d3..81a0af63942 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2227,7 +2227,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::Virtual(..) | ty::InstanceDef::ClosureOnceShim { .. } | - ty::InstanceDef::DropGlue(..) => { + ty::InstanceDef::DropGlue(..) | + ty::InstanceDef::BuiltinShim(..) => { self.mir_shims(instance) } } | 
