about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-10-29 06:03:32 -0400
committerNiko Matsakis <niko@alum.mit.edu>2013-11-08 19:42:46 -0500
commit1f4faaee401f8681e25afbcf3b6296b6cd2ca55a (patch)
treef0dac4e7f58ebab635c4bba59a04fca2833db4a8 /src/libsyntax
parent85c51d3b02e421e2ab99c330e0d8212293f64f04 (diff)
downloadrust-1f4faaee401f8681e25afbcf3b6296b6cd2ca55a.tar.gz
rust-1f4faaee401f8681e25afbcf3b6296b6cd2ca55a.zip
Generalize AST and ty::Generics to accept multiple lifetimes.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs10
-rw-r--r--src/libsyntax/ast_map.rs12
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/ext/build.rs14
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic.rs8
-rw-r--r--src/libsyntax/ext/deriving/rand.rs3
-rw-r--r--src/libsyntax/ext/deriving/ty.rs18
-rw-r--r--src/libsyntax/ext/expand.rs4
-rw-r--r--src/libsyntax/ext/format.rs7
-rw-r--r--src/libsyntax/fold.rs35
-rw-r--r--src/libsyntax/opt_vec.rs10
-rw-r--r--src/libsyntax/parse/mod.rs20
-rw-r--r--src/libsyntax/parse/parser.rs55
-rw-r--r--src/libsyntax/print/pprust.rs7
15 files changed, 120 insertions, 93 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index c0c2e2822f1..6245c61dfa1 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -28,7 +28,7 @@ use extra::serialize::{Encodable, Decodable, Encoder, Decoder};
 // table) and a SyntaxContext to track renaming and
 // macro expansion per Flatt et al., "Macros
 // That Work Together"
-#[deriving(Clone, IterBytes, ToStr)]
+#[deriving(Clone, IterBytes, ToStr, TotalEq, TotalOrd)]
 pub struct Ident { name: Name, ctxt: SyntaxContext }
 
 impl Ident {
@@ -110,6 +110,7 @@ pub enum SyntaxContext_ {
 /// A name is a part of an identifier, representing a string or gensym. It's
 /// the result of interning.
 pub type Name = uint;
+
 /// A mark represents a unique id associated with a macro expansion
 pub type Mrk = uint;
 
@@ -156,9 +157,8 @@ pub struct Path {
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     identifier: Ident,
-    /// The lifetime parameter for this path segment. Currently only one
-    /// lifetime parameter is allowed.
-    lifetime: Option<Lifetime>,
+    /// The lifetime parameters for this path segment.
+    lifetimes: OptVec<Lifetime>,
     /// The type parameters for this path segment, if present.
     types: OptVec<Ty>,
 }
@@ -167,7 +167,7 @@ pub type CrateNum = int;
 
 pub type NodeId = int;
 
-#[deriving(Clone, Eq, Encodable, Decodable, IterBytes, ToStr)]
+#[deriving(Clone, TotalEq, TotalOrd, Eq, Encodable, Decodable, IterBytes, ToStr)]
 pub struct DefId {
     crate: CrateNum,
     node: NodeId,
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 17613d19c7e..f3d7ac1804d 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -488,3 +488,15 @@ pub fn node_item_query<Result>(items: map, id: NodeId,
         _ => fail!("{}", error_msg)
     }
 }
+
+pub fn item_span(items: map,
+                 id: ast::NodeId)
+                 -> Span {
+    match items.find(&id) {
+        Some(&node_item(item, _)) => item.span,
+        r => {
+            fail!(format!("item_span: expected item with id {} but found {:?}",
+                           id, r))
+        }
+    }
+}
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 3ec87dbdd26..ccae25dc012 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -225,7 +225,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
         segments: ~[
             ast::PathSegment {
                 identifier: identifier,
-                lifetime: None,
+                lifetimes: opt_vec::Empty,
                 types: opt_vec::Empty,
             }
         ],
@@ -948,7 +948,7 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo
         for (idx,seg) in a.iter().enumerate() {
             if (seg.identifier.name != b[idx].identifier.name)
                 // FIXME #7743: ident -> name problems in lifetime comparison?
-                || (seg.lifetime != b[idx].lifetime)
+                || (seg.lifetimes != b[idx].lifetimes)
                 // can types contain idents?
                 || (seg.types != b[idx].types) {
                 return false;
@@ -966,7 +966,9 @@ mod test {
     use std::hashmap::HashMap;
 
     fn ident_to_segment(id : &Ident) -> PathSegment {
-        PathSegment{identifier:id.clone(), lifetime: None, types: opt_vec::Empty}
+        PathSegment {identifier:id.clone(),
+                     lifetimes: opt_vec::Empty,
+                     types: opt_vec::Empty}
     }
 
     #[test] fn idents_name_eq_test() {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 0a5e20fc2b2..5ae158045e0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -38,7 +38,7 @@ pub trait AstBuilder {
     fn path_all(&self, sp: Span,
                 global: bool,
                 idents: ~[ast::Ident],
-                rp: Option<ast::Lifetime>,
+                lifetimes: OptVec<ast::Lifetime>,
                 types: ~[ast::Ty])
         -> ast::Path;
 
@@ -237,19 +237,19 @@ pub trait AstBuilder {
 
 impl AstBuilder for @ExtCtxt {
     fn path(&self, span: Span, strs: ~[ast::Ident]) -> ast::Path {
-        self.path_all(span, false, strs, None, ~[])
+        self.path_all(span, false, strs, opt_vec::Empty, ~[])
     }
     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
         self.path(span, ~[id])
     }
     fn path_global(&self, span: Span, strs: ~[ast::Ident]) -> ast::Path {
-        self.path_all(span, true, strs, None, ~[])
+        self.path_all(span, true, strs, opt_vec::Empty, ~[])
     }
     fn path_all(&self,
                 sp: Span,
                 global: bool,
                 mut idents: ~[ast::Ident],
-                rp: Option<ast::Lifetime>,
+                lifetimes: OptVec<ast::Lifetime>,
                 types: ~[ast::Ty])
                 -> ast::Path {
         let last_identifier = idents.pop();
@@ -257,13 +257,13 @@ impl AstBuilder for @ExtCtxt {
                                                       .map(|ident| {
             ast::PathSegment {
                 identifier: ident,
-                lifetime: None,
+                lifetimes: opt_vec::Empty,
                 types: opt_vec::Empty,
             }
         }).collect();
         segments.push(ast::PathSegment {
             identifier: last_identifier,
-            lifetime: rp,
+            lifetimes: lifetimes,
             types: opt_vec::from(types),
         });
         ast::Path {
@@ -327,7 +327,7 @@ impl AstBuilder for @ExtCtxt {
                               self.ident_of("option"),
                               self.ident_of("Option")
                           ],
-                          None,
+                          opt_vec::Empty,
                           ~[ ty ]), None)
     }
 
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 0ca18f1208d..216bc3097ce 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -43,7 +43,7 @@ pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree])
                  segments: ~[
                     ast::PathSegment {
                         identifier: res,
-                        lifetime: None,
+                        lifetimes: opt_vec::Empty,
                         types: opt_vec::Empty,
                     }
                 ]
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index cfb6048df18..b37757341ef 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -375,14 +375,10 @@ impl<'self> TraitDef<'self> {
             cx.ty_ident(trait_span, ty_param.ident)
         };
 
-        let self_lifetime = if generics.lifetimes.is_empty() {
-            None
-        } else {
-            Some(*generics.lifetimes.get(0))
-        };
+        let self_lifetimes = generics.lifetimes.clone();
 
         // Create the type of `self`.
-        let self_type = cx.ty_path(cx.path_all(trait_span, false, ~[ type_ident ], self_lifetime,
+        let self_type = cx.ty_path(cx.path_all(trait_span, false, ~[ type_ident ], self_lifetimes,
                                                opt_vec::take_vec(self_ty_params)), None);
 
         let doc_attr = cx.attribute(
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index 1e2a6fa2eb5..d014816c070 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -14,6 +14,7 @@ use codemap::Span;
 use ext::base::ExtCtxt;
 use ext::build::{AstBuilder};
 use ext::deriving::generic::*;
+use opt_vec;
 
 pub fn expand_deriving_rand(cx: @ExtCtxt,
                             span: Span,
@@ -77,7 +78,7 @@ fn rand_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr {
             let rand_name = cx.path_all(span,
                                         true,
                                         rand_ident.clone(),
-                                        None,
+                                        opt_vec::Empty,
                                         ~[]);
             let rand_name = cx.expr_path(rand_name);
 
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index c60259304ae..d1a5af5f7e8 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -19,6 +19,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use codemap::{Span,respan};
 use opt_vec;
+use opt_vec::OptVec;
 
 /// The types of pointers
 pub enum PtrTy<'self> {
@@ -71,7 +72,7 @@ impl<'self> Path<'self> {
                    self_generics: &Generics)
                    -> ast::Path {
         let idents = self.path.map(|s| cx.ident_of(*s) );
-        let lt = mk_lifetime(cx, span, &self.lifetime);
+        let lt = mk_lifetimes(cx, span, &self.lifetime);
         let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics));
 
         cx.path_all(span, self.global, idents, lt, tys)
@@ -116,6 +117,13 @@ fn mk_lifetime(cx: @ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifet
     }
 }
 
+fn mk_lifetimes(cx: @ExtCtxt, span: Span, lt: &Option<&str>) -> OptVec<ast::Lifetime> {
+    match *lt {
+        Some(ref s) => opt_vec::with(cx.lifetime(span, cx.ident_of(*s))),
+        None => opt_vec::Empty
+    }
+}
+
 impl<'self> Ty<'self> {
     pub fn to_ty(&self,
                  cx: @ExtCtxt,
@@ -166,13 +174,9 @@ impl<'self> Ty<'self> {
                 let self_params = do self_generics.ty_params.map |ty_param| {
                     cx.ty_ident(span, ty_param.ident)
                 };
-                let lifetime = if self_generics.lifetimes.is_empty() {
-                    None
-                } else {
-                    Some(*self_generics.lifetimes.get(0))
-                };
+                let lifetimes = self_generics.lifetimes.clone();
 
-                cx.path_all(span, false, ~[self_ty], lifetime,
+                cx.path_all(span, false, ~[self_ty], lifetimes,
                             opt_vec::take_vec(self_params))
             }
             Literal(ref p) => {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index ba946d5fb1f..b74349da2a9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -169,7 +169,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
                     segments: ~[
                         ast::PathSegment {
                             identifier: ident,
-                            lifetime: None,
+                            lifetimes: opt_vec::Empty,
                             types: opt_vec::Empty,
                         }
                     ],
@@ -628,7 +628,7 @@ impl Visitor<()> for NewNameFinderContext {
                         segments: [
                             ast::PathSegment {
                                 identifier: id,
-                                lifetime: _,
+                                lifetimes: _,
                                 types: _
                             }
                         ]
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 943279d2dc6..00919fce5db 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -15,7 +15,7 @@ use ext::base;
 use ext::build::AstBuilder;
 use rsparse = parse;
 use parse::token;
-
+use opt_vec;
 use std::fmt::parse;
 use std::hashmap::{HashMap, HashSet};
 use std::vec;
@@ -464,7 +464,7 @@ impl Context {
                 sp,
                 true,
                 rtpath("Method"),
-                Some(life),
+                opt_vec::with(life),
                 ~[]
             ), None);
             let st = ast::item_static(ty, ast::MutImmutable, method);
@@ -582,7 +582,8 @@ impl Context {
                     self.ecx.ident_of("rt"),
                     self.ecx.ident_of("Piece"),
                 ],
-                Some(self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("static"))),
+                opt_vec::with(
+                    self.ecx.lifetime(self.fmtsp, self.ecx.ident_of("static"))),
                 ~[]
             ), None);
         let ty = ast::ty_fixed_length_vec(
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 388de29b456..ea0ab95a451 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -144,7 +144,7 @@ pub trait ast_fold {
             ident: self.fold_ident(m.ident),
             attrs: m.attrs.map(|a| fold_attribute_(*a, self)),
             generics: fold_generics(&m.generics, self),
-            explicit_self: m.explicit_self,
+            explicit_self: self.fold_explicit_self(&m.explicit_self),
             purity: m.purity,
             decl: fold_fn_decl(&m.decl, self),
             body: self.fold_block(&m.body),
@@ -245,12 +245,14 @@ pub trait ast_fold {
             ty_uniq(ref mt) => ty_uniq(fold_mt(mt, self)),
             ty_vec(ref mt) => ty_vec(fold_mt(mt, self)),
             ty_ptr(ref mt) => ty_ptr(fold_mt(mt, self)),
-            ty_rptr(region, ref mt) => ty_rptr(region, fold_mt(mt, self)),
+            ty_rptr(ref region, ref mt) => {
+                ty_rptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
+            }
             ty_closure(ref f) => {
                 ty_closure(@TyClosure {
                     sigil: f.sigil,
                     purity: f.purity,
-                    region: f.region,
+                    region: fold_opt_lifetime(&f.region, self),
                     onceness: f.onceness,
                     bounds: fold_opt_bounds(&f.bounds, self),
                     decl: fold_fn_decl(&f.decl, self),
@@ -349,7 +351,7 @@ pub trait ast_fold {
             global: p.global,
             segments: p.segments.map(|segment| ast::PathSegment {
                 identifier: self.fold_ident(segment.identifier),
-                lifetime: segment.lifetime,
+                lifetimes: segment.lifetimes.map(|l| fold_lifetime(l, self)),
                 types: segment.types.map(|typ| self.fold_ty(typ)),
             })
         }
@@ -389,6 +391,24 @@ pub trait ast_fold {
     fn new_span(&self, sp: Span) -> Span {
         sp
     }
+
+    fn fold_explicit_self(&self, es: &explicit_self) -> explicit_self {
+        Spanned {
+            span: self.new_span(es.span),
+            node: self.fold_explicit_self_(&es.node)
+        }
+    }
+
+    fn fold_explicit_self_(&self, es: &explicit_self_) -> explicit_self_ {
+        match *es {
+            sty_static | sty_value(_) | sty_uniq(_) | sty_box(_) => {
+                *es
+            }
+            sty_region(ref lifetime, m) => {
+                sty_region(fold_opt_lifetime(lifetime, self), m)
+            }
+        }
+    }
 }
 
 /* some little folds that probably aren't useful to have in ast_fold itself*/
@@ -505,6 +525,11 @@ pub fn fold_lifetimes<T:ast_fold>(lts: &OptVec<Lifetime>, fld: &T)
     lts.map(|l| fold_lifetime(l, fld))
 }
 
+pub fn fold_opt_lifetime<T:ast_fold>(o_lt: &Option<Lifetime>, fld: &T)
+                                     -> Option<Lifetime> {
+    o_lt.as_ref().map(|lt| fold_lifetime(lt, fld))
+}
+
 pub fn fold_generics<T:ast_fold>(generics: &Generics, fld: &T) -> Generics {
     Generics {ty_params: fold_ty_params(&generics.ty_params, fld),
               lifetimes: fold_lifetimes(&generics.lifetimes, fld)}
@@ -675,7 +700,7 @@ pub fn noop_fold_type_method<T:ast_fold>(m: &TypeMethod, fld: &T)
         purity: m.purity,
         decl: fold_fn_decl(&m.decl, fld),
         generics: fold_generics(&m.generics, fld),
-        explicit_self: m.explicit_self,
+        explicit_self: fld.fold_explicit_self(&m.explicit_self),
         id: fld.new_id(m.id),
         span: fld.new_span(m.span),
     }
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index 2000d0b9746..4d39d4df72f 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -165,3 +165,13 @@ impl<'self, T> Iterator<&'self T> for OptVecIterator<'self, T> {
         }
     }
 }
+
+impl<A> FromIterator<A> for OptVec<A> {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> OptVec<A> {
+        let mut r = Empty;
+        for x in *iterator {
+            r.push(x);
+        }
+        r
+    }
+}
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 6c81784b5de..672865aadcc 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -368,7 +368,7 @@ mod test {
                         segments: ~[
                             ast::PathSegment {
                                 identifier: str_to_ident("a"),
-                                lifetime: None,
+                                lifetimes: opt_vec::Empty,
                                 types: opt_vec::Empty,
                             }
                         ],
@@ -387,12 +387,12 @@ mod test {
                             segments: ~[
                                 ast::PathSegment {
                                     identifier: str_to_ident("a"),
-                                    lifetime: None,
+                                    lifetimes: opt_vec::Empty,
                                     types: opt_vec::Empty,
                                 },
                                 ast::PathSegment {
                                     identifier: str_to_ident("b"),
-                                    lifetime: None,
+                                    lifetimes: opt_vec::Empty,
                                     types: opt_vec::Empty,
                                 }
                             ]
@@ -592,7 +592,7 @@ mod test {
                             segments: ~[
                                 ast::PathSegment {
                                     identifier: str_to_ident("d"),
-                                    lifetime: None,
+                                    lifetimes: opt_vec::Empty,
                                     types: opt_vec::Empty,
                                 }
                             ],
@@ -614,7 +614,7 @@ mod test {
                                segments: ~[
                                 ast::PathSegment {
                                     identifier: str_to_ident("b"),
-                                    lifetime: None,
+                                    lifetimes: opt_vec::Empty,
                                     types: opt_vec::Empty,
                                 }
                                ],
@@ -641,7 +641,7 @@ mod test {
                                     segments: ~[
                                         ast::PathSegment {
                                             identifier: str_to_ident("b"),
-                                            lifetime: None,
+                                            lifetimes: opt_vec::Empty,
                                             types: opt_vec::Empty,
                                         }
                                     ],
@@ -669,7 +669,7 @@ mod test {
                                             ast::PathSegment {
                                                 identifier:
                                                     str_to_ident("int"),
-                                                lifetime: None,
+                                                lifetimes: opt_vec::Empty,
                                                 types: opt_vec::Empty,
                                             }
                                         ],
@@ -687,7 +687,7 @@ mod test {
                                                     ast::PathSegment {
                                                         identifier:
                                                             str_to_ident("b"),
-                                                        lifetime: None,
+                                                        lifetimes: opt_vec::Empty,
                                                         types: opt_vec::Empty,
                                                     }
                                                 ],
@@ -724,8 +724,8 @@ mod test {
                                                                 identifier:
                                                                 str_to_ident(
                                                                     "b"),
-                                                                lifetime:
-                                                                    None,
+                                                                lifetimes:
+                                                                opt_vec::Empty,
                                                                 types:
                                                                 opt_vec::Empty
                                                             }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7c98d8d1c85..cfb4da87720 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1490,7 +1490,7 @@ impl Parser {
                 segments.push(PathSegmentAndBoundSet {
                     segment: ast::PathSegment {
                         identifier: identifier,
-                        lifetime: None,
+                        lifetimes: opt_vec::Empty,
                         types: opt_vec::Empty,
                     },
                     bound_set: bound_set
@@ -1499,46 +1499,21 @@ impl Parser {
             }
 
             // Parse the `<` before the lifetime and types, if applicable.
-            let (any_lifetime_or_types, optional_lifetime, types) =
-                    if mode != NoTypesAllowed && self.eat(&token::LT) {
-                // Parse an optional lifetime.
-                let optional_lifetime = match *self.token {
-                    token::LIFETIME(*) => Some(self.parse_lifetime()),
-                    _ => None,
-                };
-
-                // Parse type parameters.
-                let mut types = opt_vec::Empty;
-                let mut need_comma = optional_lifetime.is_some();
-                loop {
-                    // We're done if we see a `>`.
-                    match *self.token {
-                        token::GT | token::BINOP(token::SHR) => {
-                            self.expect_gt();
-                            break
-                        }
-                        _ => {} // Go on.
-                    }
-
-                    if need_comma {
-                        self.expect(&token::COMMA)
-                    } else {
-                        need_comma = true
-                    }
-
-                    types.push(self.parse_ty(false))
+            let (any_lifetime_or_types, lifetimes, types) = {
+                if mode != NoTypesAllowed && self.eat(&token::LT) {
+                    let (lifetimes, types) =
+                        self.parse_generic_values_after_lt();
+                    (true, lifetimes, opt_vec::from(types))
+                } else {
+                    (false, opt_vec::Empty, opt_vec::Empty)
                 }
-
-                (true, optional_lifetime, types)
-            } else {
-                (false, None, opt_vec::Empty)
             };
 
             // Assemble and push the result.
             segments.push(PathSegmentAndBoundSet {
                 segment: ast::PathSegment {
                     identifier: identifier,
-                    lifetime: optional_lifetime,
+                    lifetimes: lifetimes,
                     types: types,
                 },
                 bound_set: bound_set
@@ -1609,11 +1584,11 @@ impl Parser {
     pub fn parse_lifetime(&self) -> ast::Lifetime {
         match *self.token {
             token::LIFETIME(i) => {
-                let span = self.span;
+                let span = *self.span;
                 self.bump();
                 return ast::Lifetime {
                     id: ast::DUMMY_NODE_ID,
-                    span: *span,
+                    span: span,
                     ident: i
                 };
             }
@@ -4856,7 +4831,7 @@ impl Parser {
                 segments: path.move_iter().map(|identifier| {
                     ast::PathSegment {
                         identifier: identifier,
-                        lifetime: None,
+                        lifetimes: opt_vec::Empty,
                         types: opt_vec::Empty,
                     }
                 }).collect()
@@ -4892,7 +4867,7 @@ impl Parser {
                         segments: path.move_iter().map(|identifier| {
                             ast::PathSegment {
                                 identifier: identifier,
-                                lifetime: None,
+                                lifetimes: opt_vec::Empty,
                                 types: opt_vec::Empty,
                             }
                         }).collect()
@@ -4910,7 +4885,7 @@ impl Parser {
                         segments: path.move_iter().map(|identifier| {
                             ast::PathSegment {
                                 identifier: identifier,
-                                lifetime: None,
+                                lifetimes: opt_vec::Empty,
                                 types: opt_vec::Empty,
                             }
                         }).collect()
@@ -4932,7 +4907,7 @@ impl Parser {
             segments: path.move_iter().map(|identifier| {
                 ast::PathSegment {
                     identifier: identifier,
-                    lifetime: None,
+                    lifetimes: opt_vec::Empty,
                     types: opt_vec::Empty,
                 }
             }).collect()
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 08c2ae88e4f..fd02ac68f4e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1566,13 +1566,13 @@ fn print_path_(s: @ps,
             }
         }
 
-        if segment.lifetime.is_some() || !segment.types.is_empty() {
+        if !segment.lifetimes.is_empty() || !segment.types.is_empty() {
             if colons_before_params {
                 word(s.s, "::")
             }
             word(s.s, "<");
 
-            for lifetime in segment.lifetime.iter() {
+            for lifetime in segment.lifetimes.iter() {
                 print_lifetime(s, lifetime);
                 if !segment.types.is_empty() {
                     word_space(s, ",")
@@ -1905,7 +1905,8 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) {
 pub fn print_view_path(s: @ps, vp: &ast::view_path) {
     match vp.node {
       ast::view_path_simple(ident, ref path, _) => {
-        if path.segments.last().identifier != ident {
+            // FIXME can't compare identifiers directly here
+        if path.segments.last().identifier.name != ident.name {
             print_ident(s, ident);
             space(s.s);
             word_space(s, "=");