Merge ty::TyBox into ty::TyAdt
This commit is contained in:
parent
55f9712d14
commit
ffba0cea62
@ -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<T: ?Sized>(Unique<T>);
|
||||
|
||||
|
@ -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(..) |
|
||||
|
@ -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);
|
||||
|
@ -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<Ty<'tcx>> {
|
||||
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<T>
|
||||
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())
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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<T>
|
||||
vec![referent_ty]
|
||||
}
|
||||
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) |
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => {
|
||||
vec![element_ty]
|
||||
|
@ -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| {
|
||||
|
@ -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> {
|
||||
|
@ -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(),
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -314,8 +314,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
|
||||
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),
|
||||
|
@ -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) => {
|
||||
|
@ -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<T>.
|
||||
#[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<Ty<'tcx>> {
|
||||
let result = match ty.sty {
|
||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||
TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||
TyArray(..) | TyClosure(..) | TyNever => {
|
||||
vec![]
|
||||
}
|
||||
|
@ -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(..) | // ...
|
||||
|
@ -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)?;
|
||||
|
@ -468,7 +468,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
|
||||
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<V: TypeVisitor<'tcx>>(&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),
|
||||
|
@ -115,12 +115,6 @@ pub enum TypeVariants<'tcx> {
|
||||
/// definition and not a concrete use of it.
|
||||
TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>),
|
||||
|
||||
/// `Box<T>`; 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<Self>`.
|
||||
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<T> 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<TypeAndMut<'tcx>>
|
||||
{
|
||||
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(_) |
|
||||
|
@ -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),
|
||||
|
@ -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) => {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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![],
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}) => {
|
||||
|
@ -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;
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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) => {
|
||||
|
@ -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 {
|
||||
|
@ -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<ZeroSizeType>` 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<ZeroSizeType>` 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));
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
_ => ()
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
});
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
_ => { }
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1808,10 +1808,6 @@ impl<'tcx> Clean<Type> 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<Deprecation> for attr::Deprecation {
|
||||
}
|
||||
}
|
||||
|
||||
fn lang_struct(cx: &DocContext, did: Option<DefId>,
|
||||
t: ty::Ty, name: &str,
|
||||
fallback: fn(Box<Type>) -> 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<A=Bar>`
|
||||
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)]
|
||||
pub struct TypeBinding {
|
||||
|
@ -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<isize>`
|
||||
let z: isize = a.x + b.y;
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>`
|
||||
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<isize>`
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>`
|
||||
println!("{}", answer);
|
||||
assert_eq!(answer, 42);
|
||||
}
|
||||
|
@ -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<isize>`
|
||||
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
|
||||
//~| 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<isize>`
|
||||
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
|
||||
//~| 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<isize>`
|
||||
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
|
||||
//~| 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<isize>`
|
||||
//~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box<isize>`
|
||||
//~| 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<isize>`
|
||||
//~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box<isize>`
|
||||
//~| 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<isize>`
|
||||
//~^ NOTE move occurs because `a.x.x` has type `std::boxed::Box<isize>`
|
||||
//~| value used here after move
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,5 @@ pub fn main() {
|
||||
let x: Box<Trait> = Box::new(Foo);
|
||||
let _y: &Trait = x; //~ ERROR mismatched types
|
||||
//~| expected type `&Trait`
|
||||
//~| found type `Box<Trait>`
|
||||
//~| expected &Trait, found box
|
||||
//~| found type `std::boxed::Box<Trait>`
|
||||
}
|
||||
|
@ -51,6 +51,5 @@ fn main() {
|
||||
let box box x = box 1isize as Box<T>;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `T`
|
||||
//~| found type `Box<_>`
|
||||
//~| expected trait T, found box
|
||||
//~| found type `std::boxed::Box<_>`
|
||||
}
|
||||
|
@ -16,18 +16,15 @@ fn main() {
|
||||
let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `()`
|
||||
//~| found type `Box<std::ops::FnOnce(isize)>`
|
||||
//~| expected (), found box
|
||||
//~| found type `std::boxed::Box<std::ops::FnOnce(isize)>`
|
||||
let _: () = (box |_: isize, isize| {}) as Box<Fn(isize, isize)>;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `()`
|
||||
//~| found type `Box<std::ops::Fn(isize, isize)>`
|
||||
//~| expected (), found box
|
||||
//~| found type `std::boxed::Box<std::ops::Fn(isize, isize)>`
|
||||
let _: () = (box || -> isize { unimplemented!() }) as Box<FnMut() -> isize>;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `()`
|
||||
//~| found type `Box<std::ops::FnMut() -> isize>`
|
||||
//~| expected (), found box
|
||||
//~| found type `std::boxed::Box<std::ops::FnMut() -> isize>`
|
||||
|
||||
needs_fn(1);
|
||||
//~^ ERROR : std::ops::Fn<(isize,)>`
|
||||
|
@ -13,5 +13,6 @@
|
||||
fn main() {
|
||||
let x: Box<isize> = box 0;
|
||||
|
||||
println!("{}", x + 1); //~ ERROR binary operation `+` cannot be applied to type `Box<isize>`
|
||||
println!("{}", x + 1);
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `std::boxed::Box<isize>`
|
||||
}
|
||||
|
@ -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<usize>` as `std::fmt::Debug`
|
||||
//~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
|
||||
//~^^ HELP try casting to a `Box` instead
|
||||
|
||||
let _baz = 1_usize as std::fmt::Debug;
|
||||
|
@ -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) {
|
||||
|
@ -13,9 +13,8 @@ struct BarStruct;
|
||||
impl<'a> BarStruct {
|
||||
fn foo(&'a mut self) -> Box<BarStruct> { self }
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `Box<BarStruct>`
|
||||
//~| expected type `std::boxed::Box<BarStruct>`
|
||||
//~| found type `&'a mut BarStruct`
|
||||
//~| expected box, found mutable reference
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -21,5 +21,5 @@ fn take_param<T:Foo>(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
|
||||
}
|
||||
|
@ -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<u32>); //~ ERROR found Rust type
|
||||
pub fn box_type(p: Box<u32>); //~ 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);
|
||||
|
@ -26,5 +26,5 @@ fn main() {
|
||||
let x: Box<Map<isize, isize>> = x;
|
||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||
let y: Box<Map<usize, isize>> = Box::new(x);
|
||||
//~^ ERROR `Box<Map<isize, isize>>: Map<usize, isize>` is not satisfied
|
||||
//~^ ERROR `std::boxed::Box<Map<isize, isize>>: Map<usize, isize>` is not satisfied
|
||||
}
|
||||
|
@ -14,5 +14,5 @@
|
||||
trait Foo {}
|
||||
fn take_foo<F:Foo>(f: F) {}
|
||||
fn take_object(f: Box<Foo>) { take_foo(f); }
|
||||
//~^ ERROR `Box<Foo>: Foo` is not satisfied
|
||||
//~^ ERROR `std::boxed::Box<Foo>: Foo` is not satisfied
|
||||
fn main() {}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ impl<'a> set_f<'a> for c<'a> {
|
||||
fn set_f_bad(&mut self, b: Box<b>) {
|
||||
self.f = b;
|
||||
//~^ ERROR mismatched types
|
||||
//~| expected type `Box<Box<&'a isize>>`
|
||||
//~| found type `Box<Box<&isize>>`
|
||||
//~| expected type `std::boxed::Box<std::boxed::Box<&'a isize>>`
|
||||
//~| found type `std::boxed::Box<std::boxed::Box<&isize>>`
|
||||
//~| lifetime mismatch
|
||||
}
|
||||
}
|
||||
|
@ -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<foo>`
|
||||
//~| expected struct `foo`, found box
|
||||
//~| found type `std::boxed::Box<foo>`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -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<Bar> = Box::new(Bar);
|
||||
let _ = x as Box<Foo>; //~ERROR trivial cast: `Box<Bar>` as `Box<Foo>`
|
||||
let _ = x as Box<Foo>; //~ERROR trivial cast: `std::boxed::Box<Bar>` as `std::boxed::Box<Foo>`
|
||||
let x: Box<Bar> = Box::new(Bar);
|
||||
let _: Box<Foo> = x;
|
||||
|
||||
|
@ -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<main::a::Bar + 'static>`
|
||||
//~| found type `Box<main::a::Bar>`
|
||||
//~| expected type `std::boxed::Box<main::a::Bar + 'static>`
|
||||
//~| found type `std::boxed::Box<main::a::Bar>`
|
||||
}
|
||||
}
|
||||
|
@ -70,12 +70,12 @@
|
||||
|
||||
// BOX
|
||||
// gdb-command:whatis box1
|
||||
// gdbg-check:type = struct (Box<f32>, i32)
|
||||
// gdbr-check:type = (Box<f32>, i32)
|
||||
// gdbg-check:type = struct (alloc::boxed::Box<f32>, i32)
|
||||
// gdbr-check:type = (alloc::boxed::Box<f32>, i32)
|
||||
|
||||
// gdb-command:whatis box2
|
||||
// gdbg-check:type = struct (Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
// gdbr-check:type = (Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
// gdbg-check:type = struct (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
// gdbr-check:type = (alloc::boxed::Box<type_names::mod1::mod2::Enum3<f32>>, i32)
|
||||
|
||||
|
||||
// REFERENCES
|
||||
@ -196,8 +196,8 @@
|
||||
// gdbr-check:type = (unsafe fn(type_names::GenericStruct<u16, u8>) -> type_names::mod1::Struct2, usize)
|
||||
|
||||
// gdb-command:whatis extern_stdcall_fn_with_return_value
|
||||
// gdbg-check:type = struct (extern "stdcall" fn(Box<isize>) -> usize, usize)
|
||||
// gdbr-check:type = (extern "stdcall" fn(Box<isize>) -> usize, usize)
|
||||
// gdbg-check:type = struct (extern "stdcall" fn(alloc::boxed::Box<isize>) -> usize, usize)
|
||||
// gdbr-check:type = (extern "stdcall" fn(alloc::boxed::Box<isize>) -> usize, usize)
|
||||
|
||||
// gdb-command:whatis generic_function_int
|
||||
// gdbg-check:type = struct (fn(isize) -> isize, usize)
|
||||
|
@ -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<u8>;
|
||||
|
||||
// Tests TyRawPtr
|
||||
|
@ -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<Foo + std::marker::Send + 'static>`
|
||||
found type `Box<Foo + 'static>`
|
||||
= note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
|
||||
found type `std::boxed::Box<Foo + 'static>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user