about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-01-07 05:31:23 +0000
committerbors <bors@rust-lang.org>2015-01-07 05:31:23 +0000
commit9e4e524e0eb17c8f463e731f23b544003e8709c6 (patch)
tree916024d35e08f0826c20654f629ec596b5cb1f14 /src/libsyntax/parse/parser.rs
parentea6f65c5f1a3f84e010d2cef02a0160804e9567a (diff)
parenta64000820f0fc32be4d7535a9a92418a434fa4ba (diff)
downloadrust-9e4e524e0eb17c8f463e731f23b544003e8709c6.tar.gz
rust-9e4e524e0eb17c8f463e731f23b544003e8709c6.zip
auto merge of #20677 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs411
1 files changed, 190 insertions, 221 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 32f8f5ee3d6..92e0395eca4 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -63,7 +63,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
 use ast::{Visibility, WhereClause};
 use ast;
 use ast_util::{self, as_prec, ident_to_path, operator_prec};
-use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, DUMMY_SP};
+use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp};
 use diagnostic;
 use ext::tt::macro_parser;
 use parse;
@@ -389,12 +389,12 @@ impl<'a> Parser<'a> {
         let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, format!("unexpected token: `{}`",
-                                                token_str)[]);
+                                                token_str).index(&FullRange));
     }
 
     pub fn unexpected(&mut self) -> ! {
         let this_token = self.this_token_to_string();
-        self.fatal(format!("unexpected token: `{}`", this_token)[]);
+        self.fatal(format!("unexpected token: `{}`", this_token).index(&FullRange));
     }
 
     /// Expect and consume the token t. Signal an error if
@@ -408,7 +408,7 @@ impl<'a> Parser<'a> {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(format!("expected `{}`, found `{}`",
                                    token_str,
-                                   this_token_str)[])
+                                   this_token_str).index(&FullRange))
             }
         } else {
             self.expect_one_of(slice::ref_slice(t), &[]);
@@ -449,7 +449,7 @@ impl<'a> Parser<'a> {
             expected.push_all(&*self.expected_tokens);
             expected.sort_by(|a, b| a.to_string().cmp(&b.to_string()));
             expected.dedup();
-            let expect = tokens_to_string(expected[]);
+            let expect = tokens_to_string(expected.index(&FullRange));
             let actual = self.this_token_to_string();
             self.fatal(
                 (if expected.len() != 1 {
@@ -460,7 +460,7 @@ impl<'a> Parser<'a> {
                     (format!("expected {}, found `{}`",
                              expect,
                              actual))
-                })[]
+                }).index(&FullRange)
             )
         }
     }
@@ -488,12 +488,12 @@ impl<'a> Parser<'a> {
     /// followed by some token from the set edible + inedible.  Recover
     /// from anticipated input errors, discarding erroneous characters.
     pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token], inedible: &[token::Token]) {
-        debug!("commit_expr {}", e);
+        debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
             let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
             expected.push_all(inedible);
-            self.check_for_erroneous_unit_struct_expecting(expected[]);
+            self.check_for_erroneous_unit_struct_expecting(expected.index(&FullRange));
         }
         self.expect_one_of(edible, inedible)
     }
@@ -510,9 +510,9 @@ impl<'a> Parser<'a> {
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
             let mut expected = edible.iter().map(|x| x.clone()).collect::<Vec<_>>();
-            expected.push_all(inedible[]);
+            expected.push_all(inedible.index(&FullRange));
             self.check_for_erroneous_unit_struct_expecting(
-                expected[]);
+                expected.index(&FullRange));
         }
         self.expect_one_of(edible, inedible)
     }
@@ -535,7 +535,7 @@ impl<'a> Parser<'a> {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal((format!("expected ident, found `{}`",
-                                    token_str))[])
+                                    token_str)).index(&FullRange))
             }
         }
     }
@@ -593,7 +593,7 @@ impl<'a> Parser<'a> {
             let id_interned_str = token::get_name(kw.to_name());
             let token_str = self.this_token_to_string();
             self.fatal(format!("expected `{}`, found `{}`",
-                               id_interned_str, token_str)[])
+                               id_interned_str, token_str).index(&FullRange))
         }
     }
 
@@ -604,7 +604,7 @@ impl<'a> Parser<'a> {
             let span = self.span;
             self.span_err(span,
                           format!("expected identifier, found keyword `{}`",
-                                  token_str)[]);
+                                  token_str).index(&FullRange));
         }
     }
 
@@ -613,7 +613,7 @@ impl<'a> Parser<'a> {
         if self.token.is_reserved_keyword() {
             let token_str = self.this_token_to_string();
             self.fatal(format!("`{}` is a reserved keyword",
-                               token_str)[])
+                               token_str).index(&FullRange))
         }
     }
 
@@ -633,7 +633,7 @@ impl<'a> Parser<'a> {
                     Parser::token_to_string(&token::BinOp(token::And));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    found_token,
-                                   token_str)[])
+                                   token_str).index(&FullRange))
             }
         }
     }
@@ -654,7 +654,7 @@ impl<'a> Parser<'a> {
                     Parser::token_to_string(&token::BinOp(token::Or));
                 self.fatal(format!("expected `{}`, found `{}`",
                                    token_str,
-                                   found_token)[])
+                                   found_token).index(&FullRange))
             }
         }
     }
@@ -697,7 +697,7 @@ impl<'a> Parser<'a> {
             let token_str = Parser::token_to_string(&token::Lt);
             self.fatal(format!("expected `{}`, found `{}`",
                                token_str,
-                               found_token)[])
+                               found_token).index(&FullRange))
         }
     }
 
@@ -749,7 +749,7 @@ impl<'a> Parser<'a> {
                 let this_token_str = self.this_token_to_string();
                 self.fatal(format!("expected `{}`, found `{}`",
                                    gt_str,
-                                   this_token_str)[])
+                                   this_token_str).index(&FullRange))
             }
         }
     }
@@ -946,6 +946,8 @@ impl<'a> Parser<'a> {
         self.token = next.tok;
         self.tokens_consumed += 1u;
         self.expected_tokens.clear();
+        // check after each token
+        self.check_unknown_macro_variable();
     }
 
     /// Advance the parser by one token and return the bumped token.
@@ -1369,7 +1371,7 @@ impl<'a> Parser<'a> {
                     let (inner_attrs, body) =
                         p.parse_inner_attrs_and_block();
                     let mut attrs = attrs;
-                    attrs.push_all(inner_attrs[]);
+                    attrs.push_all(inner_attrs.index(&FullRange));
                     ProvidedMethod(P(ast::Method {
                         attrs: attrs,
                         id: ast::DUMMY_NODE_ID,
@@ -1388,7 +1390,7 @@ impl<'a> Parser<'a> {
                   _ => {
                       let token_str = p.this_token_to_string();
                       p.fatal((format!("expected `;` or `{{`, found `{}`",
-                                       token_str))[])
+                                       token_str)).index(&FullRange))
                   }
                 }
             }
@@ -1584,7 +1586,7 @@ impl<'a> Parser<'a> {
         } else {
             let this_token_str = self.this_token_to_string();
             let msg = format!("expected type, found `{}`", this_token_str);
-            self.fatal(msg[]);
+            self.fatal(msg.index(&FullRange));
         };
 
         let sp = mk_sp(lo, self.last_span.hi);
@@ -1726,14 +1728,14 @@ impl<'a> Parser<'a> {
 
                     token::Str_(s) => {
                         (true,
-                         LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str())[]),
+                         LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
                                 ast::CookedStr))
                     }
                     token::StrRaw(s, n) => {
                         (true,
                          LitStr(
                             token::intern_and_get_ident(
-                                parse::raw_str_lit(s.as_str())[]),
+                                parse::raw_str_lit(s.as_str()).index(&FullRange)),
                             ast::RawStr(n)))
                     }
                     token::Binary(i) =>
@@ -1977,7 +1979,7 @@ impl<'a> Parser<'a> {
                 };
             }
             _ => {
-                self.fatal(format!("expected a lifetime name")[]);
+                self.fatal(format!("expected a lifetime name").index(&FullRange));
             }
         }
     }
@@ -2015,7 +2017,7 @@ impl<'a> Parser<'a> {
                     let msg = format!("expected `,` or `>` after lifetime \
                                       name, found `{}`",
                                       this_token_str);
-                    self.fatal(msg[]);
+                    self.fatal(msg.index(&FullRange));
                 }
             }
         }
@@ -2103,22 +2105,6 @@ impl<'a> Parser<'a> {
         ExprIndex(expr, idx)
     }
 
-    pub fn mk_slice(&mut self,
-                    expr: P<Expr>,
-                    start: Option<P<Expr>>,
-                    end: Option<P<Expr>>,
-                    _mutbl: Mutability)
-                    -> ast::Expr_ {
-        // FIXME: we could give more accurate span info here.
-        let (lo, hi) = match (&start, &end) {
-            (&Some(ref s), &Some(ref e)) => (s.span.lo, e.span.hi),
-            (&Some(ref s), &None) => (s.span.lo, s.span.hi),
-            (&None, &Some(ref e)) => (e.span.lo, e.span.hi),
-            (&None, &None) => (DUMMY_SP.lo, DUMMY_SP.hi),
-        };
-        ExprIndex(expr, self.mk_expr(lo, hi, ExprRange(start, end)))
-    }
-
     pub fn mk_range(&mut self,
                     start: Option<P<Expr>>,
                     end: Option<P<Expr>>)
@@ -2515,7 +2501,7 @@ impl<'a> Parser<'a> {
                     let last_span = self.last_span;
                     let fstr = n.as_str();
                     self.span_err(last_span,
-                                  format!("unexpected token: `{}`", n.as_str())[]);
+                                  format!("unexpected token: `{}`", n.as_str()).index(&FullRange));
                     if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
                         let float = match fstr.parse::<f64>() {
                             Some(f) => f,
@@ -2524,7 +2510,7 @@ impl<'a> Parser<'a> {
                         self.span_help(last_span,
                             format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
                                     float.trunc() as uint,
-                                    float.fract().to_string()[1..])[]);
+                                    float.fract().to_string().index(&(1..))).index(&FullRange));
                     }
                     self.abort_if_errors();
 
@@ -2550,87 +2536,44 @@ impl<'a> Parser<'a> {
               }
 
               // expr[...]
-              // Could be either an index expression or a slicing expression.
-              // Any slicing non-terminal can have a mutable version with `mut`
-              // after the opening square bracket.
+              // An index expression.
               token::OpenDelim(token::Bracket) => {
+                let bracket_pos = self.span.lo;
                 self.bump();
-                let mutbl = if self.eat_keyword(keywords::Mut) {
-                    MutMutable
+
+                let mut found_dotdot = false;
+                if self.token == token::DotDot &&
+                   self.look_ahead(1, |t| t == &token::CloseDelim(token::Bracket)) {
+                    // Using expr[..], which is a mistake, should be expr[]
+                    self.bump();
+                    self.bump();
+                    found_dotdot = true;
+                }
+
+                if found_dotdot || self.eat(&token::CloseDelim(token::Bracket)) {
+                    // No expression, expand to a FullRange
+                    // FIXME(#20516) It would be better to use a lang item or
+                    // something for FullRange.
+                    hi = self.last_span.hi;
+                    let range = ExprStruct(ident_to_path(mk_sp(lo, hi),
+                                                         token::special_idents::FullRange),
+                                           vec![],
+                                           None);
+                    let ix = self.mk_expr(bracket_pos, hi, range);
+                    let index = self.mk_index(e, ix);
+                    e = self.mk_expr(lo, hi, index)
                 } else {
-                    MutImmutable
-                };
-                match self.token {
-                    // e[]
-                    token::CloseDelim(token::Bracket) => {
-                        self.bump();
-                        hi = self.span.hi;
-                        let slice = self.mk_slice(e, None, None, mutbl);
-                        e = self.mk_expr(lo, hi, slice)
-                    }
-                    // e[..e]
-                    token::DotDot => {
-                        self.bump();
-                        match self.token {
-                            // e[..]
-                            token::CloseDelim(token::Bracket) => {
-                                self.bump();
-                                hi = self.span.hi;
-                                let slice = self.mk_slice(e, None, None, mutbl);
-                                e = self.mk_expr(lo, hi, slice);
+                    let ix = self.parse_expr();
+                    hi = self.span.hi;
+                    self.commit_expr_expecting(&*ix, token::CloseDelim(token::Bracket));
+                    let index = self.mk_index(e, ix);
+                    e = self.mk_expr(lo, hi, index)
+                }
 
-                                self.span_err(e.span, "incorrect slicing expression: `[..]`");
-                                self.span_note(e.span,
-                                    "use `expr[]` to construct a slice of the whole of expr");
-                            }
-                            // e[..e]
-                            _ => {
-                                hi = self.span.hi;
-                                let e2 = self.parse_expr();
-                                self.commit_expr_expecting(&*e2, token::CloseDelim(token::Bracket));
-                                let slice = self.mk_slice(e, None, Some(e2), mutbl);
-                                e = self.mk_expr(lo, hi, slice)
-                            }
-                        }
-                    }
-                    // e[e] | e[e..] | e[e..e]
-                    _ => {
-                        let ix = self.parse_expr_res(RESTRICTION_NO_DOTS);
-                        match self.token {
-                            // e[e..] | e[e..e]
-                            token::DotDot => {
-                                self.bump();
-                                let e2 = match self.token {
-                                    // e[e..]
-                                    token::CloseDelim(token::Bracket) => {
-                                        self.bump();
-                                        None
-                                    }
-                                    // e[e..e]
-                                    _ => {
-                                        let e2 = self.parse_expr_res(RESTRICTION_NO_DOTS);
-                                        self.commit_expr_expecting(&*e2,
-                                            token::CloseDelim(token::Bracket));
-                                        Some(e2)
-                                    }
-                                };
-                                hi = self.span.hi;
-                                let slice = self.mk_slice(e, Some(ix), e2, mutbl);
-                                e = self.mk_expr(lo, hi, slice)
-                            }
-                            // e[e]
-                            _ => {
-                                if mutbl == ast::MutMutable {
-                                    self.span_err(e.span,
-                                                  "`mut` keyword is invalid in index expressions");
-                                }
-                                hi = self.span.hi;
-                                self.commit_expr_expecting(&*ix, token::CloseDelim(token::Bracket));
-                                let index = self.mk_index(e, ix);
-                                e = self.mk_expr(lo, hi, index)
-                            }
-                        }
-                    }
+                if found_dotdot {
+                    self.span_err(e.span, "incorrect slicing expression: `[..]`");
+                    self.span_note(e.span,
+                                   "use `&expr[]` to construct a slice of the whole of expr");
                 }
               }
 
@@ -2655,6 +2598,70 @@ impl<'a> Parser<'a> {
         return e;
     }
 
+    // Parse unquoted tokens after a `$` in a token tree
+    fn parse_unquoted(&mut self) -> TokenTree {
+        let mut sp = self.span;
+        let (name, namep) = match self.token {
+            token::Dollar => {
+                self.bump();
+
+                if self.token == token::OpenDelim(token::Paren) {
+                    let Spanned { node: seq, span: seq_span } = self.parse_seq(
+                        &token::OpenDelim(token::Paren),
+                        &token::CloseDelim(token::Paren),
+                        seq_sep_none(),
+                        |p| p.parse_token_tree()
+                    );
+                    let (sep, repeat) = self.parse_sep_and_kleene_op();
+                    let name_num = macro_parser::count_names(seq.as_slice());
+                    return TtSequence(mk_sp(sp.lo, seq_span.hi),
+                                      Rc::new(SequenceRepetition {
+                                          tts: seq,
+                                          separator: sep,
+                                          op: repeat,
+                                          num_captures: name_num
+                                      }));
+                } else if self.token.is_keyword_allow_following_colon(keywords::Crate) {
+                    self.bump();
+                    return TtToken(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar));
+                } else {
+                    sp = mk_sp(sp.lo, self.span.hi);
+                    let namep = match self.token { token::Ident(_, p) => p, _ => token::Plain };
+                    let name = self.parse_ident();
+                    (name, namep)
+                }
+            }
+            token::SubstNt(name, namep) => {
+                self.bump();
+                (name, namep)
+            }
+            _ => unreachable!()
+        };
+        // continue by trying to parse the `:ident` after `$name`
+        if self.token == token::Colon && self.look_ahead(1, |t| t.is_ident() &&
+                                                                !t.is_strict_keyword() &&
+                                                                !t.is_reserved_keyword()) {
+            self.bump();
+            sp = mk_sp(sp.lo, self.span.hi);
+            let kindp = match self.token { token::Ident(_, p) => p, _ => token::Plain };
+            let nt_kind = self.parse_ident();
+            TtToken(sp, MatchNt(name, nt_kind, namep, kindp))
+        } else {
+            TtToken(sp, SubstNt(name, namep))
+        }
+    }
+
+    pub fn check_unknown_macro_variable(&mut self) {
+        if self.quote_depth == 0u {
+            match self.token {
+                token::SubstNt(name, _) =>
+                    self.fatal(format!("unknown macro variable `{}`",
+                                       token::get_ident(name)).index(&FullRange)),
+                _ => {}
+            }
+        }
+    }
+
     /// Parse an optional separator followed by a Kleene-style
     /// repetition token (+ or *).
     pub fn parse_sep_and_kleene_op(&mut self) -> (Option<token::Token>, ast::KleeneOp) {
@@ -2701,63 +2708,25 @@ impl<'a> Parser<'a> {
         fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
             maybe_whole!(deref p, NtTT);
             match p.token {
-              token::CloseDelim(_) => {
-                  // This is a conservative error: only report the last unclosed delimiter. The
-                  // previous unclosed delimiters could actually be closed! The parser just hasn't
-                  // gotten to them yet.
-                  match p.open_braces.last() {
-                      None => {}
-                      Some(&sp) => p.span_note(sp, "unclosed delimiter"),
-                  };
-                  let token_str = p.this_token_to_string();
-                  p.fatal(format!("incorrect close delimiter: `{}`",
-                                  token_str)[])
-              },
-              /* we ought to allow different depths of unquotation */
-              token::Dollar if p.quote_depth > 0u => {
-                p.bump();
-                let sp = p.span;
-
-                if p.token == token::OpenDelim(token::Paren) {
-                    let seq = p.parse_seq(
-                        &token::OpenDelim(token::Paren),
-                        &token::CloseDelim(token::Paren),
-                        seq_sep_none(),
-                        |p| p.parse_token_tree()
-                    );
-                    let (sep, repeat) = p.parse_sep_and_kleene_op();
-                    let seq = match seq {
-                        Spanned { node, .. } => node,
+                token::CloseDelim(_) => {
+                    // This is a conservative error: only report the last unclosed delimiter. The
+                    // previous unclosed delimiters could actually be closed! The parser just hasn't
+                    // gotten to them yet.
+                    match p.open_braces.last() {
+                        None => {}
+                        Some(&sp) => p.span_note(sp, "unclosed delimiter"),
                     };
-                    let name_num = macro_parser::count_names(seq[]);
-                    TtSequence(mk_sp(sp.lo, p.span.hi),
-                               Rc::new(SequenceRepetition {
-                                   tts: seq,
-                                   separator: sep,
-                                   op: repeat,
-                                   num_captures: name_num
-                               }))
-                } else if p.token.is_keyword_allow_following_colon(keywords::Crate) {
-                    p.bump();
-                    TtToken(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))
-                } else {
-                    // A nonterminal that matches or not
-                    let namep = match p.token { token::Ident(_, p) => p, _ => token::Plain };
-                    let name = p.parse_ident();
-                    if p.token == token::Colon && p.look_ahead(1, |t| t.is_ident()) {
-                        p.bump();
-                        let kindp = match p.token { token::Ident(_, p) => p, _ => token::Plain };
-                        let nt_kind = p.parse_ident();
-                        let m = TtToken(sp, MatchNt(name, nt_kind, namep, kindp));
-                        m
-                    } else {
-                        TtToken(sp, SubstNt(name, namep))
-                    }
+                    let token_str = p.this_token_to_string();
+                    p.fatal(format!("incorrect close delimiter: `{}`",
+                                    token_str).index(&FullRange))
+                },
+                /* we ought to allow different depths of unquotation */
+                token::Dollar | token::SubstNt(..) if p.quote_depth > 0u => {
+                    p.parse_unquoted()
+                }
+                _ => {
+                    TtToken(p.span, p.bump_and_get())
                 }
-              }
-              _ => {
-                  TtToken(p.span, p.bump_and_get())
-              }
             }
         }
 
@@ -2890,7 +2859,7 @@ impl<'a> Parser<'a> {
                         let this_token_to_string = self.this_token_to_string();
                         self.span_err(span,
                                       format!("expected expression, found `{}`",
-                                              this_token_to_string)[]);
+                                              this_token_to_string).index(&FullRange));
                         let box_span = mk_sp(lo, self.last_span.hi);
                         self.span_help(box_span,
                                        "perhaps you meant `box() (foo)` instead?");
@@ -3273,7 +3242,7 @@ impl<'a> Parser<'a> {
                 if self.token != token::CloseDelim(token::Brace) {
                     let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `{}`, found `{}`", "}",
-                                       token_str)[])
+                                       token_str).index(&FullRange))
                 }
                 etc = true;
                 break;
@@ -3294,7 +3263,7 @@ impl<'a> Parser<'a> {
                     BindByRef(..) | BindByValue(MutMutable) => {
                         let token_str = self.this_token_to_string();
                         self.fatal(format!("unexpected `{}`",
-                                           token_str)[])
+                                           token_str).index(&FullRange))
                     }
                     _ => {}
                 }
@@ -3577,7 +3546,7 @@ impl<'a> Parser<'a> {
             let span = self.span;
             let tok_str = self.this_token_to_string();
             self.span_fatal(span,
-                            format!("expected identifier, found `{}`", tok_str)[]);
+                            format!("expected identifier, found `{}`", tok_str).index(&FullRange));
         }
         let ident = self.parse_ident();
         let last_span = self.last_span;
@@ -3674,7 +3643,7 @@ impl<'a> Parser<'a> {
 
         let lo = self.span.lo;
         if self.token.is_keyword(keywords::Let) {
-            check_expected_item(self, item_attrs[]);
+            check_expected_item(self, item_attrs.index(&FullRange));
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
             P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
@@ -3683,7 +3652,7 @@ impl<'a> Parser<'a> {
             && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
-            check_expected_item(self, item_attrs[]);
+            check_expected_item(self, item_attrs.index(&FullRange));
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -3711,7 +3680,7 @@ impl<'a> Parser<'a> {
                     let tok_str = self.this_token_to_string();
                     self.fatal(format!("expected {}`(` or `{{`, found `{}`",
                                        ident_str,
-                                       tok_str)[])
+                                       tok_str).index(&FullRange))
                 },
             };
 
@@ -3759,7 +3728,7 @@ impl<'a> Parser<'a> {
             }
         } else {
             let found_attrs = !item_attrs.is_empty();
-            let item_err = Parser::expected_item_err(item_attrs[]);
+            let item_err = Parser::expected_item_err(item_attrs.index(&FullRange));
             match self.parse_item_or_view_item(item_attrs, false) {
                 IoviItem(i) => {
                     let hi = i.span.hi;
@@ -3803,7 +3772,7 @@ impl<'a> Parser<'a> {
             let sp = self.span;
             let tok = self.this_token_to_string();
             self.span_fatal_help(sp,
-                                 format!("expected `{{`, found `{}`", tok)[],
+                                 format!("expected `{{`, found `{}`", tok).index(&FullRange),
                                  "place this code inside a block");
         }
 
@@ -3857,13 +3826,13 @@ impl<'a> Parser<'a> {
         while self.token != token::CloseDelim(token::Brace) {
             // parsing items even when they're not allowed lets us give
             // better error messages and recover more gracefully.
-            attributes_box.push_all(self.parse_outer_attributes()[]);
+            attributes_box.push_all(self.parse_outer_attributes().index(&FullRange));
             match self.token {
                 token::Semi => {
                     if !attributes_box.is_empty() {
                         let last_span = self.last_span;
                         self.span_err(last_span,
-                                      Parser::expected_item_err(attributes_box[]));
+                                      Parser::expected_item_err(attributes_box.index(&FullRange)));
                         attributes_box = Vec::new();
                     }
                     self.bump(); // empty
@@ -3955,7 +3924,7 @@ impl<'a> Parser<'a> {
         if !attributes_box.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(attributes_box[]));
+                          Parser::expected_item_err(attributes_box.index(&FullRange)));
         }
 
         let hi = self.span.hi;
@@ -4399,7 +4368,7 @@ impl<'a> Parser<'a> {
             _ => {
                 let token_str = self.this_token_to_string();
                 self.fatal(format!("expected `self`, found `{}`",
-                                   token_str)[])
+                                   token_str).index(&FullRange))
             }
         }
     }
@@ -4553,7 +4522,7 @@ impl<'a> Parser<'a> {
                 _ => {
                     let token_str = self.this_token_to_string();
                     self.fatal(format!("expected `,` or `)`, found `{}`",
-                                       token_str)[])
+                                       token_str).index(&FullRange))
                 }
             }
             }
@@ -4729,7 +4698,7 @@ impl<'a> Parser<'a> {
                 let (inner_attrs, body) = self.parse_inner_attrs_and_block();
                 let body_span = body.span;
                 let mut new_attrs = attrs;
-                new_attrs.push_all(inner_attrs[]);
+                new_attrs.push_all(inner_attrs.index(&FullRange));
                 (ast::MethDecl(ident,
                                generics,
                                abi,
@@ -4948,7 +4917,7 @@ impl<'a> Parser<'a> {
             if fields.len() == 0 {
                 self.fatal(format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())).index(&FullRange));
             }
 
             self.bump();
@@ -4956,7 +4925,7 @@ impl<'a> Parser<'a> {
             let token_str = self.this_token_to_string();
             self.fatal(format!("expected `where`, or `{}` after struct \
                                 name, found `{}`", "{",
-                                token_str)[]);
+                                token_str).index(&FullRange));
         }
 
         fields
@@ -4987,7 +4956,7 @@ impl<'a> Parser<'a> {
             if fields.len() == 0 {
                 self.fatal(format!("unit-like struct definition should be \
                     written as `struct {};`",
-                    token::get_ident(class_name.clone()))[]);
+                    token::get_ident(class_name.clone())).index(&FullRange));
             }
 
             self.parse_where_clause(generics);
@@ -5002,7 +4971,7 @@ impl<'a> Parser<'a> {
         } else {
             let token_str = self.this_token_to_string();
             self.fatal(format!("expected `where`, `{}`, `(`, or `;` after struct \
-                name, found `{}`", "{", token_str)[]);
+                name, found `{}`", "{", token_str).index(&FullRange));
         }
     }
 
@@ -5022,7 +4991,7 @@ impl<'a> Parser<'a> {
                 let token_str = self.this_token_to_string();
                 self.span_fatal_help(span,
                                      format!("expected `,`, or `}}`, found `{}`",
-                                             token_str)[],
+                                             token_str).index(&FullRange),
                                      "struct fields should be separated by commas")
             }
         }
@@ -5109,11 +5078,11 @@ impl<'a> Parser<'a> {
             let mut attrs = self.parse_outer_attributes();
             if first {
                 let mut tmp = attrs_remaining.clone();
-                tmp.push_all(attrs[]);
+                tmp.push_all(attrs.index(&FullRange));
                 attrs = tmp;
                 first = false;
             }
-            debug!("parse_mod_items: parse_item_or_view_item(attrs={})",
+            debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
                    attrs);
             match self.parse_item_or_view_item(attrs,
                                                true /* macros allowed */) {
@@ -5126,7 +5095,7 @@ impl<'a> Parser<'a> {
               _ => {
                   let token_str = self.this_token_to_string();
                   self.fatal(format!("expected item, found `{}`",
-                                     token_str)[])
+                                     token_str).index(&FullRange))
               }
             }
         }
@@ -5135,7 +5104,7 @@ impl<'a> Parser<'a> {
             // We parsed attributes for the first item but didn't find it
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(attrs_remaining[]));
+                          Parser::expected_item_err(attrs_remaining.index(&FullRange)));
         }
 
         ast::Mod {
@@ -5205,7 +5174,7 @@ impl<'a> Parser<'a> {
                     -> (ast::Item_, Vec<ast::Attribute> ) {
         let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
         prefix.pop();
-        let mod_path = Path::new(".").join_many(self.mod_path_stack[]);
+        let mod_path = Path::new(".").join_many(self.mod_path_stack.index(&FullRange));
         let dir_path = prefix.join(&mod_path);
         let mod_string = token::get_ident(id);
         let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
@@ -5215,8 +5184,8 @@ impl<'a> Parser<'a> {
                 let mod_name = mod_string.get().to_string();
                 let default_path_str = format!("{}.rs", mod_name);
                 let secondary_path_str = format!("{}/mod.rs", mod_name);
-                let default_path = dir_path.join(default_path_str[]);
-                let secondary_path = dir_path.join(secondary_path_str[]);
+                let default_path = dir_path.join(default_path_str.index(&FullRange));
+                let secondary_path = dir_path.join(secondary_path_str.index(&FullRange));
                 let default_exists = default_path.exists();
                 let secondary_exists = secondary_path.exists();
 
@@ -5231,13 +5200,13 @@ impl<'a> Parser<'a> {
                                    format!("maybe move this module `{0}` \
                                             to its own directory via \
                                             `{0}/mod.rs`",
-                                           this_module)[]);
+                                           this_module).index(&FullRange));
                     if default_exists || secondary_exists {
                         self.span_note(id_sp,
                                        format!("... or maybe `use` the module \
                                                 `{}` instead of possibly \
                                                 redeclaring it",
-                                               mod_name)[]);
+                                               mod_name).index(&FullRange));
                     }
                     self.abort_if_errors();
                 }
@@ -5248,12 +5217,12 @@ impl<'a> Parser<'a> {
                     (false, false) => {
                         self.span_fatal_help(id_sp,
                                              format!("file not found for module `{}`",
-                                                     mod_name)[],
+                                                     mod_name).index(&FullRange),
                                              format!("name the file either {} or {} inside \
-                                                     the directory {}",
+                                                     the directory {:?}",
                                                      default_path_str,
                                                      secondary_path_str,
-                                                     dir_path.display())[]);
+                                                     dir_path.display()).index(&FullRange));
                     }
                     (true, true) => {
                         self.span_fatal_help(
@@ -5262,7 +5231,7 @@ impl<'a> Parser<'a> {
                                      and {}",
                                     mod_name,
                                     default_path_str,
-                                    secondary_path_str)[],
+                                    secondary_path_str).index(&FullRange),
                             "delete or rename one of them to remove the ambiguity");
                     }
                 }
@@ -5284,11 +5253,11 @@ impl<'a> Parser<'a> {
                 let mut err = String::from_str("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in included_mod_stack.slice(i, len).iter() {
-                    err.push_str(p.display().as_cow()[]);
+                    err.push_str(p.display().as_cow().index(&FullRange));
                     err.push_str(" -> ");
                 }
-                err.push_str(path.display().as_cow()[]);
-                self.span_fatal(id_sp, err[]);
+                err.push_str(path.display().as_cow().index(&FullRange));
+                self.span_fatal(id_sp, err.index(&FullRange));
             }
             None => ()
         }
@@ -5369,7 +5338,7 @@ impl<'a> Parser<'a> {
         if !attrs_remaining.is_empty() {
             let last_span = self.last_span;
             self.span_err(last_span,
-                          Parser::expected_item_err(attrs_remaining[]));
+                          Parser::expected_item_err(attrs_remaining.index(&FullRange)));
         }
         assert!(self.token == token::CloseDelim(token::Brace));
         ast::ForeignMod {
@@ -5410,7 +5379,7 @@ impl<'a> Parser<'a> {
                     self.span_help(span,
                                    format!("perhaps you meant to enclose the crate name `{}` in \
                                            a string?",
-                                          the_ident.as_str())[]);
+                                          the_ident.as_str()).index(&FullRange));
                     None
                 } else {
                     None
@@ -5436,7 +5405,7 @@ impl<'a> Parser<'a> {
                 self.span_fatal(span,
                                 format!("expected extern crate name but \
                                          found `{}`",
-                                        token_str)[]);
+                                        token_str).index(&FullRange));
             }
         };
 
@@ -5534,7 +5503,7 @@ impl<'a> Parser<'a> {
                     self.span_err(start_span,
                         format!("unit-like struct variant should be written \
                                  without braces, as `{},`",
-                                token::get_ident(ident))[]);
+                                token::get_ident(ident)).index(&FullRange));
                 }
                 kind = StructVariantKind(struct_def);
             } else if self.check(&token::OpenDelim(token::Paren)) {
@@ -5619,7 +5588,7 @@ impl<'a> Parser<'a> {
                             format!("illegal ABI: expected one of [{}], \
                                      found `{}`",
                                     abi::all_names().connect(", "),
-                                    the_string)[]);
+                                    the_string).index(&FullRange));
                         None
                     }
                 }
@@ -5681,7 +5650,7 @@ impl<'a> Parser<'a> {
                                  format!("`extern mod` is obsolete, use \
                                           `extern crate` instead \
                                           to refer to external \
-                                          crates.")[])
+                                          crates.").index(&FullRange))
                 }
                 return self.parse_item_extern_crate(lo, visibility, attrs);
             }
@@ -5709,7 +5678,7 @@ impl<'a> Parser<'a> {
             let token_str = self.this_token_to_string();
             self.span_fatal(span,
                             format!("expected `{}` or `fn`, found `{}`", "{",
-                                    token_str)[]);
+                                    token_str).index(&FullRange));
         }
 
         if self.eat_keyword(keywords::Virtual) {
@@ -5822,7 +5791,7 @@ impl<'a> Parser<'a> {
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
             let (ident, item_, extra_attrs) =
-                self.parse_item_mod(attrs[]);
+                self.parse_item_mod(attrs.index(&FullRange));
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
@@ -6162,7 +6131,7 @@ impl<'a> Parser<'a> {
                                   macros_allowed: bool)
                                   -> ParsedItemsAndViewItems {
         let mut attrs = first_item_attrs;
-        attrs.push_all(self.parse_outer_attributes()[]);
+        attrs.push_all(self.parse_outer_attributes().index(&FullRange));
         // First, parse view items.
         let mut view_items : Vec<ast::ViewItem> = Vec::new();
         let mut items = Vec::new();
@@ -6244,7 +6213,7 @@ impl<'a> Parser<'a> {
                            macros_allowed: bool)
         -> ParsedItemsAndViewItems {
         let mut attrs = first_item_attrs;
-        attrs.push_all(self.parse_outer_attributes()[]);
+        attrs.push_all(self.parse_outer_attributes().index(&FullRange));
         let mut foreign_items = Vec::new();
         loop {
             match self.parse_foreign_item(attrs, macros_allowed) {