diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-04-22 01:46:23 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-05-03 18:30:10 +0300 |
| commit | 0a6dfc51777eb388b6e795399bf1d3f8aac57db8 (patch) | |
| tree | 01f67adda8847634fa5ae03b3005be6868426f6c /src/librustc/traits | |
| parent | babb5df529ceef1cc8c12143d6dd4ab21188cc3e (diff) | |
| download | rust-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.rs | 5 | ||||
| -rw-r--r-- | src/librustc/traits/mod.rs | 5 | ||||
| -rw-r--r-- | src/librustc/traits/select.rs | 9 |
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 |
