about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-06-17 10:02:32 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-07-03 19:42:35 -0400
commitef85338175cb322fa07846d20eec91c2800a98e6 (patch)
tree858683392deb59bf71fbbf29829c9e5d06cef452 /src
parentf027bdc1c8a133693651f333624b756abe21960f (diff)
downloadrust-ef85338175cb322fa07846d20eec91c2800a98e6.tar.gz
rust-ef85338175cb322fa07846d20eec91c2800a98e6.zip
Code up the new lifetime default rules, but leave them disabled
for now.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/tydecode.rs8
-rw-r--r--src/librustc/metadata/tyencode.rs8
-rw-r--r--src/librustc/middle/ty.rs6
-rw-r--r--src/librustc/middle/ty_fold.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs6
-rw-r--r--src/librustc_typeck/collect.rs16
-rw-r--r--src/librustc_typeck/rscope.rs79
7 files changed, 90 insertions, 36 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index a5b9e40593a..99d27c1ba31 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -843,15 +843,15 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
 
 fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
                                              conv: &mut F)
-                                             -> Option<ty::ObjectLifetimeDefault>
+                                             -> ty::ObjectLifetimeDefault
     where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
 {
     match next(st) {
-        'n' => None,
-        'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
+        'a' => ty::ObjectLifetimeDefault::Ambiguous,
+        'b' => ty::ObjectLifetimeDefault::BaseDefault,
         's' => {
             let region = parse_region_(st, conv);
-            Some(ty::ObjectLifetimeDefault::Specific(region))
+            ty::ObjectLifetimeDefault::Specific(region)
         }
         _ => panic!("parse_object_lifetime_default: bad input")
     }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index c078b62dd2d..d80316b8f48 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -414,12 +414,12 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
 
 fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
                                          cx: &ctxt<'a, 'tcx>,
-                                         default: Option<ty::ObjectLifetimeDefault>)
+                                         default: ty::ObjectLifetimeDefault)
 {
     match default {
-        None => mywrite!(w, "n"),
-        Some(ty::ObjectLifetimeDefault::Ambiguous) => mywrite!(w, "a"),
-        Some(ty::ObjectLifetimeDefault::Specific(r)) => {
+        ty::ObjectLifetimeDefault::Ambiguous => mywrite!(w, "a"),
+        ty::ObjectLifetimeDefault::BaseDefault => mywrite!(w, "b"),
+        ty::ObjectLifetimeDefault::Specific(r) => {
             mywrite!(w, "s");
             enc_region(w, cx, r);
         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 91a038813b8..d5372d77005 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2245,6 +2245,9 @@ pub enum ObjectLifetimeDefault {
     /// `T:'a` constraints are found.
     Ambiguous,
 
+    /// Use the base default, typically 'static, but in a fn body it is a fresh variable
+    BaseDefault,
+
     /// Use the given region as the default.
     Specific(Region),
 }
@@ -2256,7 +2259,7 @@ pub struct TypeParameterDef<'tcx> {
     pub space: subst::ParamSpace,
     pub index: u32,
     pub default: Option<Ty<'tcx>>,
-    pub object_lifetime_default: Option<ObjectLifetimeDefault>,
+    pub object_lifetime_default: ObjectLifetimeDefault,
 }
 
 #[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
@@ -7328,6 +7331,7 @@ impl<'tcx> fmt::Debug for ObjectLifetimeDefault {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
+            ObjectLifetimeDefault::BaseDefault => format!("BaseDefault"),
             ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
         }
     }
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 284d26b3cd6..6bae1b68ed4 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -369,6 +369,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault {
             ty::ObjectLifetimeDefault::Ambiguous =>
                 ty::ObjectLifetimeDefault::Ambiguous,
 
+            ty::ObjectLifetimeDefault::BaseDefault =>
+                ty::ObjectLifetimeDefault::BaseDefault,
+
             ty::ObjectLifetimeDefault::Specific(r) =>
                 ty::ObjectLifetimeDefault::Specific(r.fold_with(folder)),
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c6975982c87..05166fa6134 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1779,6 +1779,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
 impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
     fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
         // RFC #599 specifies that object lifetime defaults take
         // precedence over other defaults. But within a fn body we
         // don't have a *default* region, rather we use inference to
@@ -1786,7 +1790,7 @@ impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> {
         // (and anyway, within a fn body the right region may not even
         // be something the user can write explicitly, since it might
         // be some expression).
-        Some(self.infcx().next_region_var(infer::MiscVariable(span)))
+        self.infcx().next_region_var(infer::MiscVariable(span))
     }
 
     fn anon_regions(&self, span: Span, count: usize)
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 5161c84e4b1..e170808ad07 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1532,8 +1532,7 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         let object_lifetime_default_reprs: String =
             scheme.generics.types.iter()
                                  .map(|t| match t.object_lifetime_default {
-                                     Some(ty::ObjectLifetimeDefault::Specific(r)) =>
-                                         r.to_string(),
+                                     ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
                                      d => format!("{:?}", d),
                                  })
                                  .collect::<Vec<String>>()
@@ -1637,7 +1636,7 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         name: special_idents::type_self.name,
         def_id: local_def(param_id),
         default: None,
-        object_lifetime_default: None,
+        object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
     };
 
     ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
@@ -1928,7 +1927,7 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                             param_id: ast::NodeId,
                                             param_bounds: &[ast::TyParamBound],
                                             where_clause: &ast::WhereClause)
-                                            -> Option<ty::ObjectLifetimeDefault>
+                                            -> ty::ObjectLifetimeDefault
 {
     let inline_bounds = from_bounds(ccx, param_bounds);
     let where_bounds = from_predicates(ccx, param_id, &where_clause.predicates);
@@ -1936,11 +1935,12 @@ fn compute_object_lifetime_default<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                               .chain(where_bounds)
                                               .collect();
     return if all_bounds.len() > 1 {
-        Some(ty::ObjectLifetimeDefault::Ambiguous)
+        ty::ObjectLifetimeDefault::Ambiguous
+    } else if all_bounds.len() == 0 {
+        ty::ObjectLifetimeDefault::BaseDefault
     } else {
-        all_bounds.into_iter()
-                  .next()
-                  .map(ty::ObjectLifetimeDefault::Specific)
+        ty::ObjectLifetimeDefault::Specific(
+            all_bounds.into_iter().next().unwrap())
     };
 
     fn from_bounds<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs
index b416026ba01..89f118a7179 100644
--- a/src/librustc_typeck/rscope.rs
+++ b/src/librustc_typeck/rscope.rs
@@ -45,6 +45,13 @@ pub trait RegionScope {
     /// be derived from the object traits, what should we use? If
     /// `None` is returned, an explicit annotation is required.
     fn object_lifetime_default(&self, span: Span) -> Option<ty::Region>;
+
+    /// The "base" default is the initial default for a scope. This is
+    /// 'static except for in fn bodies, where it is a fresh inference
+    /// variable. You shouldn't call this except for as part of
+    /// computing `object_lifetime_default` (in particular, in legacy
+    /// modes, it may not be relevant).
+    fn base_object_lifetime_default(&self, span: Span) -> ty::Region;
 }
 
 // A scope in which all regions must be explicitly named. This is used
@@ -53,16 +60,20 @@ pub trait RegionScope {
 pub struct ExplicitRscope;
 
 impl RegionScope for ExplicitRscope {
-    fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
-        Some(ty::ReStatic)
-    }
-
     fn anon_regions(&self,
                     _span: Span,
                     _count: usize)
                     -> Result<Vec<ty::Region>, Option<Vec<ElisionFailureInfo>>> {
         Err(None)
     }
+
+    fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, _span: Span) -> ty::Region {
+        ty::ReStatic
+    }
 }
 
 // Same as `ExplicitRscope`, but provides some extra information for diagnostics
@@ -75,10 +86,6 @@ impl UnelidableRscope {
 }
 
 impl RegionScope for UnelidableRscope {
-    fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
-        Some(ty::ReStatic)
-    }
-
     fn anon_regions(&self,
                     _span: Span,
                     _count: usize)
@@ -86,6 +93,14 @@ impl RegionScope for UnelidableRscope {
         let UnelidableRscope(ref v) = *self;
         Err(v.clone())
     }
+
+    fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, _span: Span) -> ty::Region {
+        ty::ReStatic
+    }
 }
 
 // A scope in which omitted anonymous region defaults to
@@ -103,11 +118,15 @@ impl ElidableRscope {
 }
 
 impl RegionScope for ElidableRscope {
-    fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
+    fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
         // Per RFC #599, object-lifetimes default to 'static unless
         // overridden by context, and this takes precedence over
         // lifetime elision.
-        Some(ty::ReStatic)
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, _span: Span) -> ty::Region {
+        ty::ReStatic
     }
 
     fn anon_regions(&self,
@@ -140,11 +159,15 @@ impl BindingRscope {
 }
 
 impl RegionScope for BindingRscope {
-    fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
+    fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
         // Per RFC #599, object-lifetimes default to 'static unless
         // overridden by context, and this takes precedence over the
-        // binding defaults.
-        Some(ty::ReStatic)
+        // binding defaults in a fn signature.
+        Some(self.base_object_lifetime_default(span))
+    }
+
+    fn base_object_lifetime_default(&self, _span: Span) -> ty::Region {
+        ty::ReStatic
     }
 
     fn anon_regions(&self,
@@ -159,12 +182,12 @@ impl RegionScope for BindingRscope {
 /// A scope which overrides the default object lifetime but has no other effect.
 pub struct ObjectLifetimeDefaultRscope<'r> {
     base_scope: &'r (RegionScope+'r),
-    default: Option<ty::ObjectLifetimeDefault>,
+    default: ty::ObjectLifetimeDefault,
 }
 
 impl<'r> ObjectLifetimeDefaultRscope<'r> {
     pub fn new(base_scope: &'r (RegionScope+'r),
-               default: Option<ty::ObjectLifetimeDefault>)
+               default: ty::ObjectLifetimeDefault)
                -> ObjectLifetimeDefaultRscope<'r>
     {
         ObjectLifetimeDefaultRscope {
@@ -177,9 +200,25 @@ impl<'r> ObjectLifetimeDefaultRscope<'r> {
 impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
     fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
         match self.default {
-            None => self.base_scope.object_lifetime_default(span),
-            Some(ty::ObjectLifetimeDefault::Ambiguous) => None,
-            Some(ty::ObjectLifetimeDefault::Specific(r)) => Some(r),
+            ty::ObjectLifetimeDefault::Ambiguous =>
+                None,
+
+            ty::ObjectLifetimeDefault::BaseDefault =>
+                if false { // this will become the behavior in Rust 1.3
+                    Some(self.base_object_lifetime_default(span))
+                } else {
+                    self.base_scope.object_lifetime_default(span)
+                },
+
+            ty::ObjectLifetimeDefault::Specific(r) =>
+                Some(r),
+        }
+    }
+
+    fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
+        assert!(false, "this code should not execute until Rust 1.3");
+        self.base_scope.base_object_lifetime_default(span)
+    }
         }
     }
 
@@ -210,6 +249,10 @@ impl<'r> RegionScope for ShiftedRscope<'r> {
             .map(|r| ty_fold::shift_region(r, 1))
     }
 
+    fn base_object_lifetime_default(&self, span: Span) -> ty::Region {
+        ty_fold::shift_region(self.base_scope.base_object_lifetime_default(span), 1)
+    }
+
     fn anon_regions(&self,
                     span: Span,
                     count: usize)