From ffba0cea621c2609582b4e201b76b3b19860ec4f Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 21 Jan 2017 17:40:31 +0300 Subject: [PATCH 1/4] Merge ty::TyBox into ty::TyAdt --- src/liballoc/boxed.rs | 1 + src/librustc/infer/freshen.rs | 1 - src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/traits/coherence.rs | 13 +--- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/select.rs | 8 +- src/librustc/ty/contents.rs | 8 +- src/librustc/ty/context.rs | 8 +- src/librustc/ty/error.rs | 1 - src/librustc/ty/fast_reject.rs | 5 -- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/item_path.rs | 3 +- src/librustc/ty/layout.rs | 77 +++++++++++-------- src/librustc/ty/mod.rs | 12 ++- src/librustc/ty/outlives.rs | 1 - src/librustc/ty/relate.rs | 6 -- src/librustc/ty/structural_impls.rs | 2 - src/librustc/ty/sty.rs | 25 +++--- src/librustc/ty/util.rs | 5 +- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 1 - src/librustc/util/ppaux.rs | 3 +- .../borrowck/mir/elaborate_drops.rs | 10 +-- src/librustc_const_eval/_match.rs | 2 - src/librustc_const_eval/pattern.rs | 2 +- src/librustc_driver/test.rs | 11 +-- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/types.rs | 5 -- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/type_check.rs | 5 +- src/librustc_trans/abi.rs | 14 ++-- src/librustc_trans/base.rs | 46 ++++++----- src/librustc_trans/collector.rs | 35 +++++---- src/librustc_trans/debuginfo/metadata.rs | 64 ++++++++------- src/librustc_trans/debuginfo/type_names.rs | 5 -- src/librustc_trans/glue.rs | 32 ++++---- src/librustc_trans/mir/analyze.rs | 2 +- src/librustc_trans/trans_item.rs | 5 -- src/librustc_trans/type_of.rs | 57 ++++++++------ src/librustc_typeck/astconv.rs | 15 +--- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 5 -- src/librustc_typeck/check/mod.rs | 3 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/coherence/builtin.rs | 2 - src/librustc_typeck/coherence/mod.rs | 4 +- src/librustc_typeck/coherence/orphan.rs | 7 -- src/librustc_typeck/variance/constraints.rs | 1 - src/librustdoc/clean/mod.rs | 31 -------- src/test/compile-fail/autoderef-full-lval.rs | 5 +- .../borrowck/borrowck-box-insensitivity.rs | 12 +-- src/test/compile-fail/cross-borrow-trait.rs | 3 +- .../compile-fail/destructure-trait-ref.rs | 3 +- src/test/compile-fail/fn-trait-formatting.rs | 9 +-- src/test/compile-fail/issue-14915.rs | 3 +- src/test/compile-fail/issue-17441.rs | 4 +- src/test/compile-fail/issue-5100.rs | 3 +- src/test/compile-fail/issue-7061.rs | 3 +- .../compile-fail/kindck-impl-type-params-2.rs | 2 +- src/test/compile-fail/lint-ctypes.rs | 4 +- src/test/compile-fail/map-types.rs | 2 +- .../object-does-not-impl-trait.rs | 2 +- src/test/compile-fail/occurs-check-2.rs | 2 +- src/test/compile-fail/occurs-check.rs | 2 +- .../regions-infer-paramd-indirect.rs | 4 +- src/test/compile-fail/terr-sorts.rs | 3 +- src/test/compile-fail/trivial_casts.rs | 5 +- .../type-mismatch-same-crate-name.rs | 4 +- src/test/debuginfo/type-names.rs | 12 +-- src/test/run-pass/auxiliary/issue13507.rs | 2 +- .../trait-bounds-cant-coerce.stderr | 4 +- src/test/ui/span/coerce-suggestions.stderr | 2 +- 73 files changed, 315 insertions(+), 345 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5409ade292360..d98bc1892922a 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -103,6 +103,7 @@ pub struct ExchangeHeapSingleton { /// /// See the [module-level documentation](../../std/boxed/index.html) for more. #[lang = "owned_box"] +#[fundamental] #[stable(feature = "rust1", since = "1.0.0")] pub struct Box(Unique); diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 19183892e4b0c..697a1ecadc456 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -156,7 +156,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyUint(..) | ty::TyFloat(..) | ty::TyAdt(..) | - ty::TyBox(..) | ty::TyStr | ty::TyError | ty::TyArray(..) | diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index dca85d7727a77..0e8e1921de700 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -961,7 +961,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { -> cmt<'tcx> { let ptr = match base_cmt.ty.sty { - ty::TyBox(..) => Unique, + ty::TyAdt(def, ..) if def.is_box() => Unique, ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl), ty::TyRef(r, mt) => { let bk = ty::BorrowKind::from_mutbl(mt.mutbl); diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 58cb52e897786..383fab3fcd766 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -199,7 +199,7 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt, fn uncovered_tys<'tcx>(tcx: TyCtxt, ty: Ty<'tcx>, infer_is_local: InferIsLocal) -> Vec> { - if ty_is_local_constructor(tcx, ty, infer_is_local) { + if ty_is_local_constructor(ty, infer_is_local) { vec![] } else if fundamental_ty(tcx, ty) { ty.walk_shallow() @@ -219,13 +219,13 @@ fn is_type_parameter(ty: Ty) -> bool { } fn ty_is_local(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal) -> bool { - ty_is_local_constructor(tcx, ty, infer_is_local) || + ty_is_local_constructor(ty, infer_is_local) || fundamental_ty(tcx, ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, infer_is_local)) } fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool { match ty.sty { - ty::TyBox(..) | ty::TyRef(..) => true, + ty::TyRef(..) => true, ty::TyAdt(def, _) => def.is_fundamental(), ty::TyDynamic(ref data, ..) => { data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental")) @@ -234,7 +234,7 @@ fn fundamental_ty(tcx: TyCtxt, ty: Ty) -> bool { } } -fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)-> bool { +fn ty_is_local_constructor(ty: Ty, infer_is_local: InferIsLocal)-> bool { debug!("ty_is_local_constructor({:?})", ty); match ty.sty { @@ -265,11 +265,6 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)-> def.did.is_local() } - ty::TyBox(_) => { // Box - let krate = tcx.lang_items.owned_box().map(|d| d.krate); - krate == Some(LOCAL_CRATE) - } - ty::TyDynamic(ref tt, ..) => { tt.principal().map_or(false, |p| p.def_id().is_local()) } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1658efb03235a..661d47199df13 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -154,7 +154,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyStr => Some(2), ty::TyInt(..) | ty::TyUint(..) | ty::TyInfer(ty::IntVar(..)) => Some(3), ty::TyFloat(..) | ty::TyInfer(ty::FloatVar(..)) => Some(4), - ty::TyBox(..) | ty::TyRef(..) | ty::TyRawPtr(..) => Some(5), + ty::TyRef(..) | ty::TyRawPtr(..) => Some(5), ty::TyArray(..) | ty::TySlice(..) => Some(6), ty::TyFnDef(..) | ty::TyFnPtr(..) => Some(7), ty::TyDynamic(..) => Some(8), diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 4990bb9f521d3..d51332f833d77 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1735,7 +1735,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) | ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) | - ty::TyChar | ty::TyBox(_) | ty::TyRef(..) | + ty::TyChar | ty::TyRef(..) | ty::TyArray(..) | ty::TyClosure(..) | ty::TyNever | ty::TyError => { // safe for everything @@ -1788,7 +1788,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(Vec::new())) } - ty::TyBox(_) | ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | + ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | ty::TyClosure(..) | ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { Never @@ -1865,10 +1865,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { t); } - ty::TyBox(referent_ty) => { // Box - vec![referent_ty] - } - ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) | ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => { vec![element_ty] diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index ed5b470849c41..53e8a1d0e37e5 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -191,10 +191,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> { TC::None } - ty::TyBox(typ) => { - tc_ty(tcx, typ, cache).owned_pointer() - } - ty::TyDynamic(..) => { TC::All - TC::InteriorParam } @@ -227,6 +223,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> { |ty| tc_ty(tcx, *ty, cache)) } + ty::TyAdt(def, _) if def.is_box() => { + tc_ty(tcx, ty.boxed_ty(), cache).owned_pointer() + } + ty::TyAdt(def, substs) => { let mut res = TypeContents::union(&def.variants, |v| { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 931d83f5e188a..ce4a6a3182635 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -19,6 +19,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::map as hir_map; use hir::map::DisambiguatedDefPathData; use middle::free_region::FreeRegionMap; +use middle::lang_items; use middle::region::RegionMaps; use middle::resolve_lifetime; use middle::stability; @@ -1088,7 +1089,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { pub fn print_debug_stats(self) { sty_debug_print!( self, - TyAdt, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, + TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyDynamic, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon); println!("Substs interner: #{}", self.interners.substs.borrow().len()); @@ -1336,7 +1337,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.mk_ty(TyBox(ty)) + let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem); + let adt_def = self.lookup_adt_def(def_id); + let substs = self.mk_substs(iter::once(Kind::from(ty))); + self.mk_ty(TyAdt(adt_def, substs)) } pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 91087a3dcecd0..29d855a7fcb78 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -181,7 +181,6 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), - ty::TyBox(_) => "box".to_string(), ty::TyArray(_, n) => format!("array of {} elements", n), ty::TySlice(_) => "slice".to_string(), ty::TyRawPtr(_) => "*-ptr".to_string(), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 7b4d76ad4973e..94b9abc72025f 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -11,7 +11,6 @@ use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use syntax::ast; -use middle::lang_items::OwnedBoxLangItem; use self::SimplifiedType::*; @@ -69,10 +68,6 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, // view of possibly unifying simplify_type(tcx, mt.ty, can_simplify_params) } - ty::TyBox(_) => { - // treat like we would treat `Box` - Some(AdtSimplifiedType(tcx.require_lang_item(OwnedBoxLangItem))) - } ty::TyClosure(def_id, _) => { Some(ClosureSimplifiedType(def_id)) } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index a06d3ed6cf4fb..0de77526b5a46 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -138,7 +138,7 @@ impl FlagComputation { self.add_region(r); } - &ty::TyBox(tt) | &ty::TyArray(tt, _) | &ty::TySlice(tt) => { + &ty::TyArray(tt, _) | &ty::TySlice(tt) => { self.add_ty(tt) } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index d488cd1c42711..b719911d18cf8 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -314,8 +314,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyDynamic(data, ..) => data.principal().map(|p| p.def_id()), ty::TyArray(subty, _) | - ty::TySlice(subty) | - ty::TyBox(subty) => characteristic_def_id_of_type(subty), + ty::TySlice(subty) => characteristic_def_id_of_type(subty), ty::TyRawPtr(mt) | ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index ff95554dbbfcd..78364abdaecba 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1053,6 +1053,23 @@ impl<'a, 'gcx, 'tcx> Layout { let dl = &tcx.data_layout; assert!(!ty.has_infer_types()); + let ptr_layout = |pointee: Ty<'gcx>| { + let non_zero = !ty.is_unsafe_ptr(); + let pointee = normalize_associated_type(infcx, pointee); + if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { + Ok(Scalar { value: Pointer, non_zero: non_zero }) + } else { + let unsized_part = tcx.struct_tail(pointee); + let meta = match unsized_part.sty { + ty::TySlice(_) | ty::TyStr => { + Int(dl.ptr_sized_integer()) + } + ty::TyDynamic(..) => Pointer, + _ => return Err(LayoutError::Unknown(unsized_part)) + }; + Ok(FatPointer { metadata: meta, non_zero: non_zero }) + } + }; let layout = match ty.sty { // Basic scalars. @@ -1082,24 +1099,12 @@ impl<'a, 'gcx, 'tcx> Layout { }, // Potentially-fat pointers. - ty::TyBox(pointee) | ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - let non_zero = !ty.is_unsafe_ptr(); - let pointee = normalize_associated_type(infcx, pointee); - if pointee.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) { - Scalar { value: Pointer, non_zero: non_zero } - } else { - let unsized_part = tcx.struct_tail(pointee); - let meta = match unsized_part.sty { - ty::TySlice(_) | ty::TyStr => { - Int(dl.ptr_sized_integer()) - } - ty::TyDynamic(..) => Pointer, - _ => return Err(LayoutError::Unknown(unsized_part)) - }; - FatPointer { metadata: meta, non_zero: non_zero } - } + ptr_layout(pointee)? + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_layout(ty.boxed_ty())? } // Arrays and slices. @@ -1560,26 +1565,32 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> { Err(err) => err }; + let ptr_skeleton = |pointee: Ty<'gcx>| { + let non_zero = !ty.is_unsafe_ptr(); + let tail = tcx.struct_tail(pointee); + match tail.sty { + ty::TyParam(_) | ty::TyProjection(_) => { + assert!(tail.has_param_types() || tail.has_self_ty()); + Ok(SizeSkeleton::Pointer { + non_zero: non_zero, + tail: tcx.erase_regions(&tail) + }) + } + _ => { + bug!("SizeSkeleton::compute({}): layout errored ({}), yet \ + tail `{}` is not a type parameter or a projection", + ty, err, tail) + } + } + }; + match ty.sty { - ty::TyBox(pointee) | ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - let non_zero = !ty.is_unsafe_ptr(); - let tail = tcx.struct_tail(pointee); - match tail.sty { - ty::TyParam(_) | ty::TyProjection(_) => { - assert!(tail.has_param_types() || tail.has_self_ty()); - Ok(SizeSkeleton::Pointer { - non_zero: non_zero, - tail: tcx.erase_regions(&tail) - }) - } - _ => { - bug!("SizeSkeleton::compute({}): layout errored ({}), yet \ - tail `{}` is not a type parameter or a projection", - ty, err, tail) - } - } + ptr_skeleton(pointee) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_skeleton(ty.boxed_ty()) } ty::TyAdt(def, substs) => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 702f3681a020c..db21d35f990d3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1302,6 +1302,7 @@ bitflags! { const IS_SIMD = 1 << 4, const IS_FUNDAMENTAL = 1 << 5, const IS_UNION = 1 << 6, + const IS_BOX = 1 << 7, } } @@ -1376,6 +1377,9 @@ impl<'a, 'gcx, 'tcx> AdtDef { if Some(did) == tcx.lang_items.phantom_data() { flags = flags | AdtFlags::IS_PHANTOM_DATA; } + if Some(did) == tcx.lang_items.owned_box() { + flags = flags | AdtFlags::IS_BOX; + } match kind { AdtKind::Enum => flags = flags | AdtFlags::IS_ENUM, AdtKind::Union => flags = flags | AdtFlags::IS_UNION, @@ -1468,6 +1472,12 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.flags.get().intersects(AdtFlags::IS_PHANTOM_DATA) } + /// Returns true if this is Box. + #[inline] + pub fn is_box(&self) -> bool { + self.flags.get().intersects(AdtFlags::IS_BOX) + } + /// Returns whether this type has a destructor. pub fn has_dtor(&self) -> bool { self.dtor_kind().is_present() @@ -1641,7 +1651,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { -> Vec> { let result = match ty.sty { TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | + TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | TyArray(..) | TyClosure(..) | TyNever => { vec![] } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index eb384eec6a6f1..bc30f1fb71722 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -167,7 +167,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { ty::TyFloat(..) | // OutlivesScalar ty::TyNever | // ... ty::TyAdt(..) | // OutlivesNominalType - ty::TyBox(..) | // OutlivesNominalType (ish) ty::TyAnon(..) | // OutlivesNominalType (ish) ty::TyStr | // OutlivesScalar (ish) ty::TyArray(..) | // ... diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 76c26d01ac8e2..89514085e1c78 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -418,12 +418,6 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, Ok(tcx.mk_closure_from_closure_substs(a_id, substs)) } - (&ty::TyBox(a_inner), &ty::TyBox(b_inner)) => - { - let typ = relation.relate(&a_inner, &b_inner)?; - Ok(tcx.mk_box(typ)) - } - (&ty::TyRawPtr(ref a_mt), &ty::TyRawPtr(ref b_mt)) => { let mt = relation.relate(a_mt, b_mt)?; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 06ba1b2a1fafc..05f4abad46921 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -468,7 +468,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { let sty = match self.sty { - ty::TyBox(typ) => ty::TyBox(typ.fold_with(folder)), ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)), ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz), ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)), @@ -506,7 +505,6 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match self.sty { - ty::TyBox(typ) => typ.visit_with(visitor), ty::TyRawPtr(ref tm) => tm.visit_with(visitor), ty::TyArray(typ, _sz) => typ.visit_with(visitor), ty::TySlice(typ) => typ.visit_with(visitor), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d6164e69ffd3a..d7686b60ae31e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -115,12 +115,6 @@ pub enum TypeVariants<'tcx> { /// definition and not a concrete use of it. TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>), - /// `Box`; this is nominally a struct in the documentation, but is - /// special-cased internally. For example, it is possible to implicitly - /// move the contents of a box out of that box, and methods of any type - /// can have type `Box`. - TyBox(Ty<'tcx>), - /// The pointee of a string slice. Written as `str`. TyStr, @@ -1139,10 +1133,18 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - pub fn is_unique(&self) -> bool { + pub fn is_box(&self) -> bool { match self.sty { - TyBox(_) => true, - _ => false + TyAdt(def, _) => def.is_box(), + _ => false, + } + } + + pub fn boxed_ty(&self) -> Ty<'tcx> { + match self.sty { + TyAdt(def, substs) if def.is_box() => + substs.types().next().expect("Box doesn't have type parameters"), + _ => bug!("`boxed_ty` is called on non-box type {:?}", self), } } @@ -1247,9 +1249,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { -> Option> { match self.sty { - TyBox(ty) => { + TyAdt(def, _) if def.is_box() => { Some(TypeAndMut { - ty: ty, + ty: self.boxed_ty(), mutbl: if pref == ty::PreferMutLvalue { hir::MutMutable } else { @@ -1349,7 +1351,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { TyInt(_) | TyUint(_) | TyFloat(_) | - TyBox(_) | TyStr | TyArray(..) | TySlice(_) | diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index c05375c47b03a..ba49aa1ef4866 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -481,7 +481,6 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyBool | TyChar | TyStr | - TyBox(_) | TySlice(_) => {} TyError | @@ -563,7 +562,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { mutbl: hir::MutImmutable, .. }) => Some(false), - TyStr | TyBox(..) | TyRef(_, TypeAndMut { + TyStr | TyRef(_, TypeAndMut { mutbl: hir::MutMutable, .. }) => Some(true), @@ -606,7 +605,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { // Fast-path for primitive types let result = match self.sty { TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | - TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | + TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true), TyStr | TyDynamic(..) | TySlice(_) => Some(false), diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 3fa7a803141d1..0d1dc2e4d7c21 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -83,7 +83,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => { } - ty::TyBox(ty) | ty::TyArray(ty, _) | ty::TySlice(ty) => { + ty::TyArray(ty, _) | ty::TySlice(ty) => { stack.push(ty); } ty::TyRawPtr(ref mt) | ty::TyRef(_, ref mt) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index bab9964651dca..33b70b09dcb7b 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -323,7 +323,6 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } } - ty::TyBox(_) | ty::TyRawPtr(_) => { // simple cases that are WF if their type args are WF } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 74e27f84fddc2..aa2eb2955debe 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -16,7 +16,7 @@ use ty::{TyBool, TyChar, TyAdt}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyProjection, TyAnon}; -use ty::{TyBox, TyDynamic, TyInt, TyUint, TyInfer}; +use ty::{TyDynamic, TyInt, TyUint, TyInfer}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use std::cell::Cell; @@ -708,7 +708,6 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyInt(t) => write!(f, "{}", t.ty_to_string()), TyUint(t) => write!(f, "{}", t.ty_to_string()), TyFloat(t) => write!(f, "{}", t.ty_to_string()), - TyBox(typ) => write!(f, "Box<{}>", typ), TyRawPtr(ref tm) => { write!(f, "*{} {}", match tm.mutbl { hir::MutMutable => "mut", diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index 8e0d9c147824d..d555502c3ff85 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -709,9 +709,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn open_drop<'a>(&mut self, c: &DropCtxt<'a, 'tcx>) -> BasicBlock { let ty = c.lvalue.ty(self.mir, self.tcx).to_ty(self.tcx); match ty.sty { - ty::TyAdt(def, substs) => { - self.open_drop_for_adt(c, def, substs) - } ty::TyClosure(def_id, substs) => { let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx).collect(); self.open_drop_for_tuple(c, &tys) @@ -719,8 +716,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { ty::TyTuple(tys) => { self.open_drop_for_tuple(c, tys) } - ty::TyBox(ty) => { - self.open_drop_for_box(c, ty) + ty::TyAdt(def, _) if def.is_box() => { + self.open_drop_for_box(c, ty.boxed_ty()) + } + ty::TyAdt(def, substs) => { + self.open_drop_for_adt(c, def, substs) } _ => bug!("open drop from non-ADT `{:?}`", ty) } diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 1770a112cdf23..94b2ba58c9aa5 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -722,7 +722,6 @@ fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize debug!("constructor_arity({:?}, {:?})", ctor, ty); match ty.sty { ty::TyTuple(ref fs) => fs.len(), - ty::TyBox(_) => 1, ty::TySlice(..) | ty::TyArray(..) => match *ctor { Slice(length) => length, ConstantValue(_) => 0, @@ -747,7 +746,6 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, debug!("constructor_sub_pattern_tys({:?}, {:?})", ctor, ty); match ty.sty { ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(), - ty::TyBox(ty) => vec![ty], ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { Slice(length) => repeat(ty).take(length).collect(), ConstantValue(_) => vec![], diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index a3b80ebddcf00..c6272613f4d09 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -215,7 +215,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { } PatternKind::Deref { ref subpattern } => { match self.ty.sty { - ty::TyBox(_) => write!(f, "box ")?, + ty::TyAdt(def, _) if def.is_box() => write!(f, "box ")?, ty::TyRef(_, mt) => { write!(f, "&")?; if mt.mutbl == hir::MutMutable { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 59f6889ba4d94..1086d75f02cb4 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -805,10 +805,9 @@ fn walk_ty() { let uint_ty = tcx.types.usize; let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]); - let uniq_ty = tcx.mk_box(tup2_ty); - let walked: Vec<_> = uniq_ty.walk().collect(); + let walked: Vec<_> = tup2_ty.walk().collect(); assert_eq!(walked, - [uniq_ty, tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty, + [tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, uint_ty]); }) } @@ -821,12 +820,10 @@ fn walk_ty_skip_subtree() { let uint_ty = tcx.types.usize; let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]); - let uniq_ty = tcx.mk_box(tup2_ty); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. - let mut expected = vec![(uniq_ty, false), - (tup2_ty, false), + let mut expected = vec![(tup2_ty, false), (tup1_ty, false), (int_ty, false), (uint_ty, false), @@ -836,7 +833,7 @@ fn walk_ty_skip_subtree() { (uint_ty, false)]; expected.reverse(); - let mut walker = uniq_ty.walk(); + let mut walker = tup2_ty.walk(); while let Some(t) = walker.next() { debug!("walked to {:?}", t); let (expected_ty, skip) = expected.pop().unwrap(); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2892d61b8bd6f..1592d17817641 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -95,7 +95,7 @@ pub struct BoxPointers; impl BoxPointers { fn check_heap_type<'a, 'tcx>(&self, cx: &LateContext, span: Span, ty: Ty) { for leaf_ty in ty.walk() { - if let ty::TyBox(_) = leaf_ty.sty { + if leaf_ty.is_box() { let m = format!("type uses owned (Box type) pointers: {}", ty); cx.span_lint(BOX_POINTERS, span, &m); } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 532e602226450..9669efa2d86b3 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -519,11 +519,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // Primitive types with a stable representation. ty::TyBool | ty::TyInt(..) | ty::TyUint(..) | ty::TyFloat(..) | ty::TyNever => FfiSafe, - ty::TyBox(..) => { - FfiUnsafe("found Rust type Box<_> in foreign module, \ - consider using a raw pointer instead") - } - ty::TySlice(_) => { FfiUnsafe("found Rust slice type in foreign module, \ consider using a raw pointer instead") diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index af9f7fb578138..9c1107344f241 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -350,7 +350,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { base: Lvalue::Local(index), elem: ProjectionElem::Deref }) if self.mir.local_kind(index) == LocalKind::Temp - && self.mir.local_decls[index].ty.is_unique() + && self.mir.local_decls[index].ty.is_box() && self.temp_qualif[index].map_or(false, |qualif| { qualif.intersects(Qualif::NOT_CONST) }) => { diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 0fabbe6678ad8..c9195f29f1784 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -580,9 +580,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { return; } - let arg_ty = match args[0].ty(mir, self.tcx()).sty { + let ty = args[0].ty(mir, self.tcx()); + let arg_ty = match ty.sty { ty::TyRawPtr(mt) => mt.ty, - ty::TyBox(ty) => ty, + ty::TyAdt(def, _) if def.is_box() => ty.boxed_ty(), _ => { span_mirbug!(self, term, "box_free called with bad arg ty"); return; diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 577744653f09b..d392ebaa33d42 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -429,7 +429,7 @@ impl FnType { if !type_is_fat_ptr(ccx, ret_ty) { // The `noalias` attribute on the return value is useful to a // function ptr caller. - if let ty::TyBox(_) = ret_ty.sty { + if ret_ty.is_box() { // `Box` pointer return values never alias because ownership // is transferred ret.attrs.set(ArgAttribute::NoAlias); @@ -438,12 +438,16 @@ impl FnType { // We can also mark the return value as `dereferenceable` in certain cases match ret_ty.sty { // These are not really pointers but pairs, (pointer, len) - ty::TyRef(_, ty::TypeAndMut { ty, .. }) | - ty::TyBox(ty) => { + ty::TyRef(_, ty::TypeAndMut { ty, .. }) => { let llty = type_of::sizing_type_of(ccx, ty); let llsz = llsize_of_alloc(ccx, llty); ret.attrs.set_dereferenceable(llsz); } + ty::TyAdt(def, _) if def.is_box() => { + let llty = type_of::sizing_type_of(ccx, ret_ty.boxed_ty()); + let llsz = llsize_of_alloc(ccx, llty); + ret.attrs.set_dereferenceable(llsz); + } _ => {} } } @@ -453,9 +457,9 @@ impl FnType { // Handle safe Rust thin and fat pointers. let rust_ptr_attrs = |ty: Ty<'tcx>, arg: &mut ArgType| match ty.sty { // `Box` pointer parameters never alias because ownership is transferred - ty::TyBox(inner) => { + ty::TyAdt(def, _) if def.is_box() => { arg.attrs.set(ArgAttribute::NoAlias); - Some(inner) + Some(ty.boxed_ty()) } ty::TyRef(b, mt) => { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 32fe3effcc9f8..9bd19d5bbb3e4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -227,7 +227,6 @@ pub fn unsize_thin_ptr<'a, 'tcx>( ) -> (ValueRef, ValueRef) { debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); match (&src_ty.sty, &dst_ty.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), @@ -238,6 +237,12 @@ pub fn unsize_thin_ptr<'a, 'tcx>( let ptr_ty = type_of::in_memory_type_of(bcx.ccx, b).ptr_to(); (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty()); + assert!(bcx.ccx.shared().type_is_sized(a)); + let ptr_ty = type_of::in_memory_type_of(bcx.ccx, b).ptr_to(); + (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) + } _ => bug!("unsize_thin_ptr: called on bad types"), } } @@ -249,25 +254,30 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, src_ty: Ty<'tcx>, dst: ValueRef, dst_ty: Ty<'tcx>) { + let coerce_ptr = || { + let (base, info) = if common::type_is_fat_ptr(bcx.ccx, src_ty) { + // fat-ptr to fat-ptr unsize preserves the vtable + // i.e. &'a fmt::Debug+Send => &'a fmt::Debug + // So we need to pointercast the base to ensure + // the types match up. + let (base, info) = load_fat_ptr(bcx, src, src_ty); + let llcast_ty = type_of::fat_ptr_base_ty(bcx.ccx, dst_ty); + let base = bcx.pointercast(base, llcast_ty); + (base, info) + } else { + let base = load_ty(bcx, src, src_ty); + unsize_thin_ptr(bcx, base, src_ty, dst_ty) + }; + store_fat_ptr(bcx, base, info, dst, dst_ty); + }; match (&src_ty.sty, &dst_ty.sty) { - (&ty::TyBox(..), &ty::TyBox(..)) | (&ty::TyRef(..), &ty::TyRef(..)) | (&ty::TyRef(..), &ty::TyRawPtr(..)) | (&ty::TyRawPtr(..), &ty::TyRawPtr(..)) => { - let (base, info) = if common::type_is_fat_ptr(bcx.ccx, src_ty) { - // fat-ptr to fat-ptr unsize preserves the vtable - // i.e. &'a fmt::Debug+Send => &'a fmt::Debug - // So we need to pointercast the base to ensure - // the types match up. - let (base, info) = load_fat_ptr(bcx, src, src_ty); - let llcast_ty = type_of::fat_ptr_base_ty(bcx.ccx, dst_ty); - let base = bcx.pointercast(base, llcast_ty); - (base, info) - } else { - let base = load_ty(bcx, src, src_ty); - unsize_thin_ptr(bcx, base, src_ty, dst_ty) - }; - store_fat_ptr(bcx, base, info, dst, dst_ty); + coerce_ptr() + } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + coerce_ptr() } (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b)) => { @@ -414,7 +424,7 @@ pub fn load_ty<'a, 'tcx>(b: &Builder<'a, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> V // a char is a Unicode codepoint, and so takes values from 0 // to 0x10FFFF inclusive only. b.load_range_assert(ptr, 0, 0x10FFFF + 1, llvm::False) - } else if (t.is_region_ptr() || t.is_unique()) && !common::type_is_fat_ptr(ccx, t) { + } else if (t.is_region_ptr() || t.is_box()) && !common::type_is_fat_ptr(ccx, t) { b.load_nonnull(ptr) } else { b.load(ptr) @@ -449,7 +459,7 @@ pub fn load_fat_ptr<'a, 'tcx>( b: &Builder<'a, 'tcx>, src: ValueRef, t: Ty<'tcx> ) -> (ValueRef, ValueRef) { let ptr = get_dataptr(b, src); - let ptr = if t.is_region_ptr() || t.is_unique() { + let ptr = if t.is_region_ptr() || t.is_box() { b.load_nonnull(ptr) } else { b.load(ptr) diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index fa8bad5807aaf..9766b816d9b30 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -721,14 +721,13 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, debug!("find_drop_glue_neighbors: {}", type_to_string(scx.tcx(), ty)); // Make sure the BoxFreeFn lang-item gets translated if there is a boxed value. - if let ty::TyBox(content_type) = ty.sty { + if ty.is_box() { let def_id = scx.tcx().require_lang_item(BoxFreeFnLangItem); - if should_trans_locally(scx.tcx(), def_id) { let box_free_fn_trans_item = create_fn_trans_item(scx, def_id, - scx.tcx().mk_substs(iter::once(Kind::from(content_type))), + scx.tcx().mk_substs(iter::once(Kind::from(ty.boxed_ty()))), scx.tcx().intern_substs(&[])); output.push(box_free_fn_trans_item); } @@ -790,8 +789,14 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, ty::TyDynamic(..) => { /* nothing to do */ } - ty::TyAdt(adt_def, substs) => { - for field in adt_def.all_fields() { + ty::TyAdt(def, _) if def.is_box() => { + let inner_type = glue::get_drop_glue_type(scx, ty.boxed_ty()); + if scx.type_needs_drop(inner_type) { + output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type))); + } + } + ty::TyAdt(def, substs) => { + for field in def.all_fields() { let field_type = scx.tcx().item_type(field.did); let field_type = monomorphize::apply_param_substs(scx, substs, @@ -811,7 +816,6 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, } } } - ty::TyBox(inner_type) | ty::TySlice(inner_type) | ty::TyArray(inner_type, _) => { let inner_type = glue::get_drop_glue_type(scx, inner_type); @@ -1008,21 +1012,24 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, source_ty: ty::Ty<'tcx>, target_ty: ty::Ty<'tcx>) -> (ty::Ty<'tcx>, ty::Ty<'tcx>) { + let ptr_vtable = |inner_source: ty::Ty<'tcx>, inner_target: ty::Ty<'tcx>| { + if !scx.type_is_sized(inner_source) { + (inner_source, inner_target) + } else { + scx.tcx().struct_lockstep_tails(inner_source, inner_target) + } + }; match (&source_ty.sty, &target_ty.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { - let (inner_source, inner_target) = (a, b); - - if !scx.type_is_sized(inner_source) { - (inner_source, inner_target) - } else { - scx.tcx().struct_lockstep_tails(inner_source, inner_target) - } + ptr_vtable(a, b) + } + (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { + ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty()) } (&ty::TyAdt(source_adt_def, source_substs), diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 0de3c13dc21a9..b7e319f2de434 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -490,6 +490,35 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, debug!("type_metadata: {:?}", t); let sty = &t.sty; + let ptr_metadata = |ty: Ty<'tcx>| { + match ty.sty { + ty::TySlice(typ) => { + Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)) + } + ty::TyStr => { + Ok(vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)) + } + ty::TyDynamic(..) => { + Ok(MetadataCreationResult::new( + trait_pointer_metadata(cx, ty, Some(t), unique_type_id), + false)) + } + _ => { + let pointee_metadata = type_metadata(cx, ty, usage_site_span); + + match debug_context(cx).type_map + .borrow() + .find_metadata_for_unique_id(unique_type_id) { + Some(metadata) => return Err(metadata), + None => { /* proceed normally */ } + }; + + Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), + false)) + } + } + }; + let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty { ty::TyNever | ty::TyBool | @@ -516,34 +545,17 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, trait_pointer_metadata(cx, t, None, unique_type_id), false) } - ty::TyBox(ty) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) => { - match ty.sty { - ty::TySlice(typ) => { - vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span) - } - ty::TyStr => { - vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span) - } - ty::TyDynamic(..) => { - MetadataCreationResult::new( - trait_pointer_metadata(cx, ty, Some(t), unique_type_id), - false) - } - _ => { - let pointee_metadata = type_metadata(cx, ty, usage_site_span); - - match debug_context(cx).type_map - .borrow() - .find_metadata_for_unique_id(unique_type_id) { - Some(metadata) => return metadata, - None => { /* proceed normally */ } - }; - - MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), - false) - } + match ptr_metadata(ty) { + Ok(res) => res, + Err(metadata) => return metadata, + } + } + ty::TyAdt(def, _) if def.is_box() => { + match ptr_metadata(t.boxed_ty()) { + Ok(res) => res, + Err(metadata) => return metadata, } } ty::TyFnDef(.., ref barefnty) | ty::TyFnPtr(ref barefnty) => { diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 788ce32937d84..8e11bf6b8976a 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -60,11 +60,6 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } output.push(')'); }, - ty::TyBox(inner_type) => { - output.push_str("Box<"); - push_debuginfo_type_name(cx, inner_type, true, output); - output.push('>'); - }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { output.push('*'); match mutbl { diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index b24f00ee6976d..65f3c7add4db1 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -79,16 +79,21 @@ pub fn get_drop_glue_type<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'t return scx.tcx().types.i8; } match t.sty { - ty::TyBox(typ) if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) => { - scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| { - let layout = t.layout(&infcx).unwrap(); - if layout.size(&scx.tcx().data_layout).bytes() == 0 { - // `Box` does not allocate. - scx.tcx().types.i8 - } else { - t - } - }) + ty::TyAdt(def, _) if def.is_box() => { + let typ = t.boxed_ty(); + if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) { + scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| { + let layout = t.layout(&infcx).unwrap(); + if layout.size(&scx.tcx().data_layout).bytes() == 0 { + // `Box` does not allocate. + scx.tcx().types.i8 + } else { + t + } + }) + } else { + t + } } _ => t } @@ -205,11 +210,12 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi }; let bcx = match t.sty { - ty::TyBox(content_ty) => { - // Support for TyBox is built-in and its drop glue is + ty::TyAdt(def, _) if def.is_box() => { + // Support for Box is built-in and its drop glue is // special. It may move to library and have Drop impl. As - // a safe-guard, assert TyBox not used with TyContents. + // a safe-guard, assert Box not used with TyContents. assert!(!skip_dtor); + let content_ty = t.boxed_ty(); let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) { let llbox = bcx.load(get_dataptr(&bcx, ptr.llval)); let info = bcx.load(get_meta(&bcx, ptr.llval)); diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 8df24da713588..2a1ab10d74e16 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -30,7 +30,7 @@ pub fn lvalue_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector { let ty = mircx.monomorphize(&ty); debug!("local {} has type {:?}", index, ty); if ty.is_scalar() || - ty.is_unique() || + ty.is_box() || ty.is_region_ptr() || ty.is_simd() || common::type_is_zero_size(mircx.ccx, ty) diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 43ea1e56a5a4d..d58a93e3cb71c 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -421,11 +421,6 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } output.push(')'); }, - ty::TyBox(inner_type) => { - output.push_str("Box<"); - self.push_type_name(inner_type, output); - output.push('>'); - }, ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => { output.push('*'); match mutbl { diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 469214b466e1a..4df0e989ada99 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -38,6 +38,13 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ debug!("sizing_type_of {:?}", t); let _recursion_lock = cx.enter_type_of(t); + let ptr_sizing_ty = |ty: Ty<'tcx>| { + if cx.shared().type_is_sized(ty) { + Type::i8p(cx) + } else { + Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, ty)], false) + } + }; let llsizingty = match t.sty { _ if !cx.shared().type_is_sized(t) => { Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, t)], false) @@ -50,14 +57,12 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ ty::TyFloat(t) => Type::float_from_ty(cx, t), ty::TyNever => Type::nil(cx), - ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => { - if cx.shared().type_is_sized(ty) { - Type::i8p(cx) - } else { - Type::struct_(cx, &[Type::i8p(cx), unsized_info_ty(cx, ty)], false) - } + ptr_sizing_ty(ty) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_sizing_ty(t.boxed_ty()) } ty::TyFnDef(..) => Type::nil(cx), @@ -131,11 +136,13 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ pub fn fat_ptr_base_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Type { match ty.sty { - ty::TyBox(t) | ty::TyRef(_, ty::TypeAndMut { ty: t, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) if !ccx.shared().type_is_sized(t) => { in_memory_type_of(ccx, t).ptr_to() } + ty::TyAdt(def, _) if def.is_box() => { + in_memory_type_of(ccx, ty.boxed_ty()).ptr_to() + } _ => bug!("expected fat ptr ty but got {:?}", ty) } } @@ -214,6 +221,22 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> return llty; } + let ptr_ty = |ty: Ty<'tcx>| { + if !cx.shared().type_is_sized(ty) { + if let ty::TyStr = ty.sty { + // This means we get a nicer name in the output (str is always + // unsized). + cx.str_slice_type() + } else { + let ptr_ty = in_memory_type_of(cx, ty).ptr_to(); + let info_ty = unsized_info_ty(cx, ty); + Type::struct_(cx, &[ptr_ty, info_ty], false) + } + } else { + in_memory_type_of(cx, ty).ptr_to() + } + }; + let mut llty = match t.sty { ty::TyBool => Type::bool(cx), ty::TyChar => Type::char(cx), @@ -227,22 +250,12 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> adt::incomplete_type_of(cx, t, "closure") } - ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) | ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => { - if !cx.shared().type_is_sized(ty) { - if let ty::TyStr = ty.sty { - // This means we get a nicer name in the output (str is always - // unsized). - cx.str_slice_type() - } else { - let ptr_ty = in_memory_type_of(cx, ty).ptr_to(); - let info_ty = unsized_info_ty(cx, ty); - Type::struct_(cx, &[ptr_ty, info_ty], false) - } - } else { - in_memory_type_of(cx, ty).ptr_to() - } + ptr_ty(ty) + } + ty::TyAdt(def, _) if def.is_box() => { + ptr_ty(t.boxed_ty()) } ty::TyArray(ty, size) => { @@ -300,7 +313,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // If this was an enum or struct, fill in the type now. match t.sty { - ty::TyAdt(..) | ty::TyClosure(..) if !t.is_simd() => { + ty::TyAdt(..) | ty::TyClosure(..) if !t.is_simd() && !t.is_box() => { adt::finish_type_of(cx, t, &mut llty); } _ => () diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 56de539cbfe99..bb9a487802e7b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -670,16 +670,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } }; - let substs = self.ast_path_substs_for_ty(span, - did, - item_segment); - - // FIXME(#12938): This is a hack until we have full support for DST. - if Some(did) == self.tcx().lang_items.owned_box() { - assert_eq!(substs.types().count(), 1); - return self.tcx().mk_box(substs.type_at(0)); - } - + let substs = self.ast_path_substs_for_ty(span, did, item_segment); decl_ty.subst(self.tcx(), substs) } @@ -1674,7 +1665,7 @@ impl<'tcx> ExplicitSelf<'tcx> { fn count_modifiers(ty: Ty) -> usize { match ty.sty { ty::TyRef(_, mt) => count_modifiers(mt.ty) + 1, - ty::TyBox(t) => count_modifiers(t) + 1, + ty::TyAdt(def, _) if def.is_box() => count_modifiers(ty.boxed_ty()) + 1, _ => 0, } } @@ -1687,7 +1678,7 @@ impl<'tcx> ExplicitSelf<'tcx> { } else { match self_arg_ty.sty { ty::TyRef(r, mt) => ExplicitSelf::ByReference(r, mt.mutbl), - ty::TyBox(_) => ExplicitSelf::ByBox, + ty::TyAdt(def, _) if def.is_box() => ExplicitSelf::ByBox, _ => ExplicitSelf::ByValue, } } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 0218f1c70ba8e..6215b4498dc68 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { tstr); } } - ty::TyBox(..) => { + ty::TyAdt(def, ..) if def.is_box() => { match fcx.tcx.sess.codemap().span_to_snippet(self.cast_span) { Ok(s) => { err.span_suggestion(self.cast_span, diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 91b772a748c72..34aa4eda772ad 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -448,7 +448,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>( Ok(()) } - ty::TyBox(ity) | ty::TyArray(ity, _) | ty::TySlice(ity) => { + ty::TyArray(ity, _) | ty::TySlice(ity) => { // single-element containers, behave like their element iterate_over_potentially_unsafe_regions_in_type( cx, context, ity, depth+1) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index e2d7d31a8a890..300caca30fec8 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -391,11 +391,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { ty::TyAdt(def, _) => { self.assemble_inherent_impl_candidates_for_type(def.did); } - ty::TyBox(_) => { - if let Some(box_did) = self.tcx.lang_items.owned_box() { - self.assemble_inherent_impl_candidates_for_type(box_did); - } - } ty::TyParam(p) => { self.assemble_inherent_candidates_from_param(self_ty, p); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c2f32c2b52bbe..c435f9341253e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3438,7 +3438,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprBox(ref subexpr) => { let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| { match ty.sty { - ty::TyBox(ty) => Expectation::rvalue_hint(self, ty), + ty::TyAdt(def, _) if def.is_box() + => Expectation::rvalue_hint(self, ty.boxed_ty()), _ => NoExpectation } }); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 7d515a36cfdff..d84e9d3fd3731 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -815,9 +815,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.type_must_outlive(infer::RelateObjectBound(cast_expr.span), from_ty, r); } - /*From:*/ (&ty::TyBox(from_referent_ty), - /*To: */ &ty::TyBox(to_referent_ty)) => { - self.walk_cast(cast_expr, from_referent_ty, to_referent_ty); + /*From:*/ (&ty::TyAdt(from_def, _), + /*To: */ &ty::TyAdt(to_def, _)) if from_def.is_box() && to_def.is_box() => { + self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty()); } _ => { } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 086484c643ad1..96875fce468d2 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -220,8 +220,6 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (mt_a.ty, mt_b.ty, unsize_trait, None) }; let (source, target, trait_def_id, kind) = match (&source.sty, &target.sty) { - (&ty::TyBox(a), &ty::TyBox(b)) => (a, b, unsize_trait, None), - (&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => { infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a); check_mutbl(mt_a, mt_b, &|ty| tcx.mk_imm_ref(r_b, ty)) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 5af9ea29fafa7..e9c710d2fec4c 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -21,7 +21,7 @@ use rustc::ty::{Ty, TyBool, TyChar, TyError}; use rustc::ty::{TyParam, TyRawPtr}; use rustc::ty::{TyRef, TyAdt, TyDynamic, TyNever, TyTuple}; use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt}; -use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr}; +use rustc::ty::{TyUint, TyClosure, TyFnDef, TyFnPtr}; use rustc::ty::{TyProjection, TyAnon}; use CrateCtxt; use syntax_pos::Span; @@ -61,8 +61,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { TyDynamic(ref t, ..) => t.principal().map(|p| p.def_id()), - TyBox(_) => self.tcx.lang_items.owned_box(), - TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyStr | TyArray(..) | TySlice(..) | TyFnDef(..) | TyFnPtr(_) | TyTuple(..) | TyParam(..) | TyError | TyNever | TyRawPtr(_) | TyRef(..) | TyProjection(..) => None, diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index a0d25abd14ce6..9ef231499df51 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -91,12 +91,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { ty::TyDynamic(ref data, ..) if data.principal().is_some() => { self.check_def_id(item, data.principal().unwrap().def_id()); } - ty::TyBox(..) => { - match self.tcx.lang_items.require_owned_box() { - Ok(trait_id) => self.check_def_id(item, trait_id), - Err(msg) => self.tcx.sess.span_fatal(item.span, &msg), - } - } ty::TyChar => { self.check_primitive_impl(def_id, self.tcx.lang_items.char_impl(), @@ -321,7 +315,6 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { let self_ty = trait_ref.self_ty(); let opt_self_def_id = match self_ty.sty { ty::TyAdt(self_def, _) => Some(self_def.did), - ty::TyBox(..) => self.tcx.lang_items.owned_box(), _ => None, }; diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index ba00f237684e6..40e82959336de 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -329,7 +329,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_mt(generics, mt, variance); } - ty::TyBox(typ) | ty::TyArray(typ, _) | ty::TySlice(typ) => { self.add_constraints_from_ty(generics, typ, variance); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7591475c5d3fa..cdb24a56367fc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1808,10 +1808,6 @@ impl<'tcx> Clean for ty::Ty<'tcx> { ty::TyUint(uint_ty) => Primitive(uint_ty.into()), ty::TyFloat(float_ty) => Primitive(float_ty.into()), ty::TyStr => Primitive(PrimitiveType::Str), - ty::TyBox(t) => { - let box_did = cx.tcx.lang_items.owned_box(); - lang_struct(cx, box_did, t, "Box", Unique) - } ty::TySlice(ty) => Vector(box ty.clean(cx)), ty::TyArray(ty, i) => FixedVector(box ty.clean(cx), format!("{}", i)), @@ -2888,33 +2884,6 @@ impl Clean for attr::Deprecation { } } -fn lang_struct(cx: &DocContext, did: Option, - t: ty::Ty, name: &str, - fallback: fn(Box) -> Type) -> Type { - let did = match did { - Some(did) => did, - None => return fallback(box t.clean(cx)), - }; - inline::record_extern_fqn(cx, did, TypeKind::Struct); - ResolvedPath { - typarams: None, - did: did, - path: Path { - global: false, - def: Def::Err, - segments: vec![PathSegment { - name: name.to_string(), - params: PathParameters::AngleBracketed { - lifetimes: vec![], - types: vec![t.clean(cx)], - bindings: vec![] - } - }], - }, - is_generic: false, - } -} - /// An equality constraint on an associated type, e.g. `A=Bar` in `Foo` #[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)] pub struct TypeBinding { diff --git a/src/test/compile-fail/autoderef-full-lval.rs b/src/test/compile-fail/autoderef-full-lval.rs index 0d666a4920038..c152fdd929682 100644 --- a/src/test/compile-fail/autoderef-full-lval.rs +++ b/src/test/compile-fail/autoderef-full-lval.rs @@ -22,13 +22,14 @@ struct fish { fn main() { let a: clam = clam{x: box 1, y: box 2}; let b: clam = clam{x: box 10, y: box 20}; - let z: isize = a.x + b.y; //~ ERROR binary operation `+` cannot be applied to type `Box` + let z: isize = a.x + b.y; + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` println!("{}", z); assert_eq!(z, 21); let forty: fish = fish{a: box 40}; let two: fish = fish{a: box 2}; let answer: isize = forty.a + two.a; - //~^ ERROR binary operation `+` cannot be applied to type `Box` + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` println!("{}", answer); assert_eq!(answer, 42); } diff --git a/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs b/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs index 530822f6c5baf..d09cb73d6702a 100644 --- a/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs +++ b/src/test/compile-fail/borrowck/borrowck-box-insensitivity.rs @@ -35,7 +35,7 @@ fn copy_after_move() { let _x = a.x; //~^ value moved here let _y = a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -44,7 +44,7 @@ fn move_after_move() { let _x = a.x; //~^ value moved here let _y = a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -53,7 +53,7 @@ fn borrow_after_move() { let _x = a.x; //~^ value moved here let _y = &a.y; //~ ERROR use of moved - //~^ move occurs because `a.x` has type `Box` + //~^ move occurs because `a.x` has type `std::boxed::Box` //~| value used here after move } @@ -106,7 +106,7 @@ fn copy_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } @@ -115,7 +115,7 @@ fn move_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } @@ -124,7 +124,7 @@ fn borrow_after_move_nested() { let _x = a.x.x; //~^ value moved here let _y = &a.y; //~ ERROR use of collaterally moved - //~^ NOTE move occurs because `a.x.x` has type `Box` + //~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box` //~| value used here after move } diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs index 672ff464718f8..f389380584b84 100644 --- a/src/test/compile-fail/cross-borrow-trait.rs +++ b/src/test/compile-fail/cross-borrow-trait.rs @@ -20,6 +20,5 @@ pub fn main() { let x: Box = Box::new(Foo); let _y: &Trait = x; //~ ERROR mismatched types //~| expected type `&Trait` - //~| found type `Box` - //~| expected &Trait, found box + //~| found type `std::boxed::Box` } diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index 89fb1e105900d..835ec8e4a5e7e 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -51,6 +51,5 @@ fn main() { let box box x = box 1isize as Box; //~^ ERROR mismatched types //~| expected type `T` - //~| found type `Box<_>` - //~| expected trait T, found box + //~| found type `std::boxed::Box<_>` } diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index e01a0412cef4e..6377550d3d22f 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -16,18 +16,15 @@ fn main() { let _: () = (box |_: isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box` - //~| expected (), found box + //~| found type `std::boxed::Box` let _: () = (box |_: isize, isize| {}) as Box; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box` - //~| expected (), found box + //~| found type `std::boxed::Box` let _: () = (box || -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types //~| expected type `()` - //~| found type `Box isize>` - //~| expected (), found box + //~| found type `std::boxed::Box isize>` needs_fn(1); //~^ ERROR : std::ops::Fn<(isize,)>` diff --git a/src/test/compile-fail/issue-14915.rs b/src/test/compile-fail/issue-14915.rs index 18e4ccc331196..810d6656a8f62 100644 --- a/src/test/compile-fail/issue-14915.rs +++ b/src/test/compile-fail/issue-14915.rs @@ -13,5 +13,6 @@ fn main() { let x: Box = box 0; - println!("{}", x + 1); //~ ERROR binary operation `+` cannot be applied to type `Box` + println!("{}", x + 1); + //~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box` } diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs index 7d300bfb14831..45ab9903532e7 100644 --- a/src/test/compile-fail/issue-17441.rs +++ b/src/test/compile-fail/issue-17441.rs @@ -13,9 +13,9 @@ fn main() { //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]` //~^^ HELP consider using an implicit coercion to `&[usize]` instead - // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. + // FIXME (#22405): Replace `std::boxed::Box::new` with `box` here when/if possible. let _bar = Box::new(1_usize) as std::fmt::Debug; - //~^ ERROR cast to unsized type: `Box` as `std::fmt::Debug` + //~^ ERROR cast to unsized type: `std::boxed::Box` as `std::fmt::Debug` //~^^ HELP try casting to a `Box` instead let _baz = 1_usize as std::fmt::Debug; diff --git a/src/test/compile-fail/issue-5100.rs b/src/test/compile-fail/issue-5100.rs index a1f5d74b30e36..9ef780aac8e27 100644 --- a/src/test/compile-fail/issue-5100.rs +++ b/src/test/compile-fail/issue-5100.rs @@ -43,8 +43,7 @@ fn main() { box (true, false) => () //~^ ERROR mismatched types //~| expected type `(bool, bool)` -//~| found type `Box<_>` -//~| expected tuple, found box +//~| found type `std::boxed::Box<_>` } match (true, false) { diff --git a/src/test/compile-fail/issue-7061.rs b/src/test/compile-fail/issue-7061.rs index da6f49f3efe91..b99f5b707ee2d 100644 --- a/src/test/compile-fail/issue-7061.rs +++ b/src/test/compile-fail/issue-7061.rs @@ -13,9 +13,8 @@ struct BarStruct; impl<'a> BarStruct { fn foo(&'a mut self) -> Box { self } //~^ ERROR mismatched types - //~| expected type `Box` + //~| expected type `std::boxed::Box` //~| found type `&'a mut BarStruct` - //~| expected box, found mutable reference } fn main() {} diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs index a455a7b2d5d0f..21aefc4f9c1bc 100644 --- a/src/test/compile-fail/kindck-impl-type-params-2.rs +++ b/src/test/compile-fail/kindck-impl-type-params-2.rs @@ -21,5 +21,5 @@ fn take_param(foo: &T) { } fn main() { let x: Box<_> = box 3; take_param(&x); - //~^ ERROR `Box<{integer}>: std::marker::Copy` is not satisfied + //~^ ERROR `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied } diff --git a/src/test/compile-fail/lint-ctypes.rs b/src/test/compile-fail/lint-ctypes.rs index 731c1edbfc00b..ccc25b58228bd 100644 --- a/src/test/compile-fail/lint-ctypes.rs +++ b/src/test/compile-fail/lint-ctypes.rs @@ -34,7 +34,7 @@ extern { pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without pub fn slice_type(p: &[u32]); //~ ERROR: found Rust slice type pub fn str_type(p: &str); //~ ERROR: found Rust type - pub fn box_type(p: Box); //~ ERROR found Rust type + pub fn box_type(p: Box); //~ ERROR found struct without pub fn char_type(p: char); //~ ERROR found Rust type pub fn trait_type(p: &Clone); //~ ERROR found Rust trait type pub fn tuple_type(p: (i32, i32)); //~ ERROR found Rust tuple type @@ -42,7 +42,7 @@ extern { pub fn zero_size(p: ZeroSize); //~ ERROR found zero-size struct pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust - pub fn fn_contained(p: RustBadRet); //~ ERROR: found Rust type + pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without pub fn good1(size: *const libc::c_int); pub fn good2(size: *const libc::c_uint); diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs index e24441c5497d5..eaafc312379c2 100644 --- a/src/test/compile-fail/map-types.rs +++ b/src/test/compile-fail/map-types.rs @@ -26,5 +26,5 @@ fn main() { let x: Box> = x; // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. let y: Box> = Box::new(x); - //~^ ERROR `Box>: Map` is not satisfied + //~^ ERROR `std::boxed::Box>: Map` is not satisfied } diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs index 6fa261dea71cb..8babc734c84cc 100644 --- a/src/test/compile-fail/object-does-not-impl-trait.rs +++ b/src/test/compile-fail/object-does-not-impl-trait.rs @@ -14,5 +14,5 @@ trait Foo {} fn take_foo(f: F) {} fn take_object(f: Box) { take_foo(f); } -//~^ ERROR `Box: Foo` is not satisfied +//~^ ERROR `std::boxed::Box: Foo` is not satisfied fn main() {} diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs index 5cb60079fa4b8..a276af83dee25 100644 --- a/src/test/compile-fail/occurs-check-2.rs +++ b/src/test/compile-fail/occurs-check-2.rs @@ -17,6 +17,6 @@ fn main() { f = box g; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `Box<_>` + //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index 499124cb0573b..5b6a11e58c27c 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -15,6 +15,6 @@ fn main() { f = box f; //~^ ERROR mismatched types //~| expected type `_` - //~| found type `Box<_>` + //~| found type `std::boxed::Box<_>` //~| cyclic type of infinite size } diff --git a/src/test/compile-fail/regions-infer-paramd-indirect.rs b/src/test/compile-fail/regions-infer-paramd-indirect.rs index fad115c2aedf8..c559992c86531 100644 --- a/src/test/compile-fail/regions-infer-paramd-indirect.rs +++ b/src/test/compile-fail/regions-infer-paramd-indirect.rs @@ -32,8 +32,8 @@ impl<'a> set_f<'a> for c<'a> { fn set_f_bad(&mut self, b: Box) { self.f = b; //~^ ERROR mismatched types - //~| expected type `Box>` - //~| found type `Box>` + //~| expected type `std::boxed::Box>` + //~| found type `std::boxed::Box>` //~| lifetime mismatch } } diff --git a/src/test/compile-fail/terr-sorts.rs b/src/test/compile-fail/terr-sorts.rs index 592d7b3929bfc..fd92a26d0fcec 100644 --- a/src/test/compile-fail/terr-sorts.rs +++ b/src/test/compile-fail/terr-sorts.rs @@ -20,8 +20,7 @@ fn want_foo(f: foo) {} fn have_bar(b: bar) { want_foo(b); //~ ERROR mismatched types //~| expected type `foo` - //~| found type `Box` - //~| expected struct `foo`, found box + //~| found type `std::boxed::Box` } fn main() {} diff --git a/src/test/compile-fail/trivial_casts.rs b/src/test/compile-fail/trivial_casts.rs index 7693d98a2f7b0..aabf0d26d5ba7 100644 --- a/src/test/compile-fail/trivial_casts.rs +++ b/src/test/compile-fail/trivial_casts.rs @@ -52,7 +52,8 @@ pub fn main() { let _: *mut [u32] = x; let x: Box<[u32; 3]> = Box::new([42, 43, 44]); - let _ = x as Box<[u32]>; //~ERROR trivial cast: `Box<[u32; 3]>` as `Box<[u32]>` + let _ = x as Box<[u32]>; + //~^ ERROR trivial cast: `std::boxed::Box<[u32; 3]>` as `std::boxed::Box<[u32]>` let x: Box<[u32; 3]> = Box::new([42, 43, 44]); let _: Box<[u32]> = x; @@ -70,7 +71,7 @@ pub fn main() { let _: *mut Foo = x; let x: Box = Box::new(Bar); - let _ = x as Box; //~ERROR trivial cast: `Box` as `Box` + let _ = x as Box; //~ERROR trivial cast: `std::boxed::Box` as `std::boxed::Box` let x: Box = Box::new(Bar); let _: Box = x; diff --git a/src/test/compile-fail/type-mismatch-same-crate-name.rs b/src/test/compile-fail/type-mismatch-same-crate-name.rs index e74acaa71b0f3..4295d08a4709c 100644 --- a/src/test/compile-fail/type-mismatch-same-crate-name.rs +++ b/src/test/compile-fail/type-mismatch-same-crate-name.rs @@ -33,7 +33,7 @@ fn main() { //~^ ERROR mismatched types //~| Perhaps two different versions of crate `crate_a1` //~| expected trait `main::a::Bar` - //~| expected type `Box` - //~| found type `Box` + //~| expected type `std::boxed::Box` + //~| found type `std::boxed::Box` } } diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index 438a78743bb1e..57d40cccf2d80 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -70,12 +70,12 @@ // BOX // gdb-command:whatis box1 -// gdbg-check:type = struct (Box, i32) -// gdbr-check:type = (Box, i32) +// gdbg-check:type = struct (alloc::boxed::Box, i32) +// gdbr-check:type = (alloc::boxed::Box, i32) // gdb-command:whatis box2 -// gdbg-check:type = struct (Box>, i32) -// gdbr-check:type = (Box>, i32) +// gdbg-check:type = struct (alloc::boxed::Box>, i32) +// gdbr-check:type = (alloc::boxed::Box>, i32) // REFERENCES @@ -196,8 +196,8 @@ // gdbr-check:type = (unsafe fn(type_names::GenericStruct) -> type_names::mod1::Struct2, usize) // gdb-command:whatis extern_stdcall_fn_with_return_value -// gdbg-check:type = struct (extern "stdcall" fn(Box) -> usize, usize) -// gdbr-check:type = (extern "stdcall" fn(Box) -> usize, usize) +// gdbg-check:type = struct (extern "stdcall" fn(alloc::boxed::Box) -> usize, usize) +// gdbr-check:type = (extern "stdcall" fn(alloc::boxed::Box) -> usize, usize) // gdb-command:whatis generic_function_int // gdbg-check:type = struct (fn(isize) -> isize, usize) diff --git a/src/test/run-pass/auxiliary/issue13507.rs b/src/test/run-pass/auxiliary/issue13507.rs index ba50aed42c36f..ee7d45b77bf4d 100644 --- a/src/test/run-pass/auxiliary/issue13507.rs +++ b/src/test/run-pass/auxiliary/issue13507.rs @@ -58,7 +58,7 @@ pub mod testtypes { // Tests TySlice pub type FooSlice = [u8]; - // Tests TyBox (of u8) + // Tests Box (of u8) pub type FooBox = Box; // Tests TyRawPtr diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr index c47975b01355d..ccc9fb56772f5 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types 24 | a(x); //~ ERROR mismatched types [E0308] | ^ expected trait `Foo + std::marker::Send`, found trait `Foo` | - = note: expected type `Box` - found type `Box` + = note: expected type `std::boxed::Box` + found type `std::boxed::Box` error: aborting due to previous error diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index c32fefcd0d6a9..6a70b8ff851d7 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types | ^^^^^ cyclic type of infinite size | = note: expected type `_` - found type `Box<_>` + found type `std::boxed::Box<_>` error: aborting due to 5 previous errors From 4a4f8ff0a3eeb0855f03ad88c2f11f12761041f0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 21 Jan 2017 22:44:44 +0300 Subject: [PATCH 2/4] Implement Drop for Box --- src/liballoc/boxed.rs | 8 ++++++ src/librustc/ty/contents.rs | 27 +++---------------- src/librustc/ty/sty.rs | 3 +-- .../borrowck/mir/elaborate_drops.rs | 2 +- .../borrowck/mir/gather_moves.rs | 2 +- src/librustc_borrowck/borrowck/mir/mod.rs | 2 +- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/glue.rs | 5 ++-- 8 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d98bc1892922a..b6f490e09cddf 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -293,6 +293,14 @@ impl Box { } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +unsafe impl<#[may_dangle] T: ?Sized> Drop for Box { + fn drop(&mut self) { + // FIXME: Do nothing, drop is currently performed by compiler. + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Default for Box { /// Creates a `Box`, with the `Default` value for T. diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index 53e8a1d0e37e5..00c6dca21b1ef 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -56,12 +56,8 @@ def_type_content_sets! { // InteriorAll = 0b00000000__00000000__1111, // Things that are owned by the value (second and third nibbles): - OwnsOwned = 0b0000_0000__0000_0001__0000, OwnsDtor = 0b0000_0000__0000_0010__0000, - OwnsAll = 0b0000_0000__1111_1111__0000, - - // Things that mean drop glue is necessary - NeedsDrop = 0b0000_0000__0000_0111__0000, + // OwnsAll = 0b0000_0000__1111_1111__0000, // All bits All = 0b1111_1111__1111_1111__1111 @@ -77,10 +73,6 @@ impl TypeContents { (self.bits & tc.bits) != 0 } - pub fn owns_owned(&self) -> bool { - self.intersects(TC::OwnsOwned) - } - pub fn interior_param(&self) -> bool { self.intersects(TC::InteriorParam) } @@ -90,12 +82,7 @@ impl TypeContents { } pub fn needs_drop(&self, _: TyCtxt) -> bool { - self.intersects(TC::NeedsDrop) - } - - /// Includes only those bits that still apply when indirected through a `Box` pointer - pub fn owned_pointer(&self) -> TypeContents { - TC::OwnsOwned | (*self & TC::OwnsAll) + self.intersects(TC::OwnsDtor) } pub fn union(v: I, mut f: F) -> TypeContents where @@ -104,10 +91,6 @@ impl TypeContents { { v.into_iter().fold(TC::None, |tc, ty| tc | f(ty)) } - - pub fn has_dtor(&self) -> bool { - self.intersects(TC::OwnsDtor) - } } impl ops::BitOr for TypeContents { @@ -223,10 +206,6 @@ impl<'a, 'tcx> ty::TyS<'tcx> { |ty| tc_ty(tcx, *ty, cache)) } - ty::TyAdt(def, _) if def.is_box() => { - tc_ty(tcx, ty.boxed_ty(), cache).owned_pointer() - } - ty::TyAdt(def, substs) => { let mut res = TypeContents::union(&def.variants, |v| { @@ -237,7 +216,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { if def.is_union() { // unions don't have destructors regardless of the child types - res = res - TC::NeedsDrop; + res = res - TC::OwnsDtor; } if def.has_dtor() { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d7686b60ae31e..113534e4529cd 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1142,8 +1142,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn boxed_ty(&self) -> Ty<'tcx> { match self.sty { - TyAdt(def, substs) if def.is_box() => - substs.types().next().expect("Box doesn't have type parameters"), + TyAdt(def, substs) if def.is_box() => substs.type_at(0), _ => bug!("`boxed_ty` is called on non-box type {:?}", self), } } diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs index d555502c3ff85..9e89a3689c7ac 100644 --- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs +++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs @@ -895,7 +895,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { match ty.sty { ty::TyAdt(def, _) => { - if def.has_dtor() { + if def.has_dtor() && !def.is_box() { self.tcx.sess.span_warn( c.source_info.span, &format!("dataflow bug??? moving out of type with dtor {:?}", diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs index 2a9acaf58b8f2..7cf6ab2999c05 100644 --- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { // error: can't move out of borrowed content ty::TyRef(..) | ty::TyRawPtr(..) => return Err(MovePathError::IllegalMove), // error: can't move out of struct with destructor - ty::TyAdt(adt, _) if adt.has_dtor() => + ty::TyAdt(adt, _) if adt.has_dtor() && !adt.is_box() => return Err(MovePathError::IllegalMove), // move out of union - always move the entire union ty::TyAdt(adt, _) if adt.is_union() => diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 372eb1d5d64f0..a0c36139ddcd2 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -248,7 +248,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx lv, ty); true } - ty::TyAdt(def, _) if def.has_dtor() || def.is_union() => { + ty::TyAdt(def, _) if (def.has_dtor() && !def.is_box()) || def.is_union() => { debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => true", lv, ty); true diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 9766b816d9b30..392c270c130a8 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -740,7 +740,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, _ => None }; - if let Some(destructor_did) = destructor_did { + if let (Some(destructor_did), false) = (destructor_did, ty.is_box()) { use rustc::ty::ToPolyTraitRef; let drop_trait_def_id = scx.tcx() diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 65f3c7add4db1..350c8f950ddf4 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -211,9 +211,8 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi let bcx = match t.sty { ty::TyAdt(def, _) if def.is_box() => { - // Support for Box is built-in and its drop glue is - // special. It may move to library and have Drop impl. As - // a safe-guard, assert Box not used with TyContents. + // Support for Box is built-in as yet and its drop glue is special + // despite having a dummy Drop impl in the library. assert!(!skip_dtor); let content_ty = t.boxed_ty(); let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) { From a5d725cc82f0b3ca99d3d6fc157b0a28da4ddf9b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 30 Jan 2017 23:18:22 +0300 Subject: [PATCH 3/4] cleanup: Refactor away `DtorKind` --- src/librustc/ty/mod.rs | 25 +------------------------ src/librustc_trans/glue.rs | 2 +- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index db21d35f990d3..5ab45e746e7f2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -9,7 +9,6 @@ // except according to those terms. pub use self::Variance::*; -pub use self::DtorKind::*; pub use self::AssociatedItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -120,21 +119,6 @@ pub struct Resolutions { pub maybe_unused_trait_imports: NodeSet, } -#[derive(Copy, Clone)] -pub enum DtorKind { - NoDtor, - TraitDtor -} - -impl DtorKind { - pub fn is_present(&self) -> bool { - match *self { - TraitDtor => true, - _ => false - } - } -} - #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum AssociatedItemContainer { TraitContainer(DefId), @@ -1480,7 +1464,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { /// Returns whether this type has a destructor. pub fn has_dtor(&self) -> bool { - self.dtor_kind().is_present() + self.destructor.get().is_some() } /// Asserts this is a struct and returns the struct's unique @@ -1543,13 +1527,6 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.destructor.set(Some(dtor)); } - pub fn dtor_kind(&self) -> DtorKind { - match self.destructor.get() { - Some(_) => TraitDtor, - None => NoDtor, - } - } - /// Returns a simpler type such that `Self: Sized` if and only /// if that type is Sized, or `TyErr` if this type is recursive. /// diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 350c8f950ddf4..1415ca6029f53 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -235,7 +235,7 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi bcx.call(dtor, &[ptr.llval], None); bcx } - ty::TyAdt(def, ..) if def.dtor_kind().is_present() && !skip_dtor => { + ty::TyAdt(def, ..) if def.has_dtor() && !skip_dtor => { let shallow_drop = def.is_union(); let tcx = bcx.tcx(); From 93e3f634b096129227c3863b76a1f303716122f4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 30 Jan 2017 23:18:29 +0300 Subject: [PATCH 4/4] Fix debuginfo scope issue with `Box` --- src/librustc_trans/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index f05d48566daae..e9468e56637d2 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -400,7 +400,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g. `<*mut T>::null`). match impl_self_ty.sty { - ty::TyAdt(..) => { + ty::TyAdt(def, ..) if !def.is_box() => { Some(type_metadata(cx, impl_self_ty, syntax_pos::DUMMY_SP)) } _ => None