about summary refs log tree commit diff
path: root/src/librustc/traits
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2016-04-22 01:46:23 +0300
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2016-05-03 18:30:10 +0300
commit0a6dfc51777eb388b6e795399bf1d3f8aac57db8 (patch)
tree01f67adda8847634fa5ae03b3005be6868426f6c /src/librustc/traits
parentbabb5df529ceef1cc8c12143d6dd4ab21188cc3e (diff)
downloadrust-0a6dfc51777eb388b6e795399bf1d3f8aac57db8.tar.gz
rust-0a6dfc51777eb388b6e795399bf1d3f8aac57db8.zip
require the non-last elements of a tuple to be Sized
This requirement appears to be missing from RFC1214, but is clearly
necessary for translation. The last field of a tuple/enum remains in
a state of limbo, compiling but causing an ICE when it is used - we
should eventually fix that somehow.

this is a [breaking-change] - a soundness fix - and requires a
crater run.
Diffstat (limited to 'src/librustc/traits')
-rw-r--r--src/librustc/traits/error_reporting.rs5
-rw-r--r--src/librustc/traits/mod.rs5
-rw-r--r--src/librustc/traits/select.rs9
3 files changed, 17 insertions, 2 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 531a4fbf8be..d02dfcd9ea7 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -764,6 +764,11 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
         ObligationCauseCode::SliceOrArrayElem => {
             err.note("slice and array elements must have `Sized` type");
         }
+        ObligationCauseCode::TupleElem => {
+            err.fileline_note(
+                cause_span,
+                "tuple elements must have `Sized` type");
+        }
         ObligationCauseCode::ProjectionWf(data) => {
             err.note(&format!("required so that the projection `{}` is well-formed",
                               data));
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index a160465e2e8..5921cdeab78 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -106,9 +106,12 @@ pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from span.
     MiscObligation,
 
-    /// This is the trait reference from the given projection
+    /// A slice or array is WF only if `T: Sized`
     SliceOrArrayElem,
 
+    /// A tuple is WF only if its middle elements are Sized
+    TupleElem,
+
     /// This is the trait reference from the given projection
     ProjectionWf(ty::ProjectionTy<'tcx>),
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 3a208aba6d8..08a996c142d 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -1652,7 +1652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
             ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
             ty::TyChar | ty::TyBox(_) | ty::TyRef(..) |
-            ty::TyArray(..) | ty::TyTuple(..) | ty::TyClosure(..) |
+            ty::TyArray(..) | ty::TyClosure(..) |
             ty::TyError => {
                 // safe for everything
                 Where(ty::Binder(Vec::new()))
@@ -1660,6 +1660,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             ty::TyStr | ty::TySlice(_) | ty::TyTrait(..) => Never,
 
+            ty::TyTuple(ref tys) => {
+                Where(ty::Binder(match tys.last() {
+                    Some(ty) => vec![ty],
+                    _ => vec![]
+                }))
+            }
+
             ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
                 let sized_crit = def.sized_constraint(self.tcx());
                 // (*) binder moved here