diff options
| author | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-20 03:11:12 +0000 |
| commit | aef6c4b1382dcf2f943bd5872656625f935c0b7c (patch) | |
| tree | 95920a7c62cbc07301ec8fe4b189b33e208327cd /src/libsyntax | |
| parent | 3b6e880fffb8e09b15bc6fc41d5b23f21bf5056d (diff) | |
| parent | f082416bece7cbb16ec46f870fb7f91ca15f2231 (diff) | |
auto merge of #17399 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/codemap.rs | 45 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/plugin.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 108 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 33 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 33 | ||||
| -rw-r--r-- | src/libsyntax/ext/source_util.rs | 46 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 30 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 183 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 83 | ||||
| -rw-r--r-- | src/libsyntax/print/pp.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 73 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 5 |
19 files changed, 432 insertions, 296 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index eac158e664c..5c84745c20c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -213,13 +213,20 @@ pub static DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - UnboxedFnTyParamBound(UnboxedFnTy), + UnboxedFnTyParamBound(P<UnboxedFnBound>), RegionTyParamBound(Lifetime) } pub type TyParamBounds = OwnedSlice<TyParamBound>; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct UnboxedFnBound { + pub path: Path, + pub decl: P<FnDecl>, + pub ref_id: NodeId, +} + +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TyParam { pub ident: Ident, pub id: NodeId, @@ -531,6 +538,7 @@ pub enum Expr_ { ExprField(P<Expr>, SpannedIdent, Vec<P<Ty>>), ExprTupField(P<Expr>, Spanned<uint>, Vec<P<Ty>>), ExprIndex(P<Expr>, P<Expr>), + ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability), /// Variable reference, possibly containing `::` and/or /// type parameters, e.g. foo::bar::<baz> @@ -1363,7 +1371,7 @@ mod test { inner: Span { lo: BytePos(11), hi: BytePos(19), - expn_info: None, + expn_id: NO_EXPANSION, }, view_items: Vec::new(), items: Vec::new(), @@ -1373,7 +1381,7 @@ mod test { span: Span { lo: BytePos(10), hi: BytePos(20), - expn_info: None, + expn_id: NO_EXPANSION, }, exported_macros: Vec::new(), }; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 2f30108c27b..9072889463c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -25,7 +25,6 @@ source code snippets, etc. use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::cell::RefCell; -use std::gc::Gc; use std::rc::Rc; pub trait Pos { @@ -93,10 +92,10 @@ pub struct Span { pub hi: BytePos, /// Information about where the macro came from, if this piece of /// code was created by a macro expansion. - pub expn_info: Option<Gc<ExpnInfo>> + pub expn_id: ExpnId } -pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None }; +pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION }; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct Spanned<T> { @@ -140,17 +139,19 @@ pub fn dummy_spanned<T>(t: T) -> Spanned<T> { /* assuming that we're not in macro expansion */ pub fn mk_sp(lo: BytePos, hi: BytePos) -> Span { - Span {lo: lo, hi: hi, expn_info: None} + Span {lo: lo, hi: hi, expn_id: NO_EXPANSION} } /// Return the span itself if it doesn't come from a macro expansion, /// otherwise return the call site span up to the `enclosing_sp` by /// following the `expn_info` chain. -pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span { - match (sp.expn_info, enclosing_sp.expn_info) { +pub fn original_sp(cm: &CodeMap, sp: Span, enclosing_sp: Span) -> Span { + let call_site1 = cm.with_expn_info(sp.expn_id, |ei| ei.map(|ei| ei.call_site)); + let call_site2 = cm.with_expn_info(enclosing_sp.expn_id, |ei| ei.map(|ei| ei.call_site)); + match (call_site1, call_site2) { (None, _) => sp, - (Some(expn1), Some(expn2)) if expn1.call_site == expn2.call_site => sp, - (Some(expn1), _) => original_sp(expn1.call_site, enclosing_sp), + (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp, + (Some(call_site1), _) => original_sp(cm, call_site1, enclosing_sp), } } @@ -222,6 +223,11 @@ pub struct ExpnInfo { pub callee: NameAndSpan } +#[deriving(PartialEq, Eq, Clone, Show, Hash)] +pub struct ExpnId(u32); + +pub static NO_EXPANSION: ExpnId = ExpnId(-1); + pub type FileName = String; pub struct FileLines { @@ -299,13 +305,15 @@ impl FileMap { } pub struct CodeMap { - pub files: RefCell<Vec<Rc<FileMap>>> + pub files: RefCell<Vec<Rc<FileMap>>>, + expansions: RefCell<Vec<ExpnInfo>> } impl CodeMap { pub fn new() -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), + expansions: RefCell::new(Vec::new()), } } @@ -527,6 +535,19 @@ impl CodeMap { col: chpos - linechpos } } + + pub fn record_expansion(&self, expn_info: ExpnInfo) -> ExpnId { + let mut expansions = self.expansions.borrow_mut(); + expansions.push(expn_info); + ExpnId(expansions.len().to_u32().expect("too many ExpnInfo's!") - 1) + } + + pub fn with_expn_info<T>(&self, id: ExpnId, f: |Option<&ExpnInfo>| -> T) -> T { + match id { + NO_EXPANSION => f(None), + ExpnId(i) => f(Some(&(*self.expansions.borrow())[i as uint])) + } + } } #[cfg(test)] @@ -665,7 +686,7 @@ mod test { fn t7() { // Test span_to_lines for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let file_lines = cm.span_to_lines(span); assert_eq!(file_lines.file.name, "blork.rs".to_string()); @@ -677,7 +698,7 @@ mod test { fn t8() { // Test span_to_snippet for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let snippet = cm.span_to_snippet(span); assert_eq!(snippet, Some("second line".to_string())); @@ -687,7 +708,7 @@ mod test { fn t9() { // Test span_to_str for a span ending at the end of filemap let cm = init_code_map(); - let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None}; + let span = Span {lo: BytePos(12), hi: BytePos(23), expn_id: NO_EXPANSION}; let sstr = cm.span_to_string(span); assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string()); diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index faa3946b74d..f33c768d647 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -389,7 +389,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, // we want to tell compiletest/runtest to look at the last line of the // span (since `custom_highlight_lines` displays an arrow to the end of // the span) - let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info}; + let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id}; let ses = cm.span_to_string(span_end); try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code)); if rsp.is_full_span() { @@ -523,24 +523,24 @@ fn print_macro_backtrace(w: &mut EmitterWriter, cm: &codemap::CodeMap, sp: Span) -> io::IoResult<()> { - for ei in sp.expn_info.iter() { - let ss = ei.callee - .span - .as_ref() - .map_or("".to_string(), |span| cm.span_to_string(*span)); - let (pre, post) = match ei.callee.format { - codemap::MacroAttribute => ("#[", "]"), - codemap::MacroBang => ("", "!") - }; - try!(print_diagnostic(w, ss.as_slice(), Note, - format!("in expansion of {}{}{}", pre, - ei.callee.name, - post).as_slice(), None)); - let ss = cm.span_to_string(ei.call_site); - try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None)); - try!(print_macro_backtrace(w, cm, ei.call_site)); - } - Ok(()) + let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| match expn_info { + Some(ei) => { + let ss = ei.callee.span.map_or(String::new(), |span| cm.span_to_string(span)); + let (pre, post) = match ei.callee.format { + codemap::MacroAttribute => ("#[", "]"), + codemap::MacroBang => ("", "!") + }; + try!(print_diagnostic(w, ss.as_slice(), Note, + format!("in expansion of {}{}{}", pre, + ei.callee.name, + post).as_slice(), None)); + let ss = cm.span_to_string(ei.call_site); + try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None)); + Ok(Some(ei.call_site)) + } + None => Ok(None) + })); + cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site)) } pub fn expect<T>(diag: &SpanHandler, opt: Option<T>, msg: || -> String) -> T { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 132b59c89b2..d3c39284f55 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use ast; use ast::{Ident, Name, TokenTree}; use codemap::Span; -use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult}; +use ext::base::{ExtCtxt, MacExpr, MacResult, MacItems}; use ext::build::AstBuilder; use parse::token; use ptr::P; @@ -102,7 +102,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, let sym = Ident::new(token::gensym(( "__register_diagnostic_".to_string() + token::get_ident(*code).get() ).as_slice())); - MacItem::new(quote_item!(ecx, mod $sym {}).unwrap()) + MacItems::new(vec![quote_item!(ecx, mod $sym {}).unwrap()].into_iter()) } pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, @@ -133,7 +133,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, (descriptions.len(), ecx.expr_vec(span, descriptions)) }) }); - MacItem::new(quote_item!(ecx, + MacItems::new(vec![quote_item!(ecx, pub static $name: [(&'static str, &'static str), ..$count] = $expr; - ).unwrap()) + ).unwrap()].into_iter()) } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 773daa4a4c5..b35a9456757 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -11,7 +11,7 @@ use ast; use ast::Name; use codemap; -use codemap::{CodeMap, Span, ExpnInfo}; +use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION}; use ext; use ext::expand; use parse; @@ -24,7 +24,6 @@ use ext::mtwt; use fold::Folder; use std::collections::HashMap; -use std::gc::{Gc, GC}; use std::rc::Rc; // new-style macro! tt code: @@ -203,25 +202,20 @@ impl MacResult for MacPat { Some(self.p) } } -/// A convenience type for macros that return a single item. -pub struct MacItem { - i: P<ast::Item> +/// A type for macros that return multiple items. +pub struct MacItems { + items: SmallVector<P<ast::Item>> } -impl MacItem { - pub fn new(i: P<ast::Item>) -> Box<MacResult+'static> { - box MacItem { i: i } as Box<MacResult+'static> + +impl MacItems { + pub fn new<I: Iterator<P<ast::Item>>>(mut it: I) -> Box<MacResult+'static> { + box MacItems { items: it.collect() } as Box<MacResult+'static> } } -impl MacResult for MacItem { - fn make_items(self: Box<MacItem>) -> Option<SmallVector<P<ast::Item>>> { - Some(SmallVector::one(self.i)) - } - fn make_stmt(self: Box<MacItem>) -> Option<P<ast::Stmt>> { - Some(P(codemap::respan( - self.i.span, - ast::StmtDecl( - P(codemap::respan(self.i.span, ast::DeclItem(self.i))), - ast::DUMMY_NODE_ID)))) + +impl MacResult for MacItems { + fn make_items(self: Box<MacItems>) -> Option<SmallVector<P<ast::Item>>> { + Some(self.items) } } @@ -305,11 +299,11 @@ pub enum SyntaxExtension { /// based upon it. /// /// `#[deriving(...)]` is an `ItemDecorator`. - ItemDecorator(Box<ItemDecorator + 'static>), + Decorator(Box<ItemDecorator + 'static>), /// A syntax extension that is attached to an item and modifies it /// in-place. - ItemModifier(Box<ItemModifier + 'static>), + Modifier(Box<ItemModifier + 'static>), /// A normal, function-like syntax extension. /// @@ -387,7 +381,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { builtin_normal_expander( ext::log_syntax::expand_syntax_ext)); syntax_expanders.insert(intern("deriving"), - ItemDecorator(box ext::deriving::expand_meta_deriving)); + Decorator(box ext::deriving::expand_meta_deriving)); // Quasi-quoting expanders syntax_expanders.insert(intern("quote_tokens"), @@ -457,7 +451,7 @@ fn initial_syntax_expander_table() -> SyntaxEnv { pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, - pub backtrace: Option<Gc<ExpnInfo>>, + pub backtrace: ExpnId, pub ecfg: expand::ExpansionConfig, pub mod_path: Vec<ast::Ident> , @@ -473,7 +467,7 @@ impl<'a> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, - backtrace: None, + backtrace: NO_EXPANSION, mod_path: Vec::new(), ecfg: ecfg, trace_mac: false, @@ -501,13 +495,49 @@ impl<'a> ExtCtxt<'a> { pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() } pub fn call_site(&self) -> Span { - match self.backtrace { + self.codemap().with_expn_info(self.backtrace, |ei| match ei { Some(expn_info) => expn_info.call_site, None => self.bug("missing top span") - } + }) } pub fn print_backtrace(&self) { } - pub fn backtrace(&self) -> Option<Gc<ExpnInfo>> { self.backtrace } + pub fn backtrace(&self) -> ExpnId { self.backtrace } + pub fn original_span(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + match self.codemap().with_expn_info(expn_id, |ei| ei.map(|ei| ei.call_site)) { + None => break, + Some(cs) => { + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn original_span_in_file(&self) -> Span { + let mut expn_id = self.backtrace; + let mut call_site = None; + loop { + let expn_info = self.codemap().with_expn_info(expn_id, |ei| { + ei.map(|ei| (ei.call_site, ei.callee.name.as_slice() == "include")) + }); + match expn_info { + None => break, + Some((cs, is_include)) => { + if is_include { + // Don't recurse into file using "include!". + break; + } + call_site = Some(cs); + expn_id = cs.expn_id; + } + } + } + call_site.expect("missing expansion backtrace") + } + pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); } pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); } pub fn mod_path(&self) -> Vec<ast::Ident> { @@ -516,22 +546,22 @@ impl<'a> ExtCtxt<'a> { v.extend(self.mod_path.iter().map(|a| *a)); return v; } - pub fn bt_push(&mut self, ei: codemap::ExpnInfo) { - match ei { - ExpnInfo {call_site: cs, callee: ref callee} => { - self.backtrace = - Some(box(GC) ExpnInfo { - call_site: Span {lo: cs.lo, hi: cs.hi, - expn_info: self.backtrace.clone()}, - callee: (*callee).clone() - }); - } - } + pub fn bt_push(&mut self, ei: ExpnInfo) { + let mut call_site = ei.call_site; + call_site.expn_id = self.backtrace; + self.backtrace = self.codemap().record_expansion(ExpnInfo { + call_site: call_site, + callee: ei.callee + }); } pub fn bt_pop(&mut self) { match self.backtrace { - Some(expn_info) => self.backtrace = expn_info.call_site.expn_info, - _ => self.bug("tried to pop without a push") + NO_EXPANSION => self.bug("tried to pop without a push"), + expn_id => { + self.backtrace = self.codemap().with_expn_info(expn_id, |expn_info| { + expn_info.map_or(NO_EXPANSION, |ei| ei.call_site.expn_id) + }); + } } } /// Emit `msg` attached to `sp`, and stop compilation immediately. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 7b2613d4e8b..16ecd83180e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -573,7 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(field_name.get().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: ident, span: field_span }; @@ -583,7 +583,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let field_span = Span { lo: sp.lo - Pos::from_uint(idx.to_string().len()), hi: sp.hi, - expn_info: sp.expn_info, + expn_id: sp.expn_id, }; let id = Spanned { node: idx, span: field_span }; diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index ff249495bd7..142adc9b721 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -181,7 +181,6 @@ //! ~~~ use std::cell::RefCell; -use std::gc::GC; use std::vec; use abi::Abi; @@ -1169,7 +1168,7 @@ impl<'a> TraitDef<'a> { None => cx.span_bug(self.span, "trait with empty path in generic `deriving`"), Some(name) => *name }; - to_set.expn_info = Some(box(GC) codemap::ExpnInfo { + to_set.expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: to_set, callee: codemap::NameAndSpan { name: format!("deriving({})", trait_name), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4ff9912645a..e173b93e468 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -30,8 +30,6 @@ use util::small_vector::SmallVector; use visit; use visit::Visitor; -use std::gc::Gc; - enum Either<L,R> { Left(L), Right(R) @@ -161,11 +159,11 @@ fn expand_mac_invoc<T>(mac: ast::Mac, span: codemap::Span, // be the root of the call stack. That's the most // relevant span and it's the actual invocation of // the macro. - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let opt_parsed = { let expanded = expandfun.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()); parse_thunk(expanded) }; @@ -254,7 +252,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemDecorator(ref dec) => { + Decorator(ref dec) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { @@ -311,7 +309,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) // partition the attributes into ItemModifiers and others let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { match fld.cx.syntax_env.find(&intern(attr.name().get())) { - Some(rc) => match *rc { ItemModifier(_) => true, _ => false }, + Some(rc) => match *rc { Modifier(_) => true, _ => false }, _ => false } }); @@ -330,7 +328,7 @@ fn expand_item_modifiers(mut it: P<ast::Item>, fld: &mut MacroExpander) match fld.cx.syntax_env.find(&intern(mname.get())) { Some(rc) => match *rc { - ItemModifier(ref mac) => { + Modifier(ref mac) => { attr::mark_used(attr); fld.cx.bt_push(ExpnInfo { call_site: attr.span, @@ -759,9 +757,9 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> { let fm = fresh_mark(); let marked_before = mark_tts(tts.as_slice(), fm); - let mac_span = original_span(fld.cx); + let mac_span = fld.cx.original_span(); let expanded = match expander.expand(fld.cx, - mac_span.call_site, + mac_span, marked_before.as_slice()).make_pat() { Some(e) => e, None => { @@ -969,7 +967,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span { Span { lo: sp.lo, hi: sp.hi, - expn_info: cx.backtrace(), + expn_id: cx.backtrace(), } } @@ -1083,21 +1081,6 @@ fn mark_method(expr: P<ast::Method>, m: Mrk) -> P<ast::Method> { .expect_one("marking an item didn't return exactly one method") } -fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> { - let mut relevant_info = cx.backtrace(); - let mut einfo = relevant_info.unwrap(); - loop { - match relevant_info { - None => { break } - Some(e) => { - einfo = e; - relevant_info = einfo.call_site.expn_info; - } - } - } - return einfo; -} - /// Check that there are no macro invocations left in the AST: pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) { visit::walk_crate(&mut MacroExterminator{sess:sess}, krate); diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 26586684309..b760c893a10 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -19,17 +19,18 @@ use parse::token; use ptr::P; use std::collections::HashMap; +use std::string; #[deriving(PartialEq)] enum ArgumentType { - Known(String), + Known(string::String), Unsigned, String, } enum Position { Exact(uint), - Named(String), + Named(string::String), } struct Context<'a, 'b:'a> { @@ -44,12 +45,12 @@ struct Context<'a, 'b:'a> { /// Note that we keep a side-array of the ordering of the named arguments /// found to be sure that we can translate them in the same order that they /// were declared in. - names: HashMap<String, P<ast::Expr>>, - name_types: HashMap<String, ArgumentType>, - name_ordering: Vec<String>, + names: HashMap<string::String, P<ast::Expr>>, + name_types: HashMap<string::String, ArgumentType>, + name_ordering: Vec<string::String>, /// The latest consecutive literal strings, or empty if there weren't any. - literal: String, + literal: string::String, /// Collection of the compiled `rt::Argument` structures pieces: Vec<P<ast::Expr>>, @@ -58,7 +59,7 @@ struct Context<'a, 'b:'a> { /// Stays `true` if all formatting parameters are default (as in "{}{}"). all_pieces_simple: bool, - name_positions: HashMap<String, uint>, + name_positions: HashMap<string::String, uint>, method_statics: Vec<P<ast::Item>>, /// Updated as arguments are consumed or methods are entered @@ -81,10 +82,10 @@ pub enum Invocation { /// named arguments)) fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, tts: &[ast::TokenTree]) - -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<String>, - HashMap<String, P<ast::Expr>>)>) { + -> (Invocation, Option<(P<ast::Expr>, Vec<P<ast::Expr>>, Vec<string::String>, + HashMap<string::String, P<ast::Expr>>)>) { let mut args = Vec::new(); - let mut names = HashMap::<String, P<ast::Expr>>::new(); + let mut names = HashMap::<string::String, P<ast::Expr>>::new(); let mut order = Vec::new(); let mut p = ecx.new_parser_from_tts(tts); @@ -167,7 +168,7 @@ impl<'a, 'b> Context<'a, 'b> { fn verify_piece(&mut self, p: &parse::Piece) { match *p { parse::String(..) => {} - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // width/precision first, if they have implicit positional // parameters it makes more sense to consume them first. self.verify_count(arg.format.width); @@ -222,7 +223,7 @@ impl<'a, 'b> Context<'a, 'b> { } } - fn describe_num_args(&self) -> String { + fn describe_num_args(&self) -> string::String { match self.args.len() { 0 => "no arguments given".to_string(), 1 => "there is 1 argument".to_string(), @@ -391,7 +392,7 @@ impl<'a, 'b> Context<'a, 'b> { self.literal.push_str(s); None } - parse::Argument(ref arg) => { + parse::NextArgument(ref arg) => { // Translate the position let pos = match arg.position { // These two have a direct mapping @@ -747,8 +748,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, invocation: Invocation, efmt: P<ast::Expr>, args: Vec<P<ast::Expr>>, - name_ordering: Vec<String>, - names: HashMap<String, P<ast::Expr>>) + name_ordering: Vec<string::String>, + names: HashMap<string::String, P<ast::Expr>>) -> P<ast::Expr> { let arg_types = Vec::from_fn(args.len(), |_| None); let mut cx = Context { @@ -761,7 +762,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, name_ordering: name_ordering, nest_level: 0, next_arg: 0, - literal: String::new(), + literal: string::String::new(), pieces: Vec::new(), str_pieces: Vec::new(), all_pieces_simple: true, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 5cc0ec4a122..41967b0680c 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -11,7 +11,6 @@ use ast; use codemap; use codemap::{Pos, Span}; -use codemap::{ExpnInfo, NameAndSpan}; use ext::base::*; use ext::base; use ext::build::AstBuilder; @@ -19,7 +18,6 @@ use parse; use parse::token; use print::pprust; -use std::gc::Gc; use std::io::File; use std::rc::Rc; @@ -32,10 +30,10 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.line)) + base::MacExpr::new(cx.expr_uint(topmost, loc.line)) } /* col!(): expands to the current column number */ @@ -43,9 +41,9 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "col!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); - base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint())) + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); + base::MacExpr::new(cx.expr_uint(topmost, loc.col.to_uint())) } /// file!(): expands to the current filename */ @@ -55,10 +53,10 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = topmost_expn_info(cx.backtrace().unwrap()); - let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo); + let topmost = cx.original_span_in_file(); + let loc = cx.codemap().lookup_char_pos(topmost.lo); let filename = token::intern_and_get_ident(loc.file.name.as_slice()); - base::MacExpr::new(cx.expr_str(topmost.call_site, filename)) + base::MacExpr::new(cx.expr_str(topmost, filename)) } pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) @@ -162,32 +160,6 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } -// recur along an ExpnInfo chain to find the original expression -fn topmost_expn_info(expn_info: Gc<codemap::ExpnInfo>) -> Gc<codemap::ExpnInfo> { - match *expn_info { - ExpnInfo { call_site: ref call_site, .. } => { - match call_site.expn_info { - Some(next_expn_info) => { - match *next_expn_info { - ExpnInfo { - callee: NameAndSpan { name: ref name, .. }, - .. - } => { - // Don't recurse into file using "include!" - if "include" == name.as_slice() { - expn_info - } else { - topmost_expn_info(next_expn_info) - } - } - } - }, - None => expn_info - } - } - } -} - // resolve a file-system path to an absolute file-system path (if it // isn't already) fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 3beba5bcda4..7ebb11c148b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -657,16 +657,26 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> { }) } -pub fn noop_fold_ty_param_bound<T: Folder>(tpb: TyParamBound, fld: &mut T) - -> TyParamBound { +pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) + -> TyParamBound + where T: Folder { match tpb { TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - UnboxedFnTyParamBound(UnboxedFnTy {decl, kind}) => { - UnboxedFnTyParamBound(UnboxedFnTy { - decl: fld.fold_fn_decl(decl), - kind: kind, - }) + UnboxedFnTyParamBound(bound) => { + match *bound { + UnboxedFnBound { + ref path, + ref decl, + ref_id + } => { + UnboxedFnTyParamBound(P(UnboxedFnBound { + path: fld.fold_path(path.clone()), + decl: fld.fold_fn_decl(decl.clone()), + ref_id: fld.new_id(ref_id), + })) + } + } } } } @@ -1242,6 +1252,12 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> ExprIndex(el, er) => { ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) } + ExprSlice(e, e1, e2, m) => { + ExprSlice(folder.fold_expr(e), + e1.map(|x| folder.fold_expr(x)), + e2.map(|x| folder.fold_expr(x)), + m) + } ExprPath(pth) => ExprPath(folder.fold_path(pth)), ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 457d77efb70..153b3cc90d6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -23,7 +23,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/master/")] -#![feature(macro_rules, globs, managed_boxes, default_type_params, phase)] +#![feature(macro_rules, globs, default_type_params, phase)] #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)] #![allow(deprecated)] diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index da43f08a4e5..68ddd17dd01 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1406,7 +1406,7 @@ fn ident_continue(c: Option<char>) -> bool { mod test { use super::*; - use codemap::{BytePos, CodeMap, Span}; + use codemap::{BytePos, CodeMap, Span, NO_EXPANSION}; use diagnostic; use parse::token; use parse::token::{str_to_ident}; @@ -1436,7 +1436,7 @@ mod test { let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan{ tok:token::IDENT(id, false), - sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; + sp:Span {lo:BytePos(21),hi:BytePos(23),expn_id: NO_EXPANSION}}; assert_eq!(tok1,tok2); assert_eq!(string_reader.next_token().tok, token::WS); // the 'main' id is already read: @@ -1445,7 +1445,7 @@ mod test { let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ tok:token::IDENT(str_to_ident("main"), false), - sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; + sp:Span {lo:BytePos(24),hi:BytePos(28),expn_id: NO_EXPANSION}}; assert_eq!(tok3,tok4); // the lparen is already read: assert_eq!(string_reader.last_pos.clone(), BytePos(29)) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d73cb211694..66ecdbfca02 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -721,7 +721,7 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ { mod test { use super::*; use serialize::json; - use codemap::{Span, BytePos, Spanned}; + use codemap::{Span, BytePos, Spanned, NO_EXPANSION}; use owned_slice::OwnedSlice; use ast; use abi; @@ -736,7 +736,7 @@ mod test { // produce a codemap::span fn sp(a: u32, b: u32) -> Span { - Span{lo:BytePos(a),hi:BytePos(b),expn_info:None} + Span {lo: BytePos(a), hi: BytePos(b), expn_id: NO_EXPANSION} } #[test] fn path_exprs_1() { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff4fd41fbd7..069d30cbd83 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -23,7 +23,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast}; -use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex}; +use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIndex, ExprSlice}; use ast::{ExprLit, ExprLoop, ExprMac}; use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn}; @@ -55,7 +55,8 @@ use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath}; use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; -use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock}; +use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound}; +use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause, WherePredicate}; @@ -1986,6 +1987,14 @@ 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_ { + ExprSlice(expr, start, end, mutbl) + } + pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent, tys: Vec<P<Ty>>) -> ast::Expr_ { ExprField(expr, ident, tys) @@ -2400,13 +2409,87 @@ 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. token::LBRACKET => { self.bump(); - let ix = self.parse_expr(); - hi = self.span.hi; - self.commit_expr_expecting(&*ix, token::RBRACKET); - let index = self.mk_index(e, ix); - e = self.mk_expr(lo, hi, index) + let mutbl = if self.eat_keyword(keywords::Mut) { + MutMutable + } else { + MutImmutable + }; + match self.token { + // e[] + token::RBRACKET => { + 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::RBRACKET => { + self.bump(); + hi = self.span.hi; + let slice = self.mk_slice(e, None, None, mutbl); + e = self.mk_expr(lo, hi, slice); + + 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::RBRACKET); + 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(); + match self.token { + // e[e..] | e[e..e] + token::DOTDOT => { + self.bump(); + let e2 = match self.token { + // e[e..] + token::RBRACKET => { + self.bump(); + None + } + // e[e..e] + _ => { + let e2 = self.parse_expr(); + self.commit_expr_expecting(&*e2, token::RBRACKET); + 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::RBRACKET); + let index = self.mk_index(e, ix); + e = self.mk_expr(lo, hi, index) + } + } + } + } } _ => return e @@ -3153,7 +3236,8 @@ impl<'a> Parser<'a> { // These expressions are limited to literals (possibly // preceded by unary-minus) or identifiers. let val = self.parse_literal_maybe_minus(); - if self.token == token::DOTDOT && + // FIXME(#17295) remove the DOTDOT option. + if (self.token == token::DOTDOTDOT || self.token == token::DOTDOT) && self.look_ahead(1, |t| { *t != token::COMMA && *t != token::RBRACKET }) { @@ -3198,12 +3282,16 @@ impl<'a> Parser<'a> { } }); - if self.look_ahead(1, |t| *t == token::DOTDOT) && + // FIXME(#17295) remove the DOTDOT option. + if self.look_ahead(1, |t| *t == token::DOTDOTDOT || *t == token::DOTDOT) && self.look_ahead(2, |t| { *t != token::COMMA && *t != token::RBRACKET }) { let start = self.parse_expr_res(RestrictionNoBarOp); - self.eat(&token::DOTDOT); + // FIXME(#17295) remove the DOTDOT option (self.eat(&token::DOTDOTDOT)). + if self.token == token::DOTDOTDOT || self.token == token::DOTDOT { + self.bump(); + } let end = self.parse_expr_res(RestrictionNoBarOp); pat = PatRange(start, end); } else if is_plain_ident(&self.token) && !can_be_enum_or_struct { @@ -3590,7 +3678,7 @@ impl<'a> Parser<'a> { let span_with_semi = Span { lo: span.lo, hi: self.last_span.hi, - expn_info: span.expn_info, + expn_id: span.expn_id, }; stmts.push(P(Spanned { node: StmtSemi(e, stmt_id), @@ -3666,39 +3754,6 @@ impl<'a> Parser<'a> { }) } - fn parse_unboxed_function_type(&mut self) -> UnboxedFnTy { - let (optional_unboxed_closure_kind, inputs) = - if self.eat(&token::OROR) { - (None, Vec::new()) - } else { - self.expect_or(); - - let optional_unboxed_closure_kind = - self.parse_optional_unboxed_closure_kind(); - - let inputs = self.parse_seq_to_before_or(&token::COMMA, - |p| { - p.parse_arg_general(false) - }); - self.expect_or(); - (optional_unboxed_closure_kind, inputs) - }; - - let (return_style, output) = self.parse_ret_ty(); - UnboxedFnTy { - decl: P(FnDecl { - inputs: inputs, - output: output, - cf: return_style, - variadic: false, - }), - kind: match optional_unboxed_closure_kind { - Some(kind) => kind, - None => FnMutUnboxedClosureKind, - }, - } - } - // Parses a sequence of bounds if a `:` is found, // otherwise returns empty list. fn parse_colon_then_ty_param_bounds(&mut self) @@ -3730,13 +3785,31 @@ impl<'a> Parser<'a> { self.bump(); } token::MOD_SEP | token::IDENT(..) => { - let tref = self.parse_trait_ref(); - result.push(TraitTyParamBound(tref)); - } - token::BINOP(token::OR) | token::OROR => { - let unboxed_function_type = - self.parse_unboxed_function_type(); - result.push(UnboxedFnTyParamBound(unboxed_function_type)); + let path = + self.parse_path(LifetimeAndTypesWithoutColons).path; + if self.token == token::LPAREN { + self.bump(); + let inputs = self.parse_seq_to_end( + &token::RPAREN, + seq_sep_trailing_allowed(token::COMMA), + |p| p.parse_arg_general(false)); + let (return_style, output) = self.parse_ret_ty(); + result.push(UnboxedFnTyParamBound(P(UnboxedFnBound { + path: path, + decl: P(FnDecl { + inputs: inputs, + output: output, + cf: return_style, + variadic: false, + }), + ref_id: ast::DUMMY_NODE_ID, + }))); + } else { + result.push(TraitTyParamBound(ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + })) + } } _ => break, } @@ -4423,14 +4496,6 @@ impl<'a> Parser<'a> { Some(attrs)) } - /// Parse a::B<String,int> - fn parse_trait_ref(&mut self) -> TraitRef { - ast::TraitRef { - path: self.parse_path(LifetimeAndTypesWithoutColons).path, - ref_id: ast::DUMMY_NODE_ID, - } - } - /// Parse struct Foo { ... } fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo { let class_name = self.parse_ident(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 5a0aeece272..f71190da430 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -431,9 +431,11 @@ macro_rules! declare_special_idents_and_keywords {( // If the special idents get renumbered, remember to modify these two as appropriate pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM); static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM); +static SUPER_KEYWORD_NAME: Name = Name(SUPER_KEYWORD_NAME_NUM); pub static SELF_KEYWORD_NAME_NUM: u32 = 1; static STATIC_KEYWORD_NAME_NUM: u32 = 2; +static SUPER_KEYWORD_NAME_NUM: u32 = 3; // NB: leaving holes in the ident table is bad! a different ident will get // interned with the id from the hole, but it will be between the min and max @@ -443,52 +445,53 @@ declare_special_idents_and_keywords! { pub mod special_idents { // These ones are statics (0, invalid, ""); - (super::SELF_KEYWORD_NAME_NUM, self_, "self"); - (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); - (3, static_lifetime, "'static"); + (super::SELF_KEYWORD_NAME_NUM, self_, "self"); + (super::STATIC_KEYWORD_NAME_NUM, statik, "static"); + (super::SUPER_KEYWORD_NAME_NUM, super_, "super"); + (4, static_lifetime, "'static"); // for matcher NTs - (4, tt, "tt"); - (5, matchers, "matchers"); + (5, tt, "tt"); + (6, matchers, "matchers"); // outside of libsyntax - (6, clownshoe_abi, "__rust_abi"); - (7, opaque, "<opaque>"); - (8, unnamed_field, "<unnamed_field>"); - (9, type_self, "Self"); - (10, prelude_import, "prelude_import"); + (7, clownshoe_abi, "__rust_abi"); + (8, opaque, "<opaque>"); + (9, unnamed_field, "<unnamed_field>"); + (10, type_self, "Self"); + (11, prelude_import, "prelude_import"); } pub mod keywords { // These ones are variants of the Keyword enum 'strict: - (11, As, "as"); - (12, Break, "break"); - (13, Crate, "crate"); - (14, Else, "else"); - (15, Enum, "enum"); - (16, Extern, "extern"); - (17, False, "false"); - (18, Fn, "fn"); - (19, For, "for"); - (20, If, "if"); - (21, Impl, "impl"); - (22, In, "in"); - (23, Let, "let"); - (24, Loop, "loop"); - (25, Match, "match"); - (26, Mod, "mod"); - (27, Mut, "mut"); - (28, Once, "once"); - (29, Pub, "pub"); - (30, Ref, "ref"); - (31, Return, "return"); + (12, As, "as"); + (13, Break, "break"); + (14, Crate, "crate"); + (15, Else, "else"); + (16, Enum, "enum"); + (17, Extern, "extern"); + (18, False, "false"); + (19, Fn, "fn"); + (20, For, "for"); + (21, If, "if"); + (22, Impl, "impl"); + (23, In, "in"); + (24, Let, "let"); + (25, Loop, "loop"); + (26, Match, "match"); + (27, Mod, "mod"); + (28, Mut, "mut"); + (29, Once, "once"); + (30, Pub, "pub"); + (31, Ref, "ref"); + (32, Return, "return"); // Static and Self are also special idents (prefill de-dupes) - (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); - (super::SELF_KEYWORD_NAME_NUM, Self, "self"); - (32, Struct, "struct"); - (33, Super, "super"); + (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); + (super::SELF_KEYWORD_NAME_NUM, Self, "self"); + (33, Struct, "struct"); + (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); (34, True, "true"); (35, Trait, "trait"); (36, Type, "type"); @@ -713,6 +716,7 @@ pub fn is_any_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= RESERVED_KEYWORD_FINAL }, @@ -727,9 +731,18 @@ pub fn is_strict_keyword(tok: &Token) -> bool { n == SELF_KEYWORD_NAME || n == STATIC_KEYWORD_NAME + || n == SUPER_KEYWORD_NAME || STRICT_KEYWORD_START <= n && n <= STRICT_KEYWORD_FINAL }, + token::IDENT(sid, true) => { + let n = sid.name; + + n != SELF_KEYWORD_NAME + && n != SUPER_KEYWORD_NAME + && STRICT_KEYWORD_START <= n + && n <= STRICT_KEYWORD_FINAL + } _ => false, } } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 70da4e11961..f1fdc71b9c6 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -60,7 +60,7 @@ //! avoid combining it with other lines and making matters even worse. use std::io; -use std::string::String; +use std::string; #[deriving(Clone, PartialEq)] pub enum Breaks { @@ -82,7 +82,7 @@ pub struct BeginToken { #[deriving(Clone)] pub enum Token { - String(String, int), + String(string::String, int), Break(BreakToken), Begin(BeginToken), End, @@ -107,7 +107,7 @@ impl Token { } } -pub fn tok_str(t: Token) -> String { +pub fn tok_str(t: Token) -> string::String { match t { String(s, len) => return format!("STR({},{})", s, len), Break(_) => return "BREAK".to_string(), @@ -122,12 +122,12 @@ pub fn buf_str(toks: Vec<Token>, left: uint, right: uint, lim: uint) - -> String { + -> string::String { let n = toks.len(); assert_eq!(n, szs.len()); let mut i = left; let mut l = lim; - let mut s = String::from_str("["); + let mut s = string::String::from_str("["); while i != right && l != 0u { l -= 1u; if i != left { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0ae5303641b..473179a037a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1651,6 +1651,28 @@ impl<'a> State<'a> { try!(self.print_expr(&**index)); try!(word(&mut self.s, "]")); } + ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => { + try!(self.print_expr(&**e)); + try!(word(&mut self.s, "[")); + if mutbl == &ast::MutMutable { + try!(word(&mut self.s, "mut")); + if start.is_some() || end.is_some() { + try!(space(&mut self.s)); + } + } + match start { + &Some(ref e) => try!(self.print_expr(&**e)), + _ => {} + } + if start.is_some() || end.is_some() { + try!(word(&mut self.s, "..")); + } + match end { + &Some(ref e) => try!(self.print_expr(&**e)), + _ => {} + } + try!(word(&mut self.s, "]")); + } ast::ExprPath(ref path) => try!(self.print_path(path, true)), ast::ExprBreak(opt_ident) => { try!(word(&mut self.s, "break")); @@ -1944,7 +1966,7 @@ impl<'a> State<'a> { ast::PatRange(ref begin, ref end) => { try!(self.print_expr(&**begin)); try!(space(&mut self.s)); - try!(word(&mut self.s, "..")); + try!(word(&mut self.s, "...")); try!(self.print_expr(&**end)); } ast::PatVec(ref before, ref slice, ref after) => { @@ -2190,16 +2212,13 @@ impl<'a> State<'a> { self.print_lifetime(lt) } UnboxedFnTyParamBound(ref unboxed_function_type) => { - self.print_ty_fn(None, - None, - ast::NormalFn, - ast::Many, - &*unboxed_function_type.decl, - None, - &OwnedSlice::empty(), - None, - None, - Some(unboxed_function_type.kind)) + try!(self.print_path(&unboxed_function_type.path, + false)); + try!(self.popen()); + try!(self.print_fn_args(&*unboxed_function_type.decl, + None)); + try!(self.pclose()); + self.print_fn_output(&*unboxed_function_type.decl) } }) } @@ -2430,6 +2449,23 @@ impl<'a> State<'a> { self.end() } + pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> { + match decl.output.node { + ast::TyNil => Ok(()), + _ => { + try!(self.space_if_not_bol()); + try!(self.ibox(indent_unit)); + try!(self.word_space("->")); + if decl.cf == ast::NoReturn { + try!(self.word_nbsp("!")); + } else { + try!(self.print_type(&*decl.output)); + } + self.end() + } + } + } + pub fn print_ty_fn(&mut self, opt_abi: Option<abi::Abi>, opt_sigil: Option<char>, @@ -2510,20 +2546,7 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(decl.output.span.lo)); - match decl.output.node { - ast::TyNil => {} - _ => { - try!(self.space_if_not_bol()); - try!(self.ibox(indent_unit)); - try!(self.word_space("->")); - if decl.cf == ast::NoReturn { - try!(self.word_nbsp("!")); - } else { - try!(self.print_type(&*decl.output)); - } - try!(self.end()); - } - } + try!(self.print_fn_output(decl)); match generics { Some(generics) => try!(self.print_where_clause(generics)), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d425c60f4c9..32084856817 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -785,6 +785,11 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(&**main_expression); visitor.visit_expr(&**index_expression) } + ExprSlice(ref main_expression, ref start, ref end, _) => { + visitor.visit_expr(&**main_expression); + walk_expr_opt(visitor, start); + walk_expr_opt(visitor, end) + } ExprPath(ref path) => { visitor.visit_path(path, expression.id) } |
