about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-17 20:38:18 +0000
committerbors <bors@rust-lang.org>2015-04-17 20:38:18 +0000
commitf305579e490a9fa046b1b7a14e62daf643e41865 (patch)
tree4db877cb45e780d62f3cfb69374d6dc3ca8f9a92 /src/librustc
parent3b2530c74832d8434ae7d87d01aa44936c0b0f84 (diff)
parent5368070228a90b38bc3c36841ca5d882c9afc301 (diff)
downloadrust-f305579e490a9fa046b1b7a14e62daf643e41865.tar.gz
rust-f305579e490a9fa046b1b7a14e62daf643e41865.zip
Auto merge of #24461 - nikomatsakis:issue-22077-unused-lifetimes, r=aturon
This makes it illegal to have unconstrained lifetimes that appear in an associated type definition. Arguably, we should prohibit all unconstrained lifetimes -- but it would break various macros. It'd be good to evaluate how large a break change it would be. But this seems like the minimal change we need to do to establish soundness, so we should land it regardless. Another variant would be to prohibit all lifetimes that appear in any impl item, not just associated types. I don't think that's necessary for soundness -- associated types are different because they can be projected -- but it would feel a bit more consistent and "obviously" safe. I'll experiment with that in the meantime.

r? @aturon 

Fixes #22077.
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/metadata/tydecode.rs7
-rw-r--r--src/librustc/metadata/tyencode.rs10
-rw-r--r--src/librustc/middle/astencode.rs9
-rw-r--r--src/librustc/middle/region.rs9
-rw-r--r--src/librustc/middle/subst.rs15
-rw-r--r--src/librustc/middle/ty.rs23
-rw-r--r--src/librustc/util/ppaux.rs18
7 files changed, 54 insertions, 37 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index cce31b1f4c2..955905ee263 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -341,7 +341,12 @@ fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
         let index = parse_u32(st);
         assert_eq!(next(st), '|');
         let nm = token::str_to_ident(&parse_str(st, ']'));
-        ty::ReEarlyBound(node_id, space, index, nm.name)
+        ty::ReEarlyBound(ty::EarlyBoundRegion {
+            param_id: node_id,
+            space: space,
+            index: index,
+            name: nm.name
+        })
       }
       'f' => {
         assert_eq!(next(st), '[');
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 90a905f1840..8a278811282 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -241,12 +241,12 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
             enc_bound_region(w, cx, br);
             mywrite!(w, "]");
         }
-        ty::ReEarlyBound(node_id, space, index, name) => {
+        ty::ReEarlyBound(ref data) => {
             mywrite!(w, "B[{}|{}|{}|{}]",
-                     node_id,
-                     space.to_uint(),
-                     index,
-                     token::get_name(name));
+                     data.param_id,
+                     data.space.to_uint(),
+                     data.index,
+                     token::get_name(data.name));
         }
         ty::ReFree(ref fr) => {
             mywrite!(w, "f[");
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 2b8540a34b1..7ee0ea4fd66 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -496,8 +496,13 @@ impl tr for ty::Region {
             ty::ReLateBound(debruijn, br) => {
                 ty::ReLateBound(debruijn, br.tr(dcx))
             }
-            ty::ReEarlyBound(id, space, index, ident) => {
-                ty::ReEarlyBound(dcx.tr_id(id), space, index, ident)
+            ty::ReEarlyBound(data) => {
+                ty::ReEarlyBound(ty::EarlyBoundRegion {
+                    param_id: dcx.tr_id(data.param_id),
+                    space: data.space,
+                    index: data.index,
+                    name: data.name,
+                })
             }
             ty::ReScope(scope) => {
                 ty::ReScope(scope.tr(dcx))
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 5131322dc41..2f7296051c5 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -603,14 +603,11 @@ impl RegionMaps {
                     self.sub_free_region(sub_fr, super_fr)
                 }
 
-                (ty::ReEarlyBound(param_id_a, param_space_a, index_a, _),
-                 ty::ReEarlyBound(param_id_b, param_space_b, index_b, _)) => {
+                (ty::ReEarlyBound(data_a), ty::ReEarlyBound(data_b)) => {
                     // This case is used only to make sure that explicitly-
                     // specified `Self` types match the real self type in
-                    // implementations.
-                    param_id_a == param_id_b &&
-                        param_space_a == param_space_b &&
-                        index_a == index_b
+                    // implementations. Yuck.
+                    data_a == data_b
                 }
 
                 _ => {
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index d9cdf0fa1cb..29f718fd097 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -622,11 +622,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
         // regions that appear in a function signature is done using
         // the specialized routine `ty::replace_late_regions()`.
         match r {
-            ty::ReEarlyBound(_, space, i, region_name) => {
+            ty::ReEarlyBound(data) => {
                 match self.substs.regions {
                     ErasedRegions => ty::ReStatic,
                     NonerasedRegions(ref regions) =>
-                        match regions.opt_get(space, i as usize) {
+                        match regions.opt_get(data.space, data.index as usize) {
                             Some(&r) => {
                                 self.shift_region_through_binders(r)
                             }
@@ -635,11 +635,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
                                 self.tcx().sess.span_bug(
                                     span,
                                     &format!("Type parameter out of range \
-                                     when substituting in region {} (root type={}) \
-                                     (space={:?}, index={})",
-                                    region_name.as_str(),
-                                    self.root_ty.repr(self.tcx()),
-                                    space, i));
+                                              when substituting in region {} (root type={}) \
+                                              (space={:?}, index={})",
+                                             data.name.as_str(),
+                                             self.root_ty.repr(self.tcx()),
+                                             data.space,
+                                             data.index));
                             }
                         }
                 }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index eab87dc846d..53c3cdd02af 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1134,10 +1134,7 @@ pub enum Region {
     // Region bound in a type or fn declaration which will be
     // substituted 'early' -- that is, at the same time when type
     // parameters are substituted.
-    ReEarlyBound(/* param id */ ast::NodeId,
-                 subst::ParamSpace,
-                 /*index*/ u32,
-                 ast::Name),
+    ReEarlyBound(EarlyBoundRegion),
 
     // Region bound in a function scope, which will be substituted when the
     // function is called.
@@ -1169,6 +1166,14 @@ pub enum Region {
     ReEmpty,
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
+pub struct EarlyBoundRegion {
+    pub param_id: ast::NodeId,
+    pub space: subst::ParamSpace,
+    pub index: u32,
+    pub name: ast::Name,
+}
+
 /// Upvars do not get their own node-id. Instead, we use the pair of
 /// the original var id (that is, the root variable that is referenced
 /// by the upvar) and the id of the closure expression.
@@ -1761,7 +1766,12 @@ pub struct RegionParameterDef {
 
 impl RegionParameterDef {
     pub fn to_early_bound_region(&self) -> ty::Region {
-        ty::ReEarlyBound(self.def_id.node, self.space, self.index, self.name)
+        ty::ReEarlyBound(ty::EarlyBoundRegion {
+            param_id: self.def_id.node,
+            space: self.space,
+            index: self.index,
+            name: self.name,
+        })
     }
     pub fn to_bound_region(&self) -> ty::BoundRegion {
         ty::BoundRegion::BrNamed(self.def_id, self.name)
@@ -7071,8 +7081,7 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
     let meth_regions: Vec<ty::Region> =
         method.generics.regions.get_slice(subst::FnSpace)
               .iter()
-              .map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
-                                          def.index, def.name))
+              .map(|def| def.to_early_bound_region())
               .collect();
     trait_ref.substs.clone().with_method(meth_tps, meth_regions)
 }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 650f40a8291..12a6d584857 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -163,8 +163,8 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
 
       ReEmpty => { ("the empty lifetime".to_string(), None) }
 
-      ReEarlyBound(_, _, _, name) => {
-        (format!("{}", token::get_name(name)), None)
+      ReEarlyBound(ref data) => {
+        (format!("{}", token::get_name(data.name)), None)
       }
 
       // I believe these cases should not occur (except when debugging,
@@ -223,8 +223,8 @@ pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) ->
     // `explain_region()` or `note_and_explain_region()`.
     match region {
         ty::ReScope(_) => prefix.to_string(),
-        ty::ReEarlyBound(_, _, _, name) => {
-            token::get_name(name).to_string()
+        ty::ReEarlyBound(ref data) => {
+            token::get_name(data.name).to_string()
         }
         ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
         ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
@@ -903,12 +903,12 @@ impl<'tcx> Repr<'tcx> for ty::BoundRegion {
 impl<'tcx> Repr<'tcx> for ty::Region {
     fn repr(&self, tcx: &ctxt) -> String {
         match *self {
-            ty::ReEarlyBound(id, space, index, name) => {
+            ty::ReEarlyBound(ref data) => {
                 format!("ReEarlyBound({}, {:?}, {}, {})",
-                               id,
-                               space,
-                               index,
-                               token::get_name(name))
+                        data.param_id,
+                        data.space,
+                        data.index,
+                        token::get_name(data.name))
             }
 
             ty::ReLateBound(binder_id, ref bound_region) => {