clean-up adt_sized_constraint now that it uses on-demand

This commit is contained in:
Ariel Ben-Yehuda 2017-04-21 20:24:32 +03:00
parent 23de823e93
commit 5412587910
3 changed files with 21 additions and 49 deletions

View file

@ -1790,11 +1790,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
ty::TyAdt(def, substs) => {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(ty::Binder(match sized_crit.sty {
ty::TyTuple(tys, _) => tys.to_vec().subst(self.tcx(), substs),
ty::TyBool => vec![],
_ => vec![sized_crit.subst(self.tcx(), substs)]
}))
Where(ty::Binder(
sized_crit.iter().map(|ty| ty.subst(self.tcx(), substs)).collect()
))
}
ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None,

View file

@ -396,7 +396,7 @@ define_maps! { <'tcx>
pub trait_def: ItemSignature(DefId) -> &'tcx ty::TraitDef,
pub adt_def: ItemSignature(DefId) -> &'tcx ty::AdtDef,
pub adt_destructor: AdtDestructor(DefId) -> Option<ty::Destructor>,
pub adt_sized_constraint: SizedConstraint(DefId) -> Ty<'tcx>,
pub adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
/// True if this is a foreign item (i.e., linked via `extern { ... }`).
pub is_foreign_item: IsForeignItem(DefId) -> bool,

View file

@ -1780,16 +1780,9 @@ impl<'a, 'gcx, 'tcx> AdtDef {
queries::adt_destructor::get(tcx, DUMMY_SP, self.did)
}
/// Returns a simpler type such that `Self: Sized` if and only
/// Returns a list of types such that `Self: Sized` if and only
/// if that type is Sized, or `TyErr` if this type is recursive.
///
/// HACK: instead of returning a list of types, this function can
/// return a tuple. In that case, the result is Sized only if
/// all elements of the tuple are Sized.
///
/// This is generally the `struct_tail` if this is a struct, or a
/// tuple of them if this is an enum.
///
/// Oddly enough, checking that the sized-constraint is Sized is
/// actually more expressive than checking all members:
/// the Sized trait is inductive, so an associated type that references
@ -1797,16 +1790,16 @@ impl<'a, 'gcx, 'tcx> AdtDef {
///
/// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer, e.g. issue #31299.
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
match queries::adt_sized_constraint::try_get(tcx, DUMMY_SP, self.did) {
Ok(ty) => ty,
Ok(tys) => tys,
Err(_) => {
debug!("adt_sized_constraint: {:?} is recursive", self);
// This should be reported as an error by `check_representable`.
//
// Consider the type as Sized in the meanwhile to avoid
// further errors.
tcx.types.err
tcx.intern_type_list(&[tcx.types.err])
}
}
}
@ -1836,18 +1829,13 @@ impl<'a, 'gcx, 'tcx> AdtDef {
TyAdt(adt, substs) => {
// recursive case
let adt_ty =
adt.sized_constraint(tcx)
.subst(tcx, substs);
let adt_tys = adt.sized_constraint(tcx);
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
ty, adt_ty);
if let ty::TyTuple(ref tys, _) = adt_ty.sty {
tys.iter().flat_map(|ty| {
self.sized_constraint_for_ty(tcx, ty)
}).collect()
} else {
self.sized_constraint_for_ty(tcx, adt_ty)
}
ty, adt_tys);
adt_tys.iter()
.map(|ty| ty.subst(tcx, substs))
.flat_map(|ty| self.sized_constraint_for_ty(tcx, ty))
.collect()
}
TyProjection(..) | TyAnon(..) => {
@ -2697,13 +2685,7 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
/// Calculates the Sized-constraint.
///
/// As the Sized-constraint of enums can be a *set* of types,
/// the Sized-constraint may need to be a set also. Because introducing
/// a new type of IVar is currently a complex affair, the Sized-constraint
/// may be a tuple.
///
/// In fact, there are only a few options for the constraint:
/// - `bool`, if the type is always Sized
/// In fact, there are only a few options for the types in the constraint:
/// - an obviously-unsized type
/// - a type parameter or projection whose Sizedness can't be known
/// - a tuple of type parameters or projections, if there are multiple
@ -2712,26 +2694,18 @@ fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
/// check should catch this case.
fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> Ty<'tcx> {
-> &'tcx [Ty<'tcx>] {
let def = tcx.lookup_adt_def(def_id);
let tys: Vec<_> = def.variants.iter().flat_map(|v| {
let result = tcx.intern_type_list(&def.variants.iter().flat_map(|v| {
v.fields.last()
}).flat_map(|f| {
let ty = tcx.item_type(f.did);
def.sized_constraint_for_ty(tcx, ty)
}).collect();
def.sized_constraint_for_ty(tcx, tcx.item_type(f.did))
}).collect::<Vec<_>>());
let ty = match tys.len() {
_ if tys.references_error() => tcx.types.err,
0 => tcx.types.bool,
1 => tys[0],
_ => tcx.intern_tup(&tys[..], false)
};
debug!("adt_sized_constraint: {:?} => {:?}", def, result);
debug!("adt_sized_constraint: {:?} => {:?}", def, ty);
ty
result
}
fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,