about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-04-21 20:24:32 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-04-23 14:37:18 +0300
commit5412587910f573c5d522b79a4808a1289ebea51c (patch)
tree1b7f5190644fab1abcedc8980c561623a9f86767 /src
parent23de823e93dc19ef1b9cb65b48860a892cd6ff18 (diff)
clean-up adt_sized_constraint now that it uses on-demand
Diffstat (limited to 'src')
-rw-r--r--src/librustc/traits/select.rs8
-rw-r--r--src/librustc/ty/maps.rs2
-rw-r--r--src/librustc/ty/mod.rs60
3 files changed, 21 insertions, 49 deletions
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 6442487ead9..e61e5743790 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -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,
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 4247bff0f50..693dd00574f 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -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,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index cc5eb768d9b..946c55f9406 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -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();
-
-    let ty = match tys.len() {
-        _ if tys.references_error() => tcx.types.err,
-        0 => tcx.types.bool,
-        1 => tys[0],
-        _ => tcx.intern_tup(&tys[..], false)
-    };
+        def.sized_constraint_for_ty(tcx, tcx.item_type(f.did))
+    }).collect::<Vec<_>>());
 
-    debug!("adt_sized_constraint: {:?} => {:?}", def, ty);
+    debug!("adt_sized_constraint: {:?} => {:?}", def, result);
 
-    ty
+    result
 }
 
 fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,