about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-10-28 17:37:10 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-11-08 16:52:36 -0500
commit8e1de17757a204948b8d0ead4990b2602bc81298 (patch)
treecb5319c4925395e9d350ec027b92163517fc61ca /src/libsyntax
parenta594a999fbccf04710c9dfea3ef3d231c14e1bd1 (diff)
downloadrust-8e1de17757a204948b8d0ead4990b2602bc81298.tar.gz
rust-8e1de17757a204948b8d0ead4990b2602bc81298.zip
Create a new pass to resolve named lifetimes; rscope is not only
used to indicate when anonymous regions (i.e., &T) are permitted
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs14
-rw-r--r--src/libsyntax/visit.rs103
2 files changed, 102 insertions, 15 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 2dd2629048b..c0c2e2822f1 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -251,6 +251,20 @@ pub enum Def {
     DefMethod(DefId /* method */, Option<DefId> /* trait */),
 }
 
+#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
+pub enum DefRegion {
+    DefStaticRegion,
+    DefTypeBoundRegion(/* index */ uint, /* lifetime decl */ NodeId),
+    DefFnBoundRegion(/* binder_id */ NodeId, /* depth */ uint, /* lifetime decl */ NodeId),
+    DefFreeRegion(/* block scope */ NodeId, /* lifetime decl */ NodeId),
+}
+
+#[deriving(Clone, Eq, IterBytes, Encodable, Decodable, ToStr)]
+pub struct DefNamedRegion {
+    node_id: NodeId,
+    depth: uint,
+}
+
 // The set of MetaItems that define the compilation environment of the crate,
 // used to drive conditional compilation
 pub type CrateConfig = ~[@MetaItem];
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 09ee87d1701..60127be87b6 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -90,7 +90,32 @@ pub trait Visitor<E:Clone> {
         walk_struct_def(self, s, i, g, n, e)
     }
     fn visit_struct_field(&mut self, s:@struct_field, e:E) { walk_struct_field(self, s, e) }
-    fn visit_mac(&mut self, m:&mac, e:E) { walk_mac(self, m, e); }
+    fn visit_opt_lifetime_ref(&mut self,
+                              _span: Span,
+                              opt_lifetime: &Option<Lifetime>,
+                              env: E) {
+        /*!
+         * Visits an optional reference to a lifetime. The `span` is
+         * the span of some surrounding reference should opt_lifetime
+         * be None.
+         */
+        match *opt_lifetime {
+            Some(ref l) => self.visit_lifetime_ref(l, env),
+            None => ()
+        }
+    }
+    fn visit_lifetime_ref(&mut self, _lifetime: &Lifetime, _e: E) {
+        /*! Visits a reference to a lifetime */
+    }
+    fn visit_lifetime_decl(&mut self, _lifetime: &Lifetime, _e: E) {
+        /*! Visits a declaration of a lifetime */
+    }
+    fn visit_explicit_self(&mut self, es: &explicit_self, e: E) {
+        walk_explicit_self(self, es, e)
+    }
+    fn visit_mac(&mut self, macro:&mac, e:E) {
+        walk_mac(self, macro, e)
+    }
 }
 
 pub fn walk_crate<E:Clone, V:Visitor<E>>(visitor: &mut V, crate: &Crate, env: E) {
@@ -119,6 +144,18 @@ pub fn walk_local<E:Clone, V:Visitor<E>>(visitor: &mut V, local: &Local, env: E)
     }
 }
 
+fn walk_explicit_self<E:Clone, V:Visitor<E>>(visitor: &mut V,
+                                             explicit_self: &explicit_self,
+                                             env: E) {
+    match explicit_self.node {
+        sty_static | sty_value(_) | sty_box(_) | sty_uniq(_) => {
+        }
+        sty_region(ref lifetime, _) => {
+            visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
+        }
+    }
+}
+
 fn walk_trait_ref<E:Clone, V:Visitor<E>>(visitor: &mut V,
                             trait_ref: &ast::trait_ref,
                             env: E) {
@@ -221,8 +258,11 @@ pub fn skip_ty<E, V:Visitor<E>>(_: &mut V, _: &Ty, _: E) {
 pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     match typ.node {
         ty_box(ref mutable_type) | ty_uniq(ref mutable_type) |
-        ty_vec(ref mutable_type) | ty_ptr(ref mutable_type) |
-        ty_rptr(_, ref mutable_type) => {
+        ty_vec(ref mutable_type) | ty_ptr(ref mutable_type) => {
+            visitor.visit_ty(mutable_type.ty, env)
+        }
+        ty_rptr(ref lifetime, ref mutable_type) => {
+            visitor.visit_opt_lifetime_ref(typ.span, lifetime, env.clone());
             visitor.visit_ty(mutable_type.ty, env)
         }
         ty_tup(ref tuple_element_types) => {
@@ -231,19 +271,27 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
             }
         }
         ty_closure(ref function_declaration) => {
-             for argument in function_declaration.decl.inputs.iter() {
+            for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&argument.ty, env.clone())
-             }
-             visitor.visit_ty(&function_declaration.decl.output, env.clone());
-             for bounds in function_declaration.bounds.iter() {
+            }
+            visitor.visit_ty(&function_declaration.decl.output, env.clone());
+            for bounds in function_declaration.bounds.iter() {
                 walk_ty_param_bounds(visitor, bounds, env.clone())
-             }
+            }
+            visitor.visit_opt_lifetime_ref(
+                typ.span,
+                &function_declaration.region,
+                env.clone());
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
+                                env.clone());
         }
         ty_bare_fn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&argument.ty, env.clone())
             }
-            visitor.visit_ty(&function_declaration.decl.output, env.clone())
+            visitor.visit_ty(&function_declaration.decl.output, env.clone());
+            walk_lifetime_decls(visitor, &function_declaration.lifetimes,
+                                env.clone());
         }
         ty_path(ref path, ref bounds, _) => {
             walk_path(visitor, path, env.clone());
@@ -262,10 +310,21 @@ pub fn walk_ty<E:Clone, V:Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
     }
 }
 
+fn walk_lifetime_decls<E:Clone, V:Visitor<E>>(visitor: &mut V,
+                                              lifetimes: &OptVec<Lifetime>,
+                                              env: E) {
+    for l in lifetimes.iter() {
+        visitor.visit_lifetime_decl(l, env.clone());
+    }
+}
+
 pub fn walk_path<E:Clone, V:Visitor<E>>(visitor: &mut V, path: &Path, env: E) {
     for segment in path.segments.iter() {
         for typ in segment.types.iter() {
-            visitor.visit_ty(typ, env.clone())
+            visitor.visit_ty(typ, env.clone());
+        }
+        for lifetime in segment.lifetimes.iter() {
+            visitor.visit_lifetime_ref(lifetime, env.clone());
         }
     }
 }
@@ -354,6 +413,7 @@ pub fn walk_generics<E:Clone, V:Visitor<E>>(visitor: &mut V,
     for type_parameter in generics.ty_params.iter() {
         walk_ty_param_bounds(visitor, &type_parameter.bounds, env.clone())
     }
+    walk_lifetime_decls(visitor, &generics.lifetimes, env);
 }
 
 pub fn walk_fn_decl<E:Clone, V:Visitor<E>>(visitor: &mut V,
@@ -385,18 +445,31 @@ pub fn walk_fn<E:Clone, V:Visitor<E>>(visitor: &mut V,
                          function_kind: &fn_kind,
                          function_declaration: &fn_decl,
                          function_body: &Block,
-                         _: Span,
+                         _span: Span,
                          _: NodeId,
                          env: E) {
     walk_fn_decl(visitor, function_declaration, env.clone());
-    let generics = generics_of_fn(function_kind);
-    visitor.visit_generics(&generics, env.clone());
+
+    match *function_kind {
+        fk_item_fn(_, generics, _, _) => {
+            visitor.visit_generics(generics, env.clone());
+        }
+        fk_method(_, generics, method) => {
+            visitor.visit_generics(generics, env.clone());
+
+            visitor.visit_explicit_self(&method.explicit_self, env.clone());
+        }
+        fk_anon(*) | fk_fn_block(*) => {
+        }
+    }
+
     visitor.visit_block(function_body, env)
 }
 
 pub fn walk_ty_method<E:Clone, V:Visitor<E>>(visitor: &mut V,
-                                method_type: &TypeMethod,
-                                env: E) {
+                                             method_type: &TypeMethod,
+                                             env: E) {
+    visitor.visit_explicit_self(&method_type.explicit_self, env.clone());
     for argument_type in method_type.decl.inputs.iter() {
         visitor.visit_ty(&argument_type.ty, env.clone())
     }