]> git.lizzy.rs Git - rust.git/commitdiff
Extended `syntax::{fold, ast_map}` to include lifetimes.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Fri, 11 Apr 2014 09:28:43 +0000 (11:28 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Thu, 17 Apr 2014 09:42:30 +0000 (11:42 +0200)
Part of this required added an override of `fold_type_method` in the
Folder for Ctx impl; it follows the same pattern as `fold_method`.

Also, as a drive-by fix, I moved all of the calls to `folder.new_id`
in syntax::fold's no-op default traversal to really be the first
statement in each function.

  * This is to uphold the invariant that `folder.new_id` is always
    called first (an unfortunate requirement of the current `ast_map`
    code), an invariant that we seemingly were breaking in e.g. the
    previous `noop_fold_block`.

  * Now it should be easier to see when adding new code that this
    invariant must be upheld.

  * (note that the breakage in `noop_fold_block` may not have mattered
    so much previously, since the only thing that blocks can bind are
    lifetimes, which I am only adding support for now.)

src/librustc/middle/trans/monomorphize.rs
src/libsyntax/ast_map.rs
src/libsyntax/fold.rs

index 6f2dbc182b04f3000852d8196b3af4cbbef87bd5..f7b444e439f406d378f1fc052359cad43db2cc77 100644 (file)
@@ -272,6 +272,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
         }
 
         // Ugh -- but this ensures any new variants won't be forgotten
+        ast_map::NodeLifetime(..) |
         ast_map::NodeExpr(..) |
         ast_map::NodeStmt(..) |
         ast_map::NodeArg(..) |
index 4c7803f022a159dce92a09f11772841db27a22fe..45954800e7e9a0fdc619eb2d162dd5a42481f1f6 100644 (file)
@@ -107,6 +107,8 @@ pub enum Node {
 
     /// NodeStructCtor represents a tuple struct.
     NodeStructCtor(@StructDef),
+
+    NodeLifetime(@Lifetime),
 }
 
 // The odd layout is to bring down the total size.
@@ -127,6 +129,7 @@ enum MapEntry {
     EntryLocal(NodeId, @Pat),
     EntryBlock(NodeId, P<Block>),
     EntryStructCtor(NodeId, @StructDef),
+    EntryLifetime(NodeId, @Lifetime),
 
     // Roots for node trees.
     RootCrate,
@@ -153,6 +156,7 @@ fn parent(&self) -> Option<NodeId> {
             EntryLocal(id, _) => id,
             EntryBlock(id, _) => id,
             EntryStructCtor(id, _) => id,
+            EntryLifetime(id, _) => id,
             _ => return None
         })
     }
@@ -170,6 +174,7 @@ fn to_node(&self) -> Option<Node> {
             EntryLocal(_, p) => NodeLocal(p),
             EntryBlock(_, p) => NodeBlock(p),
             EntryStructCtor(_, p) => NodeStructCtor(p),
+            EntryLifetime(_, p) => NodeLifetime(p),
             _ => return None
         })
     }
@@ -213,6 +218,8 @@ pub fn find(&self, id: NodeId) -> Option<Node> {
         self.find_entry(id).and_then(|x| x.to_node())
     }
 
+    /// Retrieve the parent NodeId for `id`, or `id` itself if no
+    /// parent is registered in this map.
     pub fn get_parent(&self, id: NodeId) -> NodeId {
         self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
     }
@@ -500,6 +507,15 @@ fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<@Stmt> {
         SmallVector::one(stmt)
     }
 
+    fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
+        let parent = self.parent;
+        self.parent = DUMMY_NODE_ID;
+        let m = fold::noop_fold_type_method(m, self);
+        assert_eq!(self.parent, m.id);
+        self.parent = parent;
+        m
+    }
+
     fn fold_method(&mut self, m: @Method) -> @Method {
         let parent = self.parent;
         self.parent = DUMMY_NODE_ID;
@@ -522,6 +538,12 @@ fn fold_block(&mut self, block: P<Block>) -> P<Block> {
         self.insert(block.id, EntryBlock(self.parent, block));
         block
     }
+
+    fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
+        let lifetime = fold::noop_fold_lifetime(lifetime, self);
+        self.insert(lifetime.id, EntryLifetime(self.parent, @lifetime));
+        lifetime
+    }
 }
 
 pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
@@ -658,6 +680,9 @@ fn node_id_to_str(map: &Map, id: NodeId) -> ~str {
         Some(NodeStructCtor(_)) => {
             format!("struct_ctor {} (id={})", map.path_to_str(id), id)
         }
+        Some(NodeLifetime(ref l)) => {
+            format!("lifetime {} (id={})", pprust::lifetime_to_str(*l), id)
+        }
         None => {
             format!("unknown node (id={})", id)
         }
index 63df5566fa5df27803e92ddd1fa884eb5ecd3980..cc3ae025263d196e03b8ce298f9a55d6a0860df5 100644 (file)
@@ -32,14 +32,17 @@ fn fold_view_paths(&mut self, view_paths: &[@ViewPath]) -> Vec<@ViewPath> {
         view_paths.iter().map(|view_path| {
             let inner_view_path = match view_path.node {
                 ViewPathSimple(ref ident, ref path, node_id) => {
+                    let id = self.new_id(node_id);
                     ViewPathSimple(ident.clone(),
                                    self.fold_path(path),
-                                   self.new_id(node_id))
+                                   id)
                 }
                 ViewPathGlob(ref path, node_id) => {
-                    ViewPathGlob(self.fold_path(path), self.new_id(node_id))
+                    let id = self.new_id(node_id);
+                    ViewPathGlob(self.fold_path(path), id)
                 }
                 ViewPathList(ref path, ref path_list_idents, node_id) => {
+                    let id = self.new_id(node_id);
                     ViewPathList(self.fold_path(path),
                                  path_list_idents.iter().map(|path_list_ident| {
                                     let id = self.new_id(path_list_ident.node
@@ -55,7 +58,7 @@ fn fold_view_paths(&mut self, view_paths: &[@ViewPath]) -> Vec<@ViewPath> {
                                             path_list_ident.span)
                                     }
                                  }).collect(),
-                                 self.new_id(node_id))
+                                 id)
                 }
             };
             @Spanned {
@@ -78,10 +81,11 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
     }
 
     fn fold_struct_field(&mut self, sf: &StructField) -> StructField {
+        let id = self.new_id(sf.node.id);
         Spanned {
             node: ast::StructField_ {
                 kind: sf.node.kind,
-                id: self.new_id(sf.node.id),
+                id: id,
                 ty: self.fold_ty(sf.node.ty),
                 attrs: sf.node.attrs.iter().map(|e| fold_attribute_(*e, self)).collect()
             },
@@ -146,6 +150,7 @@ fn fold_expr(&mut self, e: @Expr) -> @Expr {
     }
 
     fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
+        let id = self.new_id(t.id);
         let node = match t.node {
             TyNil | TyBot | TyInfer => t.node.clone(),
             TyBox(ty) => TyBox(self.fold_ty(ty)),
@@ -161,7 +166,7 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
                     onceness: f.onceness,
                     bounds: fold_opt_bounds(&f.bounds, self),
                     decl: self.fold_fn_decl(f.decl),
-                    lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
+                    lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
                 }, fold_opt_lifetime(region, self))
             }
             TyProc(ref f) => {
@@ -170,12 +175,12 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
                     onceness: f.onceness,
                     bounds: fold_opt_bounds(&f.bounds, self),
                     decl: self.fold_fn_decl(f.decl),
-                    lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
+                    lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
                 })
             }
             TyBareFn(ref f) => {
                 TyBareFn(@BareFnTy {
-                    lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
+                    lifetimes: f.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
                     fn_style: f.fn_style,
                     abi: f.abi,
                     decl: self.fold_fn_decl(f.decl)
@@ -183,9 +188,10 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
             }
             TyTup(ref tys) => TyTup(tys.iter().map(|&ty| self.fold_ty(ty)).collect()),
             TyPath(ref path, ref bounds, id) => {
+                let id = self.new_id(id);
                 TyPath(self.fold_path(path),
                        fold_opt_bounds(bounds, self),
-                       self.new_id(id))
+                       id)
             }
             TyFixedLengthVec(ty, e) => {
                 TyFixedLengthVec(self.fold_ty(ty), self.fold_expr(e))
@@ -193,7 +199,7 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
             TyTypeof(expr) => TyTypeof(self.fold_expr(expr)),
         };
         P(Ty {
-            id: self.new_id(t.id),
+            id: id,
             span: self.new_span(t.span),
             node: node,
         })
@@ -218,6 +224,7 @@ fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod {
     }
 
     fn fold_variant(&mut self, v: &Variant) -> P<Variant> {
+        let id = self.new_id(v.node.id);
         let kind;
         match v.node.kind {
             TupleVariantKind(ref variant_args) => {
@@ -243,7 +250,7 @@ fn fold_variant(&mut self, v: &Variant) -> P<Variant> {
             name: v.node.name,
             attrs: attrs,
             kind: kind,
-            id: self.new_id(v.node.id),
+            id: id,
             disr_expr: de,
             vis: v.node.vis,
         };
@@ -263,15 +270,16 @@ fn fold_path(&mut self, p: &Path) -> Path {
             global: p.global,
             segments: p.segments.iter().map(|segment| ast::PathSegment {
                 identifier: self.fold_ident(segment.identifier),
-                lifetimes: segment.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
+                lifetimes: segment.lifetimes.iter().map(|l| self.fold_lifetime(l)).collect(),
                 types: segment.types.iter().map(|&typ| self.fold_ty(typ)).collect(),
             }).collect()
         }
     }
 
     fn fold_local(&mut self, l: @Local) -> @Local {
+        let id = self.new_id(l.id); // Needs to be first, for ast_map.
         @Local {
-            id: self.new_id(l.id), // Needs to be first, for ast_map.
+            id: id,
             ty: self.fold_ty(l.ty),
             pat: self.fold_pat(l.pat),
             init: l.init.map(|e| self.fold_expr(e)),
@@ -319,6 +327,10 @@ fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
             }
         }
     }
+
+    fn fold_lifetime(&mut self, l: &Lifetime) -> Lifetime {
+        noop_fold_lifetime(l, self)
+    }
 }
 
 /* some little folds that probably aren't useful to have in Folder itself*/
@@ -353,8 +365,9 @@ fn fold_attribute_<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
 
 //used in noop_fold_foreign_item and noop_fold_fn_decl
 fn fold_arg_<T: Folder>(a: &Arg, fld: &mut T) -> Arg {
+    let id = fld.new_id(a.id); // Needs to be first, for ast_map.
     Arg {
-        id: fld.new_id(a.id), // Needs to be first, for ast_map.
+        id: id,
         ty: fld.fold_ty(a.ty),
         pat: fld.fold_pat(a.pat),
     }
@@ -425,9 +438,10 @@ fn fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
 }
 
 pub fn fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam {
+    let id = fld.new_id(tp.id);
     TyParam {
         ident: tp.ident,
-        id: fld.new_id(tp.id),
+        id: id,
         bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
         default: tp.default.map(|x| fld.fold_ty(x))
     }
@@ -438,9 +452,10 @@ pub fn fold_ty_params<T: Folder>(tps: &OwnedSlice<TyParam>, fld: &mut T)
     tps.map(|tp| fold_ty_param(tp, fld))
 }
 
-pub fn fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
+pub fn noop_fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
+    let id = fld.new_id(l.id);
     Lifetime {
-        id: fld.new_id(l.id),
+        id: id,
         span: fld.new_span(l.span),
         name: l.name
     }
@@ -448,12 +463,12 @@ pub fn fold_lifetime<T: Folder>(l: &Lifetime, fld: &mut T) -> Lifetime {
 
 pub fn fold_lifetimes<T: Folder>(lts: &Vec<Lifetime>, fld: &mut T)
                                    -> Vec<Lifetime> {
-    lts.iter().map(|l| fold_lifetime(l, fld)).collect()
+    lts.iter().map(|l| fld.fold_lifetime(l)).collect()
 }
 
 pub fn fold_opt_lifetime<T: Folder>(o_lt: &Option<Lifetime>, fld: &mut T)
                                       -> Option<Lifetime> {
-    o_lt.as_ref().map(|lt| fold_lifetime(lt, fld))
+    o_lt.as_ref().map(|lt| fld.fold_lifetime(lt))
 }
 
 pub fn fold_generics<T: Folder>(generics: &Generics, fld: &mut T) -> Generics {
@@ -469,17 +484,19 @@ fn fold_struct_def<T: Folder>(struct_def: @StructDef, fld: &mut T) -> @StructDef
 }
 
 fn fold_trait_ref<T: Folder>(p: &TraitRef, fld: &mut T) -> TraitRef {
+    let id = fld.new_id(p.ref_id);
     ast::TraitRef {
         path: fld.fold_path(&p.path),
-        ref_id: fld.new_id(p.ref_id),
+        ref_id: id,
     }
 }
 
 fn fold_struct_field<T: Folder>(f: &StructField, fld: &mut T) -> StructField {
+    let id = fld.new_id(f.node.id);
     Spanned {
         node: ast::StructField_ {
             kind: f.node.kind,
-            id: fld.new_id(f.node.id),
+            id: id,
             ty: fld.fold_ty(f.node.ty),
             attrs: f.node.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
         },
@@ -512,9 +529,10 @@ fn fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut
 }
 
 fn fold_variant_arg_<T: Folder>(va: &VariantArg, folder: &mut T) -> VariantArg {
+    let id = folder.new_id(va.id);
     ast::VariantArg {
         ty: folder.fold_ty(va.ty),
-        id: folder.new_id(va.id)
+        id: id,
     }
 }
 
@@ -539,10 +557,11 @@ pub fn noop_fold_view_item<T: Folder>(vi: &ViewItem, folder: &mut T)
 }
 
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
+    let id = folder.new_id(b.id); // Needs to be first, for ast_map.
     let view_items = b.view_items.iter().map(|x| folder.fold_view_item(x)).collect();
     let stmts = b.stmts.iter().flat_map(|s| folder.fold_stmt(*s).move_iter()).collect();
     P(Block {
-        id: folder.new_id(b.id), // Needs to be first, for ast_map.
+        id: id,
         view_items: view_items,
         stmts: stmts,
         expr: b.expr.map(|x| folder.fold_expr(x)),
@@ -606,8 +625,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_
 }
 
 pub fn noop_fold_type_method<T: Folder>(m: &TypeMethod, fld: &mut T) -> TypeMethod {
+    let id = fld.new_id(m.id); // Needs to be first, for ast_map.
     TypeMethod {
-        id: fld.new_id(m.id), // Needs to be first, for ast_map.
+        id: id,
         ident: fld.fold_ident(m.ident),
         attrs: m.attrs.iter().map(|a| fold_attribute_(*a, fld)).collect(),
         fn_style: m.fn_style,
@@ -658,8 +678,9 @@ pub fn noop_fold_item<T: Folder>(i: &Item, folder: &mut T) -> SmallVector<@Item>
 }
 
 pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem, folder: &mut T) -> @ForeignItem {
+    let id = folder.new_id(ni.id); // Needs to be first, for ast_map.
     @ForeignItem {
-        id: folder.new_id(ni.id), // Needs to be first, for ast_map.
+        id: id,
         ident: folder.fold_ident(ni.ident),
         attrs: ni.attrs.iter().map(|x| fold_attribute_(*x, folder)).collect(),
         node: match ni.node {
@@ -681,8 +702,9 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: &ForeignItem, folder: &mut T) -> @F
 }
 
 pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
+    let id = folder.new_id(m.id); // Needs to be first, for ast_map.
     @Method {
-        id: folder.new_id(m.id), // Needs to be first, for ast_map.
+        id: id,
         ident: folder.fold_ident(m.ident),
         attrs: m.attrs.iter().map(|a| fold_attribute_(*a, folder)).collect(),
         generics: fold_generics(&m.generics, folder),
@@ -696,6 +718,7 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
 }
 
 pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
+    let id = folder.new_id(p.id);
     let node = match p.node {
         PatWild => PatWild,
         PatWildMulti => PatWildMulti,
@@ -733,13 +756,14 @@ pub fn noop_fold_pat<T: Folder>(p: @Pat, folder: &mut T) -> @Pat {
     };
 
     @Pat {
-        id: folder.new_id(p.id),
+        id: id,
         span: folder.new_span(p.span),
         node: node,
     }
 }
 
 pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
+    let id = folder.new_id(e.id);
     let node = match e.node {
         ExprVstore(e, v) => {
             ExprVstore(folder.fold_expr(e), v)
@@ -849,7 +873,7 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
     };
 
     @Expr {
-        id: folder.new_id(e.id),
+        id: id,
         node: node,
         span: folder.new_span(e.span),
     }
@@ -857,16 +881,19 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
 
 pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt> {
     let nodes = match s.node {
-        StmtDecl(d, nid) => {
+        StmtDecl(d, id) => {
+            let id = folder.new_id(id);
             folder.fold_decl(d).move_iter()
-                    .map(|d| StmtDecl(d, folder.new_id(nid)))
+                    .map(|d| StmtDecl(d, id))
                     .collect()
         }
-        StmtExpr(e, nid) => {
-            SmallVector::one(StmtExpr(folder.fold_expr(e), folder.new_id(nid)))
+        StmtExpr(e, id) => {
+            let id = folder.new_id(id);
+            SmallVector::one(StmtExpr(folder.fold_expr(e), id))
         }
-        StmtSemi(e, nid) => {
-            SmallVector::one(StmtSemi(folder.fold_expr(e), folder.new_id(nid)))
+        StmtSemi(e, id) => {
+            let id = folder.new_id(id);
+            SmallVector::one(StmtSemi(folder.fold_expr(e), id))
         }
         StmtMac(ref mac, semi) => SmallVector::one(StmtMac(folder.fold_mac(mac), semi))
     };