From 462e43f685db22be54c5e79b70043bb09db95d51 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 21 Jun 2016 09:22:23 -0700 Subject: [PATCH] Sync with rustc 1.11.0-nightly (5522e678b 2016-06-20) --- syntex_syntax/src/ast.rs | 4 - syntex_syntax/src/attr.rs | 33 +- syntex_syntax/src/codemap.rs | 67 +- syntex_syntax/src/config.rs | 161 +- syntex_syntax/src/errors/emitter.rs | 10 +- syntex_syntax/src/errors/snippet/test.rs | 28 +- syntex_syntax/src/ext/base.rs | 51 +- syntex_syntax/src/ext/expand.rs | 167 +- syntex_syntax/src/ext/source_util.rs | 4 +- syntex_syntax/src/ext/tt/macro_rules.rs | 251 +-- syntex_syntax/src/feature_gate.rs | 91 +- syntex_syntax/src/parse/lexer/comments.rs | 2 +- syntex_syntax/src/parse/lexer/mod.rs | 2 +- syntex_syntax/src/parse/mod.rs | 2 +- syntex_syntax/src/parse/parser.rs | 21 +- syntex_syntax/src/print/pprust.rs | 1751 ++++++++++----------- syntex_syntax/src/std_inject.rs | 172 +- syntex_syntax/src/test.rs | 21 +- syntex_syntax/src/util/interner.rs | 10 +- syntex_syntax/src/util/parser_testing.rs | 2 +- syntex_syntax/src/util/small_vector.rs | 19 + syntex_syntax/src/visit.rs | 6 + 22 files changed, 1302 insertions(+), 1573 deletions(-) diff --git a/syntex_syntax/src/ast.rs b/syntex_syntax/src/ast.rs index 40c98206..8537fcc2 100644 --- a/syntex_syntax/src/ast.rs +++ b/syntex_syntax/src/ast.rs @@ -60,10 +60,6 @@ impl Name { pub fn as_str(self) -> token::InternedString { token::InternedString::new_from_name(self) } - - pub fn unhygienize(self) -> Name { - token::intern(&self.as_str()) - } } impl fmt::Debug for Name { diff --git a/syntex_syntax/src/attr.rs b/syntex_syntax/src/attr.rs index c3c3deea..e36e1580 100644 --- a/syntex_syntax/src/attr.rs +++ b/syntex_syntax/src/attr.rs @@ -20,12 +20,11 @@ use ast::{Stmt, StmtKind, DeclKind}; use ast::{Expr, Item, Local, Decl}; use codemap::{Span, Spanned, spanned, dummy_spanned}; use codemap::BytePos; -use config::CfgDiag; use errors::Handler; -use feature_gate::{GatedCfg, GatedCfgAttr}; +use feature_gate::{Features, GatedCfg}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::token::InternedString; -use parse::token; +use parse::{ParseSess, token}; use ptr::P; use std::cell::{RefCell, Cell}; @@ -365,35 +364,29 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool { } /// Tests if a cfg-pattern matches the cfg set -pub fn cfg_matches(cfgs: &[P], - cfg: &ast::MetaItem, - diag: &mut T) -> bool { +pub fn cfg_matches(cfgs: &[P], cfg: &ast::MetaItem, + sess: &ParseSess, features: Option<&Features>) + -> bool { match cfg.node { ast::MetaItemKind::List(ref pred, ref mis) if &pred[..] == "any" => - mis.iter().any(|mi| cfg_matches(cfgs, &mi, diag)), + mis.iter().any(|mi| cfg_matches(cfgs, &mi, sess, features)), ast::MetaItemKind::List(ref pred, ref mis) if &pred[..] == "all" => - mis.iter().all(|mi| cfg_matches(cfgs, &mi, diag)), + mis.iter().all(|mi| cfg_matches(cfgs, &mi, sess, features)), ast::MetaItemKind::List(ref pred, ref mis) if &pred[..] == "not" => { if mis.len() != 1 { - diag.emit_error(|diagnostic| { - diagnostic.span_err(cfg.span, "expected 1 cfg-pattern"); - }); + sess.span_diagnostic.span_err(cfg.span, "expected 1 cfg-pattern"); return false; } - !cfg_matches(cfgs, &mis[0], diag) + !cfg_matches(cfgs, &mis[0], sess, features) } ast::MetaItemKind::List(ref pred, _) => { - diag.emit_error(|diagnostic| { - diagnostic.span_err(cfg.span, - &format!("invalid predicate `{}`", pred)); - }); + sess.span_diagnostic.span_err(cfg.span, &format!("invalid predicate `{}`", pred)); false }, ast::MetaItemKind::Word(_) | ast::MetaItemKind::NameValue(..) => { - diag.flag_gated(|feature_gated_cfgs| { - feature_gated_cfgs.extend( - GatedCfg::gate(cfg).map(GatedCfgAttr::GatedCfg)); - }); + if let (Some(features), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) { + gated_cfg.check_and_emit(sess, features); + } contains(cfgs, cfg) } } diff --git a/syntex_syntax/src/codemap.rs b/syntex_syntax/src/codemap.rs index d391cd0b..5e1335b4 100644 --- a/syntex_syntax/src/codemap.rs +++ b/syntex_syntax/src/codemap.rs @@ -21,10 +21,11 @@ pub use self::ExpnFormat::*; use std::cell::{Cell, RefCell}; use std::ops::{Add, Sub}; -use std::path::Path; +use std::path::{Path,PathBuf}; use std::rc::Rc; use std::cmp; +use std::env; use std::{fmt, fs}; use std::io::{self, Read}; @@ -508,6 +509,8 @@ pub struct FileMap { /// originate from files has names between angle brackets by convention, /// e.g. `` pub name: FileName, + /// The absolute path of the file that the source came from. + pub abs_path: Option, /// The complete source code pub src: Option>, /// The start position of this source in the CodeMap @@ -522,11 +525,12 @@ pub struct FileMap { impl Encodable for FileMap { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_struct("FileMap", 5, |s| { + s.emit_struct("FileMap", 6, |s| { s.emit_struct_field("name", 0, |s| self.name.encode(s))?; - s.emit_struct_field("start_pos", 1, |s| self.start_pos.encode(s))?; - s.emit_struct_field("end_pos", 2, |s| self.end_pos.encode(s))?; - s.emit_struct_field("lines", 3, |s| { + s.emit_struct_field("abs_path", 1, |s| self.abs_path.encode(s))?; + s.emit_struct_field("start_pos", 2, |s| self.start_pos.encode(s))?; + s.emit_struct_field("end_pos", 3, |s| self.end_pos.encode(s))?; + s.emit_struct_field("lines", 4, |s| { let lines = self.lines.borrow(); // store the length s.emit_u32(lines.len() as u32)?; @@ -572,7 +576,7 @@ impl Encodable for FileMap { Ok(()) })?; - s.emit_struct_field("multibyte_chars", 4, |s| { + s.emit_struct_field("multibyte_chars", 5, |s| { (*self.multibyte_chars.borrow()).encode(s) }) }) @@ -582,11 +586,13 @@ impl Encodable for FileMap { impl Decodable for FileMap { fn decode(d: &mut D) -> Result { - d.read_struct("FileMap", 5, |d| { + d.read_struct("FileMap", 6, |d| { let name: String = d.read_struct_field("name", 0, |d| Decodable::decode(d))?; - let start_pos: BytePos = d.read_struct_field("start_pos", 1, |d| Decodable::decode(d))?; - let end_pos: BytePos = d.read_struct_field("end_pos", 2, |d| Decodable::decode(d))?; - let lines: Vec = d.read_struct_field("lines", 3, |d| { + let abs_path: Option = + d.read_struct_field("abs_path", 1, |d| Decodable::decode(d))?; + let start_pos: BytePos = d.read_struct_field("start_pos", 2, |d| Decodable::decode(d))?; + let end_pos: BytePos = d.read_struct_field("end_pos", 3, |d| Decodable::decode(d))?; + let lines: Vec = d.read_struct_field("lines", 4, |d| { let num_lines: u32 = Decodable::decode(d)?; let mut lines = Vec::with_capacity(num_lines as usize); @@ -615,9 +621,10 @@ impl Decodable for FileMap { Ok(lines) })?; let multibyte_chars: Vec = - d.read_struct_field("multibyte_chars", 4, |d| Decodable::decode(d))?; + d.read_struct_field("multibyte_chars", 5, |d| Decodable::decode(d))?; Ok(FileMap { name: name, + abs_path: abs_path, start_pos: start_pos, end_pos: end_pos, src: None, @@ -703,6 +710,9 @@ pub trait FileLoader { /// Query the existence of a file. fn file_exists(&self, path: &Path) -> bool; + /// Return an absolute path to a file, if possible. + fn abs_path(&self, path: &Path) -> Option; + /// Read the contents of an UTF-8 file into memory. fn read_file(&self, path: &Path) -> io::Result; } @@ -715,6 +725,16 @@ impl FileLoader for RealFileLoader { fs::metadata(path).is_ok() } + fn abs_path(&self, path: &Path) -> Option { + if path.is_absolute() { + Some(path.to_path_buf()) + } else { + env::current_dir() + .ok() + .map(|cwd| cwd.join(path)) + } + } + fn read_file(&self, path: &Path) -> io::Result { let mut src = String::new(); fs::File::open(path)?.read_to_string(&mut src)?; @@ -755,7 +775,8 @@ impl CodeMap { pub fn load_file(&self, path: &Path) -> io::Result> { let src = self.file_loader.read_file(path)?; - Ok(self.new_filemap(path.to_str().unwrap().to_string(), src)) + let abs_path = self.file_loader.abs_path(path).map(|p| p.to_str().unwrap().to_string()); + Ok(self.new_filemap(path.to_str().unwrap().to_string(), abs_path, src)) } fn next_start_pos(&self) -> usize { @@ -770,7 +791,8 @@ impl CodeMap { /// Creates a new filemap without setting its line information. If you don't /// intend to set the line information yourself, you should use new_filemap_and_lines. - pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc { + pub fn new_filemap(&self, filename: FileName, abs_path: Option, + mut src: String) -> Rc { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); @@ -783,6 +805,7 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, + abs_path: abs_path, src: Some(Rc::new(src)), start_pos: Pos::from_usize(start_pos), end_pos: Pos::from_usize(end_pos), @@ -796,8 +819,11 @@ impl CodeMap { } /// Creates a new filemap and sets its line information. - pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc { - let fm = self.new_filemap(filename.to_string(), src.to_owned()); + pub fn new_filemap_and_lines(&self, filename: &str, abs_path: Option<&str>, + src: &str) -> Rc { + let fm = self.new_filemap(filename.to_string(), + abs_path.map(|s| s.to_owned()), + src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; for line in src.lines() { // register the start of this line @@ -816,6 +842,7 @@ impl CodeMap { /// information for things inlined from other crates. pub fn new_imported_filemap(&self, filename: FileName, + abs_path: Option, source_len: usize, mut file_local_lines: Vec, mut file_local_multibyte_chars: Vec) @@ -836,6 +863,7 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, + abs_path: abs_path, src: None, start_pos: start_pos, end_pos: end_pos, @@ -1422,6 +1450,7 @@ mod tests { fn t1 () { let cm = CodeMap::new(); let fm = cm.new_filemap("blork.rs".to_string(), + None, "first line.\nsecond line".to_string()); fm.next_line(BytePos(0)); // Test we can get lines with partial line info. @@ -1438,6 +1467,7 @@ mod tests { fn t2 () { let cm = CodeMap::new(); let fm = cm.new_filemap("blork.rs".to_string(), + None, "first line.\nsecond line".to_string()); // TESTING *REALLY* BROKEN BEHAVIOR: fm.next_line(BytePos(0)); @@ -1448,10 +1478,13 @@ mod tests { fn init_code_map() -> CodeMap { let cm = CodeMap::new(); let fm1 = cm.new_filemap("blork.rs".to_string(), + None, "first line.\nsecond line".to_string()); let fm2 = cm.new_filemap("empty.rs".to_string(), + None, "".to_string()); let fm3 = cm.new_filemap("blork2.rs".to_string(), + None, "first line.\nsecond line".to_string()); fm1.next_line(BytePos(0)); @@ -1514,8 +1547,10 @@ mod tests { // € is a three byte utf8 char. let fm1 = cm.new_filemap("blork.rs".to_string(), + None, "fir€st €€€€ line.\nsecond line".to_string()); let fm2 = cm.new_filemap("blork2.rs".to_string(), + None, "first line€€.\n€ second line".to_string()); fm1.next_line(BytePos(0)); @@ -1583,7 +1618,7 @@ mod tests { let cm = CodeMap::new(); let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", inputtext); + cm.new_filemap_and_lines("blork.rs", None, inputtext); let span = span_from_selection(inputtext, selection); // check that we are extracting the text we thought we were extracting diff --git a/syntex_syntax/src/config.rs b/syntex_syntax/src/config.rs index c164e89c..0e5d6841 100644 --- a/syntex_syntax/src/config.rs +++ b/syntex_syntax/src/config.rs @@ -9,50 +9,33 @@ // except according to those terms. use attr::{AttrMetaMethods, HasAttrs}; -use errors::Handler; -use feature_gate::GatedCfgAttr; +use feature_gate::{emit_feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features, GateIssue}; use fold::Folder; use {ast, fold, attr}; use codemap::{Spanned, respan}; +use parse::{ParseSess, token}; use ptr::P; use util::small_vector::SmallVector; -pub trait CfgFolder: fold::Folder { - // Check if a node with the given attributes is in this configuration. - fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool; - - // Update a node before checking if it is in this configuration (used to implement `cfg_attr`). - fn process_attrs(&mut self, node: T) -> T { node } - - // Visit attributes on expression and statements (but not attributes on items in blocks). - fn visit_stmt_or_expr_attrs(&mut self, _attrs: &[ast::Attribute]) {} - - // Visit unremovable (non-optional) expressions -- c.f. `fold_expr` vs `fold_opt_expr`. - fn visit_unremovable_expr(&mut self, _expr: &ast::Expr) {} +/// A folder that strips out items that do not belong in the current configuration. +pub struct StripUnconfigured<'a> { + pub config: &'a ast::CrateConfig, + pub should_test: bool, + pub sess: &'a ParseSess, + pub features: Option<&'a Features>, +} +impl<'a> StripUnconfigured<'a> { fn configure(&mut self, node: T) -> Option { - let node = self.process_attrs(node); + let node = self.process_cfg_attrs(node); if self.in_cfg(node.attrs()) { Some(node) } else { None } } -} - -/// A folder that strips out items that do not belong in the current -/// configuration. -pub struct StripUnconfigured<'a> { - diag: CfgDiagReal<'a, 'a>, - config: &'a ast::CrateConfig, -} -impl<'a> StripUnconfigured<'a> { - pub fn new(config: &'a ast::CrateConfig, - diagnostic: &'a Handler, - feature_gated_cfgs: &'a mut Vec) - -> Self { - StripUnconfigured { - config: config, - diag: CfgDiagReal { diag: diagnostic, feature_gated_cfgs: feature_gated_cfgs }, - } + fn process_cfg_attrs(&mut self, node: T) -> T { + node.map_attrs(|attrs| { + attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect() + }) } fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Option { @@ -64,7 +47,7 @@ impl<'a> StripUnconfigured<'a> { Some(attr_list) => attr_list, None => { let msg = "expected `#[cfg_attr(, )]`"; - self.diag.diag.span_err(attr.span, msg); + self.sess.span_diagnostic.span_err(attr.span, msg); return None; } }; @@ -72,13 +55,13 @@ impl<'a> StripUnconfigured<'a> { (2, Some(cfg), Some(mi)) => (cfg, mi), _ => { let msg = "expected `#[cfg_attr(, )]`"; - self.diag.diag.span_err(attr.span, msg); + self.sess.span_diagnostic.span_err(attr.span, msg); return None; } }; - if attr::cfg_matches(self.config, &cfg, &mut self.diag) { - Some(respan(mi.span, ast::Attribute_ { + if attr::cfg_matches(self.config, &cfg, self.sess, self.features) { + self.process_cfg_attr(respan(mi.span, ast::Attribute_ { id: attr::mk_attr_id(), style: attr.node.style, value: mi.clone(), @@ -88,61 +71,73 @@ impl<'a> StripUnconfigured<'a> { None } } -} -impl<'a> CfgFolder for StripUnconfigured<'a> { - // Determine if an item should be translated in the current crate - // configuration based on the item's attributes + // Determine if a node with the given attributes should be included in this configuation. fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool { attrs.iter().all(|attr| { + // When not compiling with --test we should not compile the #[test] functions + if !self.should_test && is_test_or_bench(attr) { + return false; + } + let mis = match attr.node.value.node { ast::MetaItemKind::List(_, ref mis) if is_cfg(&attr) => mis, _ => return true }; if mis.len() != 1 { - self.diag.emit_error(|diagnostic| { - diagnostic.span_err(attr.span, "expected 1 cfg-pattern"); - }); + self.sess.span_diagnostic.span_err(attr.span, "expected 1 cfg-pattern"); return true; } - attr::cfg_matches(self.config, &mis[0], &mut self.diag) - }) - } - - fn process_attrs(&mut self, node: T) -> T { - node.map_attrs(|attrs| { - attrs.into_iter().filter_map(|attr| self.process_cfg_attr(attr)).collect() + attr::cfg_matches(self.config, &mis[0], self.sess, self.features) }) } + // Visit attributes on expression and statements (but not attributes on items in blocks). fn visit_stmt_or_expr_attrs(&mut self, attrs: &[ast::Attribute]) { // flag the offending attributes for attr in attrs.iter() { - self.diag.feature_gated_cfgs.push(GatedCfgAttr::GatedAttr(attr.span)); - } - } - - fn visit_unremovable_expr(&mut self, expr: &ast::Expr) { - if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) { - let msg = "removing an expression is not supported in this position"; - self.diag.diag.span_err(attr.span, msg); + if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { + emit_feature_err(&self.sess.span_diagnostic, + "stmt_expr_attributes", + attr.span, + GateIssue::Language, + EXPLAIN_STMT_ATTR_SYNTAX); + } } } } // Support conditional compilation by transforming the AST, stripping out // any items that do not belong in the current configuration -pub fn strip_unconfigured_items(diagnostic: &Handler, krate: ast::Crate, - feature_gated_cfgs: &mut Vec) - -> ast::Crate -{ - let config = &krate.config.clone(); - StripUnconfigured::new(config, diagnostic, feature_gated_cfgs).fold_crate(krate) +pub fn strip_unconfigured_items(mut krate: ast::Crate, sess: &ParseSess, should_test: bool) + -> (ast::Crate, Features) { + let features; + { + let mut strip_unconfigured = StripUnconfigured { + config: &krate.config.clone(), + should_test: should_test, + sess: sess, + features: None, + }; + + let err_count = sess.span_diagnostic.err_count(); + let krate_attrs = strip_unconfigured.process_cfg_attrs(krate.attrs.clone()); + features = get_features(&sess.span_diagnostic, &krate_attrs); + if err_count < sess.span_diagnostic.err_count() { + krate.attrs = krate_attrs.clone(); // Avoid reconfiguring malformed `cfg_attr`s + } + + strip_unconfigured.features = Some(&features); + krate = strip_unconfigured.fold_crate(krate); + krate.attrs = krate_attrs; + } + + (krate, features) } -impl fold::Folder for T { +impl<'a> fold::Folder for StripUnconfigured<'a> { fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod { ast::ForeignMod { abi: foreign_mod.abi, @@ -195,6 +190,7 @@ impl fold::Folder for T { fn fold_expr(&mut self, expr: P) -> P { self.visit_stmt_or_expr_attrs(expr.attrs()); + // If an expr is valid to cfg away it will have been removed by the // outer stmt or expression folder before descending in here. // Anything else is always required, and thus has to error out @@ -202,8 +198,12 @@ impl fold::Folder for T { // // NB: This is intentionally not part of the fold_expr() function // in order for fold_opt_expr() to be able to avoid this check - self.visit_unremovable_expr(&expr); - let expr = self.process_attrs(expr); + if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a) || is_test_or_bench(a)) { + let msg = "removing an expression is not supported in this position"; + self.sess.span_diagnostic.span_err(attr.span, msg); + } + + let expr = self.process_cfg_attrs(expr); fold_expr(self, expr) } @@ -247,9 +247,15 @@ impl fold::Folder for T { self.configure(item).map(|item| fold::noop_fold_trait_item(item, self)) .unwrap_or(SmallVector::zero()) } + + fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal { + // Don't configure interpolated AST (c.f. #34171). + // Interpolated AST will get configured once the surrounding tokens are parsed. + nt + } } -fn fold_expr(folder: &mut F, expr: P) -> P { +fn fold_expr(folder: &mut StripUnconfigured, expr: P) -> P { expr.map(|ast::Expr {id, span, node, attrs}| { fold::noop_fold_expr(ast::Expr { id: id, @@ -271,21 +277,6 @@ fn is_cfg(attr: &ast::Attribute) -> bool { attr.check_name("cfg") } -pub trait CfgDiag { - fn emit_error(&mut self, f: F) where F: FnMut(&Handler); - fn flag_gated(&mut self, f: F) where F: FnMut(&mut Vec); -} - -pub struct CfgDiagReal<'a, 'b> { - pub diag: &'a Handler, - pub feature_gated_cfgs: &'b mut Vec, -} - -impl<'a, 'b> CfgDiag for CfgDiagReal<'a, 'b> { - fn emit_error(&mut self, mut f: F) where F: FnMut(&Handler) { - f(self.diag) - } - fn flag_gated(&mut self, mut f: F) where F: FnMut(&mut Vec) { - f(self.feature_gated_cfgs) - } +fn is_test_or_bench(attr: &ast::Attribute) -> bool { + attr.check_name("test") || attr.check_name("bench") } diff --git a/syntex_syntax/src/errors/emitter.rs b/syntex_syntax/src/errors/emitter.rs index 6b15aa4f..71a03e84 100644 --- a/syntex_syntax/src/errors/emitter.rs +++ b/syntex_syntax/src/errors/emitter.rs @@ -668,7 +668,7 @@ mod test { tolv dreizehn "; - let file = cm.new_filemap_and_lines("dummy.txt", content); + let file = cm.new_filemap_and_lines("dummy.txt", None, content); let start = file.lines.borrow()[10]; let end = file.lines.borrow()[11]; let sp = mk_sp(start, end); @@ -694,7 +694,7 @@ mod test { let cm = CodeMap::new(); let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", inputtext); + cm.new_filemap_and_lines("blork.rs", None, inputtext); let sp = span_from_selection(inputtext, selection); let msp: MultiSpan = sp.into(); @@ -717,7 +717,7 @@ mod test { let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection1 = " \n \n \n \n ~ \n"; // intentionally out of order let selection2 = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", inputtext); + cm.new_filemap_and_lines("blork.rs", None, inputtext); let sp1 = span_from_selection(inputtext, selection1); let sp2 = span_from_selection(inputtext, selection2); let msp: MultiSpan = MultiSpan::from_spans(vec![sp1, sp2]); @@ -757,7 +757,7 @@ mod test { assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected); sp }; - cm.new_filemap_and_lines("dummy.txt", inp); + cm.new_filemap_and_lines("dummy.txt", None, inp); let sp1 = span(sp1, "aaaaaa"); let sp2 = span(sp2, "bbbbbb"); let sp3 = span(sp3, "ccccc"); @@ -802,7 +802,7 @@ mod test { ddd__eee_\n\ elided\n\ __f_gg"; - let file = cm.new_filemap_and_lines("dummy.txt", inp); + let file = cm.new_filemap_and_lines("dummy.txt", None, inp); let span = |lo, hi, (off_lo, off_hi)| { let lines = file.lines.borrow(); diff --git a/syntex_syntax/src/errors/snippet/test.rs b/syntex_syntax/src/errors/snippet/test.rs index 51fe4572..79e40a09 100644 --- a/syntex_syntax/src/errors/snippet/test.rs +++ b/syntex_syntax/src/errors/snippet/test.rs @@ -88,7 +88,7 @@ fn foo() { "; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span_bar = cm.span_substr(&foo, file_text, "bar", 0); let mut snippet = SnippetData::new(cm, Some(span_bar)); @@ -113,7 +113,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0); let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1); let span_semi = cm.span_substr(&foo, file_text, ";", 0); @@ -173,12 +173,12 @@ fn bar() { "#; let cm = Rc::new(CodeMap::new()); - let foo_map = cm.new_filemap_and_lines("foo.rs", file_text_foo); + let foo_map = cm.new_filemap_and_lines("foo.rs", None, file_text_foo); let span_foo_vec0 = cm.span_substr(&foo_map, file_text_foo, "vec", 0); let span_foo_vec1 = cm.span_substr(&foo_map, file_text_foo, "vec", 1); let span_foo_semi = cm.span_substr(&foo_map, file_text_foo, ";", 0); - let bar_map = cm.new_filemap_and_lines("bar.rs", file_text_bar); + let bar_map = cm.new_filemap_and_lines("bar.rs", None, file_text_bar); let span_bar_vec0 = cm.span_substr(&bar_map, file_text_bar, "vec", 0); let span_bar_vec1 = cm.span_substr(&bar_map, file_text_bar, "vec", 1); let span_bar_semi = cm.span_substr(&bar_map, file_text_bar, ";", 0); @@ -235,7 +235,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span_data0 = cm.span_substr(&foo, file_text, "data", 0); let span_data1 = cm.span_substr(&foo, file_text, "data", 1); let span_rbrace = cm.span_substr(&foo, file_text, "}", 3); @@ -274,7 +274,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span0 = cm.span_substr(&foo, file_text, "vec.push", 0); let span1 = cm.span_substr(&foo, file_text, "vec", 0); let span2 = cm.span_substr(&foo, file_text, "ec.push", 0); @@ -312,7 +312,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0); let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1); let span_semi = cm.span_substr(&foo, file_text, ";", 0); @@ -354,7 +354,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let span_vec0 = cm.span_substr(&foo, file_text, "vec", 3); let span_vec1 = cm.span_substr(&foo, file_text, "vec", 8); @@ -393,7 +393,7 @@ fn foo() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut snippet = SnippetData::new(cm.clone(), None); for i in 0..4 { @@ -427,7 +427,7 @@ impl SomeTrait for () { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut snippet = SnippetData::new(cm.clone(), None); let fn_span = cm.span_substr(&foo, file_text, "fn", 0); @@ -456,7 +456,7 @@ fn span_overlap_label() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut snippet = SnippetData::new(cm.clone(), None); let fn_span = cm.span_substr(&foo, file_text, "fn foo(x: u32)", 0); @@ -491,7 +491,7 @@ fn span_overlap_label2() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut snippet = SnippetData::new(cm.clone(), None); let fn_span = cm.span_substr(&foo, file_text, "fn foo(x", 0); @@ -529,7 +529,7 @@ fn span_overlap_label3() { "#; let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut snippet = SnippetData::new(cm.clone(), None); @@ -578,7 +578,7 @@ fn main() { let cm = Rc::new(CodeMap::new()); - let foo = cm.new_filemap_and_lines("foo.rs", file_text); + let foo = cm.new_filemap_and_lines("foo.rs", None, file_text); let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1); rbrace_span.lo = rbrace_span.hi; diff --git a/syntex_syntax/src/ext/base.rs b/syntex_syntax/src/ext/base.rs index 303187ae..5da81a26 100644 --- a/syntex_syntax/src/ext/base.rs +++ b/syntex_syntax/src/ext/base.rs @@ -18,7 +18,6 @@ use errors::DiagnosticBuilder; use ext; use ext::expand; use ext::tt::macro_rules; -use feature_gate::GatedCfgAttr; use parse; use parse::parser; use parse::token; @@ -95,6 +94,16 @@ impl Annotatable { _ => panic!("expected Item") } } + + pub fn fold_with(self, folder: &mut F) -> SmallVector { + match self { + Annotatable::Item(item) => folder.fold_item(item).map(Annotatable::Item), + Annotatable::ImplItem(item) => + folder.fold_impl_item(item.unwrap()).map(|item| Annotatable::ImplItem(P(item))), + Annotatable::TraitItem(item) => + folder.fold_trait_item(item.unwrap()).map(|item| Annotatable::TraitItem(P(item))), + } + } } // A more flexible ItemDecorator. @@ -536,6 +545,17 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders } +pub trait MacroLoader { + fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec; +} + +pub struct DummyMacroLoader; +impl MacroLoader for DummyMacroLoader { + fn load_crate(&mut self, _: &ast::Item, _: bool) -> Vec { + Vec::new() + } +} + /// One of these is made during expansion and incrementally updated as we go; /// when a macro expansion occurs, the resulting nodes have the backtrace() /// -> expn_info of their expansion context stored into their span. @@ -545,7 +565,7 @@ pub struct ExtCtxt<'a> { pub backtrace: ExpnId, pub ecfg: expand::ExpansionConfig<'a>, pub crate_root: Option<&'static str>, - pub feature_gated_cfgs: &'a mut Vec, + pub loader: &'a mut MacroLoader, pub mod_path: Vec , pub exported_macros: Vec, @@ -561,7 +581,8 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, ecfg: expand::ExpansionConfig<'a>, - feature_gated_cfgs: &'a mut Vec) -> ExtCtxt<'a> { + loader: &'a mut MacroLoader) + -> ExtCtxt<'a> { let env = initial_syntax_expander_table(&ecfg); ExtCtxt { parse_sess: parse_sess, @@ -570,8 +591,8 @@ impl<'a> ExtCtxt<'a> { mod_path: Vec::new(), ecfg: ecfg, crate_root: None, - feature_gated_cfgs: feature_gated_cfgs, exported_macros: Vec::new(), + loader: loader, syntax_env: env, recursion_count: 0, @@ -602,22 +623,6 @@ impl<'a> ExtCtxt<'a> { } pub fn backtrace(&self) -> ExpnId { self.backtrace } - /// Original span that caused the current exapnsion to happen. - 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") - } - /// Returns span for the macro which originally caused the current expansion to happen. /// /// Stops backtracing at include! boundary. @@ -925,4 +930,10 @@ impl SyntaxEnv { let last_chain_index = self.chain.len() - 1; &mut self.chain[last_chain_index].info } + + pub fn is_crate_root(&mut self) -> bool { + // The first frame is pushed in `SyntaxEnv::new()` and the second frame is + // pushed when folding the crate root pseudo-module (c.f. noop_fold_crate). + self.chain.len() <= 2 + } } diff --git a/syntex_syntax/src/ext/expand.rs b/syntex_syntax/src/ext/expand.rs index d3f5a573..d6341156 100644 --- a/syntex_syntax/src/ext/expand.rs +++ b/syntex_syntax/src/ext/expand.rs @@ -41,6 +41,7 @@ trait MacroGenerable: Sized { // Fold this node or list of nodes using the given folder. fn fold_with(self, folder: &mut F) -> Self; + fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V); // Return a placeholder expansion to allow compilation to continue after an erroring expansion. fn dummy(span: Span) -> Self; @@ -50,7 +51,9 @@ trait MacroGenerable: Sized { } macro_rules! impl_macro_generable { - ($($ty:ty: $kind_name:expr, .$make:ident, $(.$fold:ident)* $(lift .$fold_elt:ident)*, + ($($ty:ty: $kind_name:expr, .$make:ident, + $(.$fold:ident)* $(lift .$fold_elt:ident)*, + $(.$visit:ident)* $(lift .$visit_elt:ident)*, |$span:ident| $dummy:expr;)*) => { $( impl MacroGenerable for $ty { fn kind_name() -> &'static str { $kind_name } @@ -59,21 +62,27 @@ macro_rules! impl_macro_generable { $( folder.$fold(self) )* $( self.into_iter().flat_map(|item| folder. $fold_elt (item)).collect() )* } + fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V) { + $( visitor.$visit(self) )* + $( for item in self.as_slice() { visitor. $visit_elt (item) } )* + } fn dummy($span: Span) -> Self { $dummy } } )* } } impl_macro_generable! { - P: "expression", .make_expr, .fold_expr, |span| DummyResult::raw_expr(span); - P: "pattern", .make_pat, .fold_pat, |span| P(DummyResult::raw_pat(span)); - P: "type", .make_ty, .fold_ty, |span| DummyResult::raw_ty(span); - SmallVector: - "impl item", .make_impl_items, lift .fold_impl_item, |_span| SmallVector::zero(); - SmallVector>: - "item", .make_items, lift .fold_item, |_span| SmallVector::zero(); + P: "pattern", .make_pat, .fold_pat, .visit_pat, |span| P(DummyResult::raw_pat(span)); + P: "type", .make_ty, .fold_ty, .visit_ty, |span| DummyResult::raw_ty(span); + P: + "expression", .make_expr, .fold_expr, .visit_expr, |span| DummyResult::raw_expr(span); SmallVector: - "statement", .make_stmts, lift .fold_stmt, |_span| SmallVector::zero(); + "statement", .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero(); + SmallVector>: + "item", .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero(); + SmallVector: + "impl item", .make_impl_items, lift .fold_impl_item, lift .visit_impl_item, + |_span| SmallVector::zero(); } impl MacroGenerable for Option> { @@ -85,6 +94,9 @@ impl MacroGenerable for Option> { fn fold_with(self, folder: &mut F) -> Self { self.and_then(|expr| folder.fold_opt_expr(expr)) } + fn visit_with<'v, V: Visitor<'v>>(&'v self, visitor: &mut V) { + self.as_ref().map(|expr| visitor.visit_expr(expr)); + } } pub fn expand_expr(expr: ast::Expr, fld: &mut MacroExpander) -> P { @@ -236,14 +248,8 @@ fn expand_mac_invoc(mac: ast::Mac, ident: Option, attrs: Vec { @@ -326,6 +332,7 @@ fn expand_mac_invoc(mac: ast::Mac, ident: Option, attrs: Vec SmallVector { let a = expand_item_multi_modifier(a, fld); - let mut decorator_items = SmallVector::zero(); - let mut new_attrs = Vec::new(); - expand_decorators(a.clone(), fld, &mut decorator_items, &mut new_attrs); - - let mut new_items: SmallVector = match a { + let new_items: SmallVector = match a { Annotatable::Item(it) => match it.node { ast::ItemKind::Mac(..) => { - let new_items: SmallVector> = it.and_then(|it| match it.node { + it.and_then(|it| match it.node { ItemKind::Mac(mac) => expand_mac_invoc(mac, Some(it.ident), it.attrs, it.span, fld), _ => unreachable!(), - }); - - new_items.into_iter().map(|i| Annotatable::Item(i)).collect() + }) } ast::ItemKind::Mod(_) | ast::ItemKind::ForeignMod(_) => { let valid_ident = @@ -745,23 +746,17 @@ fn expand_annotatable(a: Annotatable, if valid_ident { fld.cx.mod_push(it.ident); } - let macro_use = contains_macro_use(fld, &new_attrs[..]); + let macro_use = contains_macro_use(fld, &it.attrs); let result = with_exts_frame!(fld.cx.syntax_env, macro_use, noop_fold_item(it, fld)); if valid_ident { fld.cx.mod_pop(); } - result.into_iter().map(|i| Annotatable::Item(i)).collect() + result }, - _ => { - let it = P(ast::Item { - attrs: new_attrs, - ..(*it).clone() - }); - noop_fold_item(it, fld).into_iter().map(|i| Annotatable::Item(i)).collect() - } - }, + _ => noop_fold_item(it, fld), + }.into_iter().map(|i| Annotatable::Item(i)).collect(), Annotatable::TraitItem(it) => match it.node { ast::TraitItemKind::Method(_, Some(_)) => { @@ -789,6 +784,15 @@ fn expand_annotatable(a: Annotatable, } }; + new_items.into_iter().flat_map(|a| decorate(a, fld)).collect() +} + +fn decorate(a: Annotatable, fld: &mut MacroExpander) -> SmallVector { + let mut decorator_items = SmallVector::zero(); + let mut new_attrs = Vec::new(); + expand_decorators(a.clone(), fld, &mut decorator_items, &mut new_attrs); + + let mut new_items = SmallVector::one(a.fold_attrs(new_attrs)); new_items.push_all(decorator_items); new_items } @@ -839,16 +843,18 @@ fn expand_decorators(a: Annotatable, } }); - // we'd ideally decorator_items.push_all(expand_annotatable(ann, fld)), - // but that double-mut-borrows fld let mut items: SmallVector = SmallVector::zero(); dec.expand(fld.cx, attr.span, &attr.node.value, &a, &mut |ann| items.push(ann)); - decorator_items.extend(items.into_iter() - .flat_map(|ann| expand_annotatable(ann, fld).into_iter())); + + for item in items { + for configured_item in item.fold_with(&mut fld.strip_unconfigured()) { + decorator_items.extend(expand_annotatable(configured_item, fld)); + } + } fld.cx.bt_pop(); } @@ -992,9 +998,46 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fn strip_unconfigured(&mut self) -> StripUnconfigured { - StripUnconfigured::new(&self.cx.cfg, - &self.cx.parse_sess.span_diagnostic, - self.cx.feature_gated_cfgs) + StripUnconfigured { + config: &self.cx.cfg, + should_test: self.cx.ecfg.should_test, + sess: self.cx.parse_sess, + features: self.cx.ecfg.features, + } + } + + fn load_macros(&mut self, node: &T) { + struct MacroLoadingVisitor<'a, 'b: 'a>{ + cx: &'a mut ExtCtxt<'b>, + at_crate_root: bool, + } + + impl<'a, 'b, 'v> Visitor<'v> for MacroLoadingVisitor<'a, 'b> { + fn visit_mac(&mut self, _: &'v ast::Mac) {} + fn visit_item(&mut self, item: &'v ast::Item) { + if let ast::ItemKind::ExternCrate(..) = item.node { + // We need to error on `#[macro_use] extern crate` when it isn't at the + // crate root, because `$crate` won't work properly. + for def in self.cx.loader.load_crate(item, self.at_crate_root) { + self.cx.insert_macro(def); + } + } else { + let at_crate_root = ::std::mem::replace(&mut self.at_crate_root, false); + visit::walk_item(self, item); + self.at_crate_root = at_crate_root; + } + } + fn visit_block(&mut self, block: &'v ast::Block) { + let at_crate_root = ::std::mem::replace(&mut self.at_crate_root, false); + visit::walk_block(self, block); + self.at_crate_root = at_crate_root; + } + } + + node.visit_with(&mut MacroLoadingVisitor { + at_crate_root: self.cx.syntax_env.is_crate_root(), + cx: self.cx, + }); } } @@ -1098,6 +1141,7 @@ pub struct ExpansionConfig<'feat> { pub features: Option<&'feat Features>, pub recursion_limit: usize, pub trace_mac: bool, + pub should_test: bool, // If false, strip `#[test]` nodes } macro_rules! feature_tests { @@ -1120,6 +1164,7 @@ impl<'feat> ExpansionConfig<'feat> { features: None, recursion_limit: 64, trace_mac: false, + should_test: false, } } @@ -1136,10 +1181,8 @@ impl<'feat> ExpansionConfig<'feat> { } pub fn expand_crate(mut cx: ExtCtxt, - // these are the macros being imported to this crate: - imported_macros: Vec, user_exts: Vec, - c: Crate) -> (Crate, HashSet) { + mut c: Crate) -> (Crate, HashSet) { if std_inject::no_core(&c) { cx.crate_root = None; } else if std_inject::no_std(&c) { @@ -1150,14 +1193,14 @@ pub fn expand_crate(mut cx: ExtCtxt, let ret = { let mut expander = MacroExpander::new(&mut cx); - for def in imported_macros { - expander.cx.insert_macro(def); - } - for (name, extension) in user_exts { expander.cx.syntax_env.insert(name, extension); } + let items = SmallVector::many(c.module.items); + expander.load_macros(&items); + c.module.items = items.into(); + let err_count = cx.parse_sess.span_diagnostic.err_count(); let mut ret = expander.fold_crate(c); ret.exported_macros = expander.cx.exported_macros.clone(); @@ -1219,7 +1262,7 @@ mod tests { use ast; use ast::Name; use codemap; - use ext::base::ExtCtxt; + use ext::base::{ExtCtxt, DummyMacroLoader}; use ext::mtwt; use fold::Folder; use parse; @@ -1290,9 +1333,9 @@ mod tests { src, Vec::new(), &sess).unwrap(); // should fail: - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let mut loader = DummyMacroLoader; + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader); + expand_crate(ecx, vec![], crate_ast); } // make sure that macros can't escape modules @@ -1305,9 +1348,9 @@ mod tests { "".to_string(), src, Vec::new(), &sess).unwrap(); - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let mut loader = DummyMacroLoader; + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader); + expand_crate(ecx, vec![], crate_ast); } // macro_use modules should allow macros to escape @@ -1319,18 +1362,18 @@ mod tests { "".to_string(), src, Vec::new(), &sess).unwrap(); - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast); + let mut loader = DummyMacroLoader; + let ecx = ExtCtxt::new(&sess, vec![], test_ecfg(), &mut loader); + expand_crate(ecx, vec![], crate_ast); } fn expand_crate_str(crate_str: String) -> ast::Crate { let ps = parse::ParseSess::new(); let crate_ast = panictry!(string_to_parser(&ps, crate_str).parse_crate_mod()); // the cfg argument actually does matter, here... - let mut gated_cfgs = vec![]; - let ecx = ExtCtxt::new(&ps, vec![], test_ecfg(), &mut gated_cfgs); - expand_crate(ecx, vec![], vec![], crate_ast).0 + let mut loader = DummyMacroLoader; + let ecx = ExtCtxt::new(&ps, vec![], test_ecfg(), &mut loader); + expand_crate(ecx, vec![], crate_ast).0 } // find the pat_ident paths in a crate diff --git a/syntex_syntax/src/ext/source_util.rs b/syntex_syntax/src/ext/source_util.rs index 3e375e17..fd229d77 100644 --- a/syntex_syntax/src/ext/source_util.rs +++ b/syntex_syntax/src/ext/source_util.rs @@ -154,7 +154,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // dependency information let filename = format!("{}", file.display()); let interned = token::intern_and_get_ident(&src[..]); - cx.codemap().new_filemap_and_lines(&filename, &src); + cx.codemap().new_filemap_and_lines(&filename, None, &src); base::MacEager::expr(cx.expr_str(sp, interned)) } @@ -185,7 +185,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // Add this input file to the code map to make it available as // dependency information, but don't enter it's contents let filename = format!("{}", file.display()); - cx.codemap().new_filemap_and_lines(&filename, ""); + cx.codemap().new_filemap_and_lines(&filename, None, ""); base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Rc::new(bytes)))) } diff --git a/syntex_syntax/src/ext/tt/macro_rules.rs b/syntex_syntax/src/ext/tt/macro_rules.rs index 69e24cf0..bbe989b0 100644 --- a/syntex_syntax/src/ext/tt/macro_rules.rs +++ b/syntex_syntax/src/ext/tt/macro_rules.rs @@ -349,203 +349,12 @@ fn check_rhs(cx: &mut ExtCtxt, rhs: &TokenTree) -> bool { false } -// Issue 30450: when we are through a warning cycle, we can just error -// on all failure conditions and remove this struct and enum. - -#[derive(Debug)] -struct OnFail { - saw_failure: bool, - action: OnFailAction, -} - -#[derive(Copy, Clone, Debug, PartialEq)] -enum OnFailAction { Warn, Error, DoNothing } - -impl OnFail { - fn warn() -> OnFail { OnFail { saw_failure: false, action: OnFailAction::Warn } } - fn error() -> OnFail { OnFail { saw_failure: false, action: OnFailAction::Error } } - fn do_nothing() -> OnFail { OnFail { saw_failure: false, action: OnFailAction::DoNothing } } - fn react(&mut self, cx: &mut ExtCtxt, sp: Span, msg: &str, help: Option<&str>) { - match self.action { - OnFailAction::DoNothing => {} - OnFailAction::Error => { - let mut err = cx.struct_span_err(sp, msg); - if let Some(msg) = help { err.span_help(sp, msg); } - err.emit(); - } - OnFailAction::Warn => { - let mut warn = cx.struct_span_warn(sp, msg); - if let Some(msg) = help { warn.span_help(sp, msg); } - warn.span_note(sp, "The above warning will be a hard error in the next release.") - .emit(); - } - }; - self.saw_failure = true; - } -} - fn check_matcher(cx: &mut ExtCtxt, matcher: &[TokenTree]) -> bool { - // Issue 30450: when we are through a warning cycle, we can just - // error on all failure conditions (and remove check_matcher_old). - - // First run the old-pass, but *only* to find out if it would have failed. - let mut on_fail = OnFail::do_nothing(); - check_matcher_old(cx, matcher.iter(), &Eof, &mut on_fail); - // Then run the new pass, but merely warn if the old pass accepts and new pass rejects. - // (Note this silently accepts code if new pass accepts.) - let mut on_fail = if on_fail.saw_failure { - OnFail::error() - } else { - OnFail::warn() - }; - check_matcher_new(cx, matcher, &mut on_fail); - // matcher is valid if the new pass didn't see any error, - // or if errors were considered warnings - on_fail.action != OnFailAction::Error || !on_fail.saw_failure -} - -// returns the last token that was checked, for TokenTree::Sequence. -// return value is used by recursive calls. -fn check_matcher_old<'a, I>(cx: &mut ExtCtxt, matcher: I, follow: &Token, on_fail: &mut OnFail) --> Option<(Span, Token)> where I: Iterator { - use print::pprust::token_to_string; - use std::iter::once; - - let mut last = None; - - // 2. For each token T in M: - let mut tokens = matcher.peekable(); - while let Some(token) = tokens.next() { - last = match *token { - TokenTree::Token(sp, MatchNt(ref name, ref frag_spec)) => { - // ii. If T is a simple NT, look ahead to the next token T' in - // M. If T' is in the set FOLLOW(NT), continue. Else; reject. - if can_be_followed_by_any(&frag_spec.name.as_str()) { - continue - } else { - let next_token = match tokens.peek() { - // If T' closes a complex NT, replace T' with F - Some(&&TokenTree::Token(_, CloseDelim(_))) => follow.clone(), - Some(&&TokenTree::Token(_, ref tok)) => tok.clone(), - Some(&&TokenTree::Sequence(sp, _)) => { - // Be conservative around sequences: to be - // more specific, we would need to - // consider FIRST sets, but also the - // possibility that the sequence occurred - // zero times (in which case we need to - // look at the token that follows the - // sequence, which may itself be a sequence, - // and so on). - on_fail.react(cx, sp, - &format!("`${0}:{1}` is followed by a \ - sequence repetition, which is not \ - allowed for `{1}` fragments", - name, frag_spec), - None); - Eof - }, - // die next iteration - Some(&&TokenTree::Delimited(_, ref delim)) => delim.close_token(), - // else, we're at the end of the macro or sequence - None => follow.clone() - }; - - let tok = if let TokenTree::Token(_, ref tok) = *token { - tok - } else { - unreachable!() - }; - - // If T' is in the set FOLLOW(NT), continue. Else, reject. - match (&next_token, is_in_follow(cx, &next_token, &frag_spec.name.as_str())) { - (_, Err((msg, _))) => { - // no need for help message, those messages - // are never emitted anyway... - on_fail.react(cx, sp, &msg, None); - continue - } - (&Eof, _) => return Some((sp, tok.clone())), - (_, Ok(true)) => continue, - (next, Ok(false)) => { - on_fail.react(cx, sp, &format!("`${0}:{1}` is followed by `{2}`, which \ - is not allowed for `{1}` fragments", - name, frag_spec, - token_to_string(next)), None); - continue - }, - } - } - }, - TokenTree::Sequence(sp, ref seq) => { - // iii. Else, T is a complex NT. - match seq.separator { - // If T has the form $(...)U+ or $(...)U* for some token U, - // run the algorithm on the contents with F set to U. If it - // accepts, continue, else, reject. - Some(ref u) => { - let last = check_matcher_old(cx, seq.tts.iter(), u, on_fail); - match last { - // Since the delimiter isn't required after the last - // repetition, make sure that the *next* token is - // sane. This doesn't actually compute the FIRST of - // the rest of the matcher yet, it only considers - // single tokens and simple NTs. This is imprecise, - // but conservatively correct. - Some((span, tok)) => { - let fol = match tokens.peek() { - Some(&&TokenTree::Token(_, ref tok)) => tok.clone(), - Some(&&TokenTree::Delimited(_, ref delim)) => - delim.close_token(), - Some(_) => { - on_fail.react(cx, sp, "sequence repetition followed by \ - another sequence repetition, which is not allowed", - None); - Eof - }, - None => Eof - }; - check_matcher_old(cx, once(&TokenTree::Token(span, tok.clone())), - &fol, on_fail) - }, - None => last, - } - }, - // If T has the form $(...)+ or $(...)*, run the algorithm - // on the contents with F set to the token following the - // sequence. If it accepts, continue, else, reject. - None => { - let fol = match tokens.peek() { - Some(&&TokenTree::Token(_, ref tok)) => tok.clone(), - Some(&&TokenTree::Delimited(_, ref delim)) => delim.close_token(), - Some(_) => { - on_fail.react(cx, sp, "sequence repetition followed by another \ - sequence repetition, which is not allowed", None); - Eof - }, - None => Eof - }; - check_matcher_old(cx, seq.tts.iter(), &fol, on_fail) - } - } - }, - TokenTree::Token(..) => { - // i. If T is not an NT, continue. - continue - }, - TokenTree::Delimited(_, ref tts) => { - // if we don't pass in that close delimiter, we'll incorrectly consider the matcher - // `{ $foo:ty }` as having a follow that isn't `RBrace` - check_matcher_old(cx, tts.tts.iter(), &tts.close_token(), on_fail) - } - } - } - last -} - -fn check_matcher_new(cx: &mut ExtCtxt, matcher: &[TokenTree], on_fail: &mut OnFail) { let first_sets = FirstSets::new(matcher); let empty_suffix = TokenSet::empty(); - check_matcher_core(cx, &first_sets, matcher, &empty_suffix, on_fail); + let err = cx.parse_sess.span_diagnostic.err_count(); + check_matcher_core(cx, &first_sets, matcher, &empty_suffix); + err == cx.parse_sess.span_diagnostic.err_count() } // The FirstSets for a matcher is a mapping from subsequences in the @@ -785,8 +594,7 @@ impl TokenSet { fn check_matcher_core(cx: &mut ExtCtxt, first_sets: &FirstSets, matcher: &[TokenTree], - follow: &TokenSet, - on_fail: &mut OnFail) -> TokenSet { + follow: &TokenSet) -> TokenSet { use print::pprust::token_to_string; let mut last = TokenSet::empty(); @@ -815,11 +623,11 @@ fn check_matcher_core(cx: &mut ExtCtxt, TokenTree::Token(sp, ref tok) => { let can_be_followed_by_any; if let Err(bad_frag) = has_legal_fragment_specifier(tok) { - on_fail.react(cx, sp, - &format!("invalid fragment specifier `{}`", bad_frag), - Some("valid fragment specifiers are `ident`, `block`, \ - `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ - and `item`")); + cx.struct_span_err(sp, &format!("invalid fragment specifier `{}`", bad_frag)) + .help("valid fragment specifiers are `ident`, `block`, \ + `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \ + and `item`") + .emit(); // (This eliminates false positives and duplicates // from error messages.) can_be_followed_by_any = true; @@ -840,7 +648,7 @@ fn check_matcher_core(cx: &mut ExtCtxt, } TokenTree::Delimited(_, ref d) => { let my_suffix = TokenSet::singleton((d.close_span, Token::CloseDelim(d.delim))); - check_matcher_core(cx, first_sets, &d.tts, &my_suffix, on_fail); + check_matcher_core(cx, first_sets, &d.tts, &my_suffix); // don't track non NT tokens last.replace_with_irrelevant(); @@ -872,7 +680,7 @@ fn check_matcher_core(cx: &mut ExtCtxt, // At this point, `suffix_first` is built, and // `my_suffix` is some TokenSet that we can use // for checking the interior of `seq_rep`. - let next = check_matcher_core(cx, first_sets, &seq_rep.tts, my_suffix, on_fail); + let next = check_matcher_core(cx, first_sets, &seq_rep.tts, my_suffix); if next.maybe_empty { last.add_all(&next); } else { @@ -894,7 +702,7 @@ fn check_matcher_core(cx: &mut ExtCtxt, for &(sp, ref next_token) in &suffix_first.tokens { match is_in_follow(cx, next_token, &frag_spec.name.as_str()) { Err((msg, help)) => { - on_fail.react(cx, sp, &msg, Some(help)); + cx.struct_span_err(sp, &msg).help(help).emit(); // don't bother reporting every source of // conflict for a particular element of `last`. continue 'each_last; @@ -909,15 +717,14 @@ fn check_matcher_core(cx: &mut ExtCtxt, "may be" }; - on_fail.react( - cx, sp, + cx.span_err( + sp, &format!("`${name}:{frag}` {may_be} followed by `{next}`, which \ is not allowed for `{frag}` fragments", name=name, frag=frag_spec, next=token_to_string(next_token), - may_be=may_be), - None + may_be=may_be) ); } } @@ -947,33 +754,11 @@ fn token_can_be_followed_by_any(tok: &Token) -> bool { /// ANYTHING without fear of future compatibility hazards). fn frag_can_be_followed_by_any(frag: &str) -> bool { match frag { - "item" | // always terminated by `}` or `;` - "block" | // exactly one token tree - "ident" | // exactly one token tree - "meta" | // exactly one token tree - "tt" => // exactly one token tree - true, - - _ => - false, - } -} - -/// True if a fragment of type `frag` can be followed by any sort of -/// token. We use this (among other things) as a useful approximation -/// for when `frag` can be followed by a repetition like `$(...)*` or -/// `$(...)+`. In general, these can be a bit tricky to reason about, -/// so we adopt a conservative position that says that any fragment -/// specifier which consumes at most one token tree can be followed by -/// a fragment specifier (indeed, these fragments can be followed by -/// ANYTHING without fear of future compatibility hazards). -fn can_be_followed_by_any(frag: &str) -> bool { - match frag { - "item" | // always terminated by `}` or `;` + "item" | // always terminated by `}` or `;` "block" | // exactly one token tree "ident" | // exactly one token tree - "meta" | // exactly one token tree - "tt" => // exactly one token tree + "meta" | // exactly one token tree + "tt" => // exactly one token tree true, _ => diff --git a/syntex_syntax/src/feature_gate.rs b/syntex_syntax/src/feature_gate.rs index 86c4a338..550eb0a5 100644 --- a/syntex_syntax/src/feature_gate.rs +++ b/syntex_syntax/src/feature_gate.rs @@ -34,10 +34,10 @@ use codemap::{CodeMap, Span}; use errors::Handler; use visit; use visit::{FnKind, Visitor}; +use parse::ParseSess; use parse::token::InternedString; use std::ascii::AsciiExt; -use std::cmp; macro_rules! setter { ($field: ident) => {{ @@ -603,60 +603,12 @@ const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), ]; -#[derive(Debug, Eq, PartialEq)] -pub enum GatedCfgAttr { - GatedCfg(GatedCfg), - GatedAttr(Span), -} - #[derive(Debug, Eq, PartialEq)] pub struct GatedCfg { span: Span, index: usize, } -impl Ord for GatedCfgAttr { - fn cmp(&self, other: &GatedCfgAttr) -> cmp::Ordering { - let to_tup = |s: &GatedCfgAttr| match *s { - GatedCfgAttr::GatedCfg(ref gated_cfg) => { - (gated_cfg.span.lo.0, gated_cfg.span.hi.0, gated_cfg.index) - } - GatedCfgAttr::GatedAttr(ref span) => { - (span.lo.0, span.hi.0, GATED_CFGS.len()) - } - }; - to_tup(self).cmp(&to_tup(other)) - } -} - -impl PartialOrd for GatedCfgAttr { - fn partial_cmp(&self, other: &GatedCfgAttr) -> Option { - Some(self.cmp(other)) - } -} - -impl GatedCfgAttr { - pub fn check_and_emit(&self, - diagnostic: &Handler, - features: &Features, - codemap: &CodeMap) { - match *self { - GatedCfgAttr::GatedCfg(ref cfg) => { - cfg.check_and_emit(diagnostic, features, codemap); - } - GatedCfgAttr::GatedAttr(span) => { - if !features.stmt_expr_attributes { - emit_feature_err(diagnostic, - "stmt_expr_attributes", - span, - GateIssue::Language, - EXPLAIN_STMT_ATTR_SYNTAX); - } - } - } - } -} - impl GatedCfg { pub fn gate(cfg: &ast::MetaItem) -> Option { let name = cfg.name(); @@ -669,12 +621,11 @@ impl GatedCfg { } }) } - fn check_and_emit(&self, - diagnostic: &Handler, - features: &Features, - codemap: &CodeMap) { + + pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) { let (cfg, feature, has_feature) = GATED_CFGS[self.index]; - if !has_feature(features) && !codemap.span_allows_unstable(self.span) { + if !has_feature(features) && !sess.codemap().span_allows_unstable(self.span) { + let diagnostic = &sess.span_diagnostic; let explain = format!("`cfg({})` is experimental and subject to change", cfg); emit_feature_err(diagnostic, feature, self.span, GateIssue::Language, &explain); } @@ -810,7 +761,7 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs const EXPLAIN_BOX_SYNTAX: &'static str = "box expression syntax is experimental; you can call `Box::new` instead."; -const EXPLAIN_STMT_ATTR_SYNTAX: &'static str = +pub const EXPLAIN_STMT_ATTR_SYNTAX: &'static str = "attributes on non-item statements and expressions are experimental."; pub const EXPLAIN_ASM: &'static str = @@ -1142,10 +1093,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { } } -pub fn get_features(span_handler: &Handler, krate: &ast::Crate) -> Features { +pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> Features { let mut features = Features::new(); - for attr in &krate.attrs { + for attr in krate_attrs { if !attr.check_name("feature") { continue } @@ -1188,21 +1139,19 @@ pub fn get_features(span_handler: &Handler, krate: &ast::Crate) -> Features { features } -pub fn check_crate(cm: &CodeMap, span_handler: &Handler, krate: &ast::Crate, +pub fn check_crate(krate: &ast::Crate, + sess: &ParseSess, + features: &Features, plugin_attributes: &[(String, AttributeType)], - unstable: UnstableFeatures) -> Features { - maybe_stage_features(span_handler, krate, unstable); - let features = get_features(span_handler, krate); - { - let ctx = Context { - features: &features, - span_handler: span_handler, - cm: cm, - plugin_attributes: plugin_attributes, - }; - visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate); - } - features + unstable: UnstableFeatures) { + maybe_stage_features(&sess.span_diagnostic, krate, unstable); + let ctx = Context { + features: features, + span_handler: &sess.span_diagnostic, + cm: sess.codemap(), + plugin_attributes: plugin_attributes, + }; + visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate); } #[derive(Clone, Copy)] diff --git a/syntex_syntax/src/parse/lexer/comments.rs b/syntex_syntax/src/parse/lexer/comments.rs index 629edced..06d255d5 100644 --- a/syntex_syntax/src/parse/lexer/comments.rs +++ b/syntex_syntax/src/parse/lexer/comments.rs @@ -346,7 +346,7 @@ pub fn gather_comments_and_literals(span_diagnostic: &errors::Handler, srdr.read_to_end(&mut src).unwrap(); let src = String::from_utf8(src).unwrap(); let cm = CodeMap::new(); - let filemap = cm.new_filemap(path, src); + let filemap = cm.new_filemap(path, None, src); let mut rdr = lexer::StringReader::new_raw(span_diagnostic, filemap); let mut comments: Vec = Vec::new(); diff --git a/syntex_syntax/src/parse/lexer/mod.rs b/syntex_syntax/src/parse/lexer/mod.rs index da62e528..d78a81de 100644 --- a/syntex_syntax/src/parse/lexer/mod.rs +++ b/syntex_syntax/src/parse/lexer/mod.rs @@ -1695,7 +1695,7 @@ mod tests { span_handler: &'a errors::Handler, teststr: String) -> StringReader<'a> { - let fm = cm.new_filemap("zebra.rs".to_string(), teststr); + let fm = cm.new_filemap("zebra.rs".to_string(), None, teststr); StringReader::new(span_handler, fm) } diff --git a/syntex_syntax/src/parse/mod.rs b/syntex_syntax/src/parse/mod.rs index 2a9bcfd6..2e4d46bc 100644 --- a/syntex_syntax/src/parse/mod.rs +++ b/syntex_syntax/src/parse/mod.rs @@ -178,7 +178,7 @@ pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String) -> Parser<'a> { - filemap_to_parser(sess, sess.codemap().new_filemap(name, source), cfg) + filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source), cfg) } /// Create a new parser, handling errors as appropriate diff --git a/syntex_syntax/src/parse/parser.rs b/syntex_syntax/src/parse/parser.rs index 22cc20b8..341b076e 100644 --- a/syntex_syntax/src/parse/parser.rs +++ b/syntex_syntax/src/parse/parser.rs @@ -5430,18 +5430,15 @@ impl<'a> Parser<'a> { name: String, id_sp: Span) -> PResult<'a, (ast::ItemKind, Vec )> { let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); - match included_mod_stack.iter().position(|p| *p == path) { - Some(i) => { - let mut err = String::from("circular modules: "); - let len = included_mod_stack.len(); - for p in &included_mod_stack[i.. len] { - err.push_str(&p.to_string_lossy()); - err.push_str(" -> "); - } - err.push_str(&path.to_string_lossy()); - return Err(self.span_fatal(id_sp, &err[..])); - } - None => () + if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { + let mut err = String::from("circular modules: "); + let len = included_mod_stack.len(); + for p in &included_mod_stack[i.. len] { + err.push_str(&p.to_string_lossy()); + err.push_str(" -> "); + } + err.push_str(&path.to_string_lossy()); + return Err(self.span_fatal(id_sp, &err[..])); } included_mod_stack.push(path.clone()); drop(included_mod_stack); diff --git a/syntex_syntax/src/print/pprust.rs b/syntex_syntax/src/print/pprust.rs index 5b9ec924..a2ee5bf6 100644 --- a/syntex_syntax/src/print/pprust.rs +++ b/syntex_syntax/src/print/pprust.rs @@ -123,16 +123,16 @@ pub fn print_crate<'a>(cm: &'a CodeMap, let list = attr::mk_list_item(InternedString::new("feature"), vec![prelude_import_meta]); let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), list); - s.print_attribute(&fake_attr)?; + try!(s.print_attribute(&fake_attr)); // #![no_std] let no_std_meta = attr::mk_word_item(InternedString::new("no_std")); let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), no_std_meta); - s.print_attribute(&fake_attr)?; + try!(s.print_attribute(&fake_attr)); } - s.print_mod(&krate.module, &krate.attrs)?; - s.print_remaining_comments()?; + try!(s.print_mod(&krate.module, &krate.attrs)); + try!(s.print_remaining_comments()); eof(&mut s.s) } @@ -385,10 +385,10 @@ pub fn fun_to_string(decl: &ast::FnDecl, generics: &ast::Generics) -> String { to_string(|s| { - s.head("")?; - s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), - generics, &ast::Visibility::Inherited)?; - s.end()?; // Close the head box + try!(s.head("")); + try!(s.print_fn(decl, unsafety, constness, Abi::Rust, Some(name), + generics, &ast::Visibility::Inherited)); + try!(s.end()); // Close the head box s.end() // Close the outer box }) } @@ -396,9 +396,9 @@ pub fn fun_to_string(decl: &ast::FnDecl, pub fn block_to_string(blk: &ast::Block) -> String { to_string(|s| { // containing cbox, will be closed by print-block at } - s.cbox(INDENT_UNIT)?; + try!(s.cbox(INDENT_UNIT)); // head-ibox, will be closed by print-block after { - s.ibox(0)?; + try!(s.ibox(0)); s.print_block(blk) }) } @@ -454,7 +454,7 @@ pub trait PrintState<'a> { fn literals(&self) -> &Option>; fn word_space(&mut self, w: &str) -> io::Result<()> { - word(self.writer(), w)?; + try!(word(self.writer(), w)); space(self.writer()) } @@ -483,7 +483,7 @@ pub trait PrintState<'a> { fn hardbreak_if_not_bol(&mut self) -> io::Result<()> { if !self.is_bol() { - hardbreak(self.writer())? + try!(hardbreak(self.writer())) } Ok(()) } @@ -507,11 +507,11 @@ pub trait PrintState<'a> { fn commasep(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where F: FnMut(&mut Self, &T) -> io::Result<()>, { - self.rbox(0, b)?; + try!(self.rbox(0, b)); let mut first = true; for elt in elts { - if first { first = false; } else { self.word_space(",")?; } - op(self, elt)?; + if first { first = false; } else { try!(self.word_space(",")); } + try!(op(self, elt)); } self.end() } @@ -543,7 +543,7 @@ pub trait PrintState<'a> { match self.next_comment() { Some(ref cmnt) => { if (*cmnt).pos < pos { - self.print_comment(cmnt)?; + try!(self.print_comment(cmnt)); self.cur_cmnt_and_lit().cur_cmnt += 1; } else { break; } } @@ -558,34 +558,34 @@ pub trait PrintState<'a> { match cmnt.style { comments::Mixed => { assert_eq!(cmnt.lines.len(), 1); - zerobreak(self.writer())?; - word(self.writer(), &cmnt.lines[0])?; + try!(zerobreak(self.writer())); + try!(word(self.writer(), &cmnt.lines[0])); zerobreak(self.writer()) } comments::Isolated => { - self.hardbreak_if_not_bol()?; + try!(self.hardbreak_if_not_bol()); for line in &cmnt.lines { // Don't print empty lines because they will end up as trailing // whitespace if !line.is_empty() { - word(self.writer(), &line[..])?; + try!(word(self.writer(), &line[..])); } - hardbreak(self.writer())?; + try!(hardbreak(self.writer())); } Ok(()) } comments::Trailing => { - word(self.writer(), " ")?; + try!(word(self.writer(), " ")); if cmnt.lines.len() == 1 { - word(self.writer(), &cmnt.lines[0])?; + try!(word(self.writer(), &cmnt.lines[0])); hardbreak(self.writer()) } else { - self.ibox(0)?; + try!(self.ibox(0)); for line in &cmnt.lines { if !line.is_empty() { - word(self.writer(), &line[..])?; + try!(word(self.writer(), &line[..])); } - hardbreak(self.writer())?; + try!(hardbreak(self.writer())); } self.end() } @@ -597,7 +597,7 @@ pub trait PrintState<'a> { _ => false }; if is_semi || self.is_begin() || self.is_end() { - hardbreak(self.writer())?; + try!(hardbreak(self.writer())); } hardbreak(self.writer()) } @@ -619,7 +619,7 @@ pub trait PrintState<'a> { } fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { - self.maybe_print_comment(lit.span.lo)?; + try!(self.maybe_print_comment(lit.span.lo)); match self.next_lit(lit.span.lo) { Some(ref ltrl) => { return word(self.writer(), &(*ltrl).lit); @@ -725,15 +725,15 @@ pub trait PrintState<'a> { let mut count = 0; for attr in attrs { if attr.node.style == kind { - self.print_attribute_inline(attr, is_inline)?; - if is_inline { - self.nbsp()?; - } - count += 1; + try!(self.print_attribute_inline(attr, is_inline)); + if is_inline { + try!(self.nbsp()); + } + count += 1; } } if count > 0 && trailing_hardbreak && !is_inline { - self.hardbreak_if_not_bol()?; + try!(self.hardbreak_if_not_bol()); } Ok(()) } @@ -745,47 +745,47 @@ pub trait PrintState<'a> { fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> io::Result<()> { if !is_inline { - self.hardbreak_if_not_bol()?; + try!(self.hardbreak_if_not_bol()); } - self.maybe_print_comment(attr.span.lo)?; + try!(self.maybe_print_comment(attr.span.lo)); if attr.node.is_sugared_doc { - word(self.writer(), &attr.value_str().unwrap())?; + try!(word(self.writer(), &attr.value_str().unwrap())); hardbreak(self.writer()) } else { match attr.node.style { - ast::AttrStyle::Inner => word(self.writer(), "#![")?, - ast::AttrStyle::Outer => word(self.writer(), "#[")?, + ast::AttrStyle::Inner => try!(word(self.writer(), "#![")), + ast::AttrStyle::Outer => try!(word(self.writer(), "#[")), } - self.print_meta_item(&attr.meta())?; + try!(self.print_meta_item(&attr.meta())); word(self.writer(), "]") } } fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> { - self.ibox(INDENT_UNIT)?; + try!(self.ibox(INDENT_UNIT)); match item.node { ast::MetaItemKind::Word(ref name) => { - word(self.writer(), &name)?; + try!(word(self.writer(), &name)); } ast::MetaItemKind::NameValue(ref name, ref value) => { - self.word_space(&name[..])?; - self.word_space("=")?; - self.print_literal(value)?; + try!(self.word_space(&name[..])); + try!(self.word_space("=")); + try!(self.print_literal(value)); } ast::MetaItemKind::List(ref name, ref items) => { - word(self.writer(), &name)?; - self.popen()?; - self.commasep(Consistent, + try!(word(self.writer(), &name)); + try!(self.popen()); + try!(self.commasep(Consistent, &items[..], - |s, i| s.print_meta_item(&i))?; - self.pclose()?; + |s, i| s.print_meta_item(&i))); + try!(self.pclose()); } } self.end() } fn space_if_not_bol(&mut self) -> io::Result<()> { - if !self.is_bol() { space(self.writer())?; } + if !self.is_bol() { try!(space(self.writer())); } Ok(()) } @@ -821,24 +821,24 @@ impl<'a> State<'a> { } pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { - word(&mut self.s, w)?; + try!(word(&mut self.s, w)); self.nbsp() } pub fn head(&mut self, w: &str) -> io::Result<()> { // outer-box is consistent - self.cbox(INDENT_UNIT)?; + try!(self.cbox(INDENT_UNIT)); // head-box is inconsistent - self.ibox(w.len() + 1)?; + try!(self.ibox(w.len() + 1)); // keyword that starts the head if !w.is_empty() { - self.word_nbsp(w)?; + try!(self.word_nbsp(w)); } Ok(()) } pub fn bopen(&mut self) -> io::Result<()> { - word(&mut self.s, "{")?; + try!(word(&mut self.s, "{")); self.end() // close the head-box } @@ -848,11 +848,11 @@ impl<'a> State<'a> { } pub fn bclose_maybe_open(&mut self, span: codemap::Span, indented: usize, close_box: bool) -> io::Result<()> { - self.maybe_print_comment(span.hi)?; - self.break_offset_if_not_bol(1, -(indented as isize))?; - word(&mut self.s, "}")?; + try!(self.maybe_print_comment(span.hi)); + try!(self.break_offset_if_not_bol(1, -(indented as isize))); + try!(word(&mut self.s, "}")); if close_box { - self.end()?; // close the outer-box + try!(self.end()); // close the outer-box } Ok(()) } @@ -885,10 +885,10 @@ impl<'a> State<'a> { // Synthesizes a comment that was not textually present in the original source // file. pub fn synth_comment(&mut self, text: String) -> io::Result<()> { - word(&mut self.s, "/*")?; - space(&mut self.s)?; - word(&mut self.s, &text[..])?; - space(&mut self.s)?; + try!(word(&mut self.s, "/*")); + try!(space(&mut self.s)); + try!(word(&mut self.s, &text[..])); + try!(space(&mut self.s)); word(&mut self.s, "*/") } @@ -902,18 +902,18 @@ impl<'a> State<'a> { F: FnMut(&mut State, &T) -> io::Result<()>, G: FnMut(&T) -> codemap::Span, { - self.rbox(0, b)?; + try!(self.rbox(0, b)); let len = elts.len(); let mut i = 0; for elt in elts { - self.maybe_print_comment(get_span(elt).hi)?; - op(self, elt)?; + try!(self.maybe_print_comment(get_span(elt).hi)); + try!(op(self, elt)); i += 1; if i < len { - word(&mut self.s, ",")?; - self.maybe_print_trailing_comment(get_span(elt), - Some(get_span(&elts[i]).hi))?; - self.space_if_not_bol()?; + try!(word(&mut self.s, ",")); + try!(self.maybe_print_trailing_comment(get_span(elt), + Some(get_span(&elts[i]).hi))); + try!(self.space_if_not_bol()); } } self.end() @@ -926,18 +926,18 @@ impl<'a> State<'a> { pub fn print_mod(&mut self, _mod: &ast::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { - self.print_inner_attributes(attrs)?; + try!(self.print_inner_attributes(attrs)); for item in &_mod.items { - self.print_item(&item)?; + try!(self.print_item(&item)); } Ok(()) } pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod, attrs: &[ast::Attribute]) -> io::Result<()> { - self.print_inner_attributes(attrs)?; + try!(self.print_inner_attributes(attrs)); for item in &nmod.items { - self.print_foreign_item(item)?; + try!(self.print_foreign_item(item)); } Ok(()) } @@ -945,47 +945,47 @@ impl<'a> State<'a> { pub fn print_opt_lifetime(&mut self, lifetime: &Option) -> io::Result<()> { if let Some(l) = *lifetime { - self.print_lifetime(&l)?; - self.nbsp()?; + try!(self.print_lifetime(&l)); + try!(self.nbsp()); } Ok(()) } pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> { - self.maybe_print_comment(ty.span.lo)?; - self.ibox(0)?; + try!(self.maybe_print_comment(ty.span.lo)); + try!(self.ibox(0)); match ty.node { ast::TyKind::Vec(ref ty) => { - word(&mut self.s, "[")?; - self.print_type(&ty)?; - word(&mut self.s, "]")?; + try!(word(&mut self.s, "[")); + try!(self.print_type(&ty)); + try!(word(&mut self.s, "]")); } ast::TyKind::Ptr(ref mt) => { - word(&mut self.s, "*")?; + try!(word(&mut self.s, "*")); match mt.mutbl { - ast::Mutability::Mutable => self.word_nbsp("mut")?, - ast::Mutability::Immutable => self.word_nbsp("const")?, + ast::Mutability::Mutable => try!(self.word_nbsp("mut")), + ast::Mutability::Immutable => try!(self.word_nbsp("const")), } - self.print_type(&mt.ty)?; + try!(self.print_type(&mt.ty)); } ast::TyKind::Rptr(ref lifetime, ref mt) => { - word(&mut self.s, "&")?; - self.print_opt_lifetime(lifetime)?; - self.print_mt(mt)?; + try!(word(&mut self.s, "&")); + try!(self.print_opt_lifetime(lifetime)); + try!(self.print_mt(mt)); } ast::TyKind::Tup(ref elts) => { - self.popen()?; - self.commasep(Inconsistent, &elts[..], - |s, ty| s.print_type(&ty))?; + try!(self.popen()); + try!(self.commasep(Inconsistent, &elts[..], + |s, ty| s.print_type(&ty))); if elts.len() == 1 { - word(&mut self.s, ",")?; + try!(word(&mut self.s, ",")); } - self.pclose()?; + try!(self.pclose()); } ast::TyKind::Paren(ref typ) => { - self.popen()?; - self.print_type(&typ)?; - self.pclose()?; + try!(self.popen()); + try!(self.print_type(&typ)); + try!(self.pclose()); } ast::TyKind::BareFn(ref f) => { let generics = ast::Generics { @@ -996,45 +996,45 @@ impl<'a> State<'a> { predicates: Vec::new(), }, }; - self.print_ty_fn(f.abi, + try!(self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, - &generics)?; + &generics)); } ast::TyKind::Path(None, ref path) => { - self.print_path(path, false, 0)?; + try!(self.print_path(path, false, 0)); } ast::TyKind::Path(Some(ref qself), ref path) => { - self.print_qpath(path, qself, false)? + try!(self.print_qpath(path, qself, false)) } ast::TyKind::ObjectSum(ref ty, ref bounds) => { - self.print_type(&ty)?; - self.print_bounds("+", &bounds[..])?; + try!(self.print_type(&ty)); + try!(self.print_bounds("+", &bounds[..])); } ast::TyKind::PolyTraitRef(ref bounds) => { - self.print_bounds("", &bounds[..])?; + try!(self.print_bounds("", &bounds[..])); } ast::TyKind::FixedLengthVec(ref ty, ref v) => { - word(&mut self.s, "[")?; - self.print_type(&ty)?; - word(&mut self.s, "; ")?; - self.print_expr(&v)?; - word(&mut self.s, "]")?; + try!(word(&mut self.s, "[")); + try!(self.print_type(&ty)); + try!(word(&mut self.s, "; ")); + try!(self.print_expr(&v)); + try!(word(&mut self.s, "]")); } ast::TyKind::Typeof(ref e) => { - word(&mut self.s, "typeof(")?; - self.print_expr(&e)?; - word(&mut self.s, ")")?; + try!(word(&mut self.s, "typeof(")); + try!(self.print_expr(&e)); + try!(word(&mut self.s, ")")); } ast::TyKind::Infer => { - word(&mut self.s, "_")?; + try!(word(&mut self.s, "_")); } ast::TyKind::ImplicitSelf => { - unreachable!(); + try!(word(&mut self.s, "Self")); } ast::TyKind::Mac(ref m) => { - self.print_mac(m, token::Paren)?; + try!(self.print_mac(m, token::Paren)); } } self.end() @@ -1042,30 +1042,30 @@ impl<'a> State<'a> { pub fn print_foreign_item(&mut self, item: &ast::ForeignItem) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo)?; - self.print_outer_attributes(&item.attrs)?; + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(item.span.lo)); + try!(self.print_outer_attributes(&item.attrs)); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { - self.head("")?; - self.print_fn(decl, ast::Unsafety::Normal, + try!(self.head("")); + try!(self.print_fn(decl, ast::Unsafety::Normal, ast::Constness::NotConst, Abi::Rust, Some(item.ident), - generics, &item.vis)?; - self.end()?; // end head-ibox - word(&mut self.s, ";")?; + generics, &item.vis)); + try!(self.end()); // end head-ibox + try!(word(&mut self.s, ";")); self.end() // end the outer fn box } ast::ForeignItemKind::Static(ref t, m) => { - self.head(&visibility_qualified(&item.vis, "static"))?; + try!(self.head(&visibility_qualified(&item.vis, "static"))); if m { - self.word_space("mut")?; + try!(self.word_space("mut")); } - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&t)?; - word(&mut self.s, ";")?; - self.end()?; // end the head-ibox + try!(self.print_ident(item.ident)); + try!(self.word_space(":")); + try!(self.print_type(&t)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end the head-ibox self.end() // end the outer cbox } } @@ -1078,15 +1078,15 @@ impl<'a> State<'a> { vis: &ast::Visibility) -> io::Result<()> { - word(&mut self.s, &visibility_qualified(vis, ""))?; - self.word_space("const")?; - self.print_ident(ident)?; - self.word_space(":")?; - self.print_type(ty)?; + try!(word(&mut self.s, &visibility_qualified(vis, ""))); + try!(self.word_space("const")); + try!(self.print_ident(ident)); + try!(self.word_space(":")); + try!(self.print_type(ty)); if let Some(expr) = default { - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(expr)?; + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_expr(expr)); } word(&mut self.s, ";") } @@ -1096,83 +1096,83 @@ impl<'a> State<'a> { bounds: Option<&ast::TyParamBounds>, ty: Option<&ast::Ty>) -> io::Result<()> { - self.word_space("type")?; - self.print_ident(ident)?; + try!(self.word_space("type")); + try!(self.print_ident(ident)); if let Some(bounds) = bounds { - self.print_bounds(":", bounds)?; + try!(self.print_bounds(":", bounds)); } if let Some(ty) = ty { - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(ty)?; + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_type(ty)); } word(&mut self.s, ";") } /// Pretty-print an item pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo)?; - self.print_outer_attributes(&item.attrs)?; - self.ann.pre(self, NodeItem(item))?; + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(item.span.lo)); + try!(self.print_outer_attributes(&item.attrs)); + try!(self.ann.pre(self, NodeItem(item))); match item.node { ast::ItemKind::ExternCrate(ref optional_path) => { - self.head(&visibility_qualified(&item.vis, "extern crate"))?; + try!(self.head(&visibility_qualified(&item.vis, "extern crate"))); if let Some(p) = *optional_path { let val = p.as_str(); if val.contains("-") { - self.print_string(&val, ast::StrStyle::Cooked)?; + try!(self.print_string(&val, ast::StrStyle::Cooked)); } else { - self.print_name(p)?; + try!(self.print_name(p)); } - space(&mut self.s)?; - word(&mut self.s, "as")?; - space(&mut self.s)?; + try!(space(&mut self.s)); + try!(word(&mut self.s, "as")); + try!(space(&mut self.s)); } - self.print_ident(item.ident)?; - word(&mut self.s, ";")?; - self.end()?; // end inner head-block - self.end()?; // end outer head-block + try!(self.print_ident(item.ident)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end inner head-block + try!(self.end()); // end outer head-block } ast::ItemKind::Use(ref vp) => { - self.head(&visibility_qualified(&item.vis, "use"))?; - self.print_view_path(&vp)?; - word(&mut self.s, ";")?; - self.end()?; // end inner head-block - self.end()?; // end outer head-block + try!(self.head(&visibility_qualified(&item.vis, "use"))); + try!(self.print_view_path(&vp)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end inner head-block + try!(self.end()); // end outer head-block } ast::ItemKind::Static(ref ty, m, ref expr) => { - self.head(&visibility_qualified(&item.vis, "static"))?; + try!(self.head(&visibility_qualified(&item.vis, "static"))); if m == ast::Mutability::Mutable { - self.word_space("mut")?; + try!(self.word_space("mut")); } - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&ty)?; - space(&mut self.s)?; - self.end()?; // end the head-ibox + try!(self.print_ident(item.ident)); + try!(self.word_space(":")); + try!(self.print_type(&ty)); + try!(space(&mut self.s)); + try!(self.end()); // end the head-ibox - self.word_space("=")?; - self.print_expr(&expr)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer cbox + try!(self.word_space("=")); + try!(self.print_expr(&expr)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end the outer cbox } ast::ItemKind::Const(ref ty, ref expr) => { - self.head(&visibility_qualified(&item.vis, "const"))?; - self.print_ident(item.ident)?; - self.word_space(":")?; - self.print_type(&ty)?; - space(&mut self.s)?; - self.end()?; // end the head-ibox - - self.word_space("=")?; - self.print_expr(&expr)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer cbox + try!(self.head(&visibility_qualified(&item.vis, "const"))); + try!(self.print_ident(item.ident)); + try!(self.word_space(":")); + try!(self.print_type(&ty)); + try!(space(&mut self.s)); + try!(self.end()); // end the head-ibox + + try!(self.word_space("=")); + try!(self.print_expr(&expr)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end the outer cbox } ast::ItemKind::Fn(ref decl, unsafety, constness, abi, ref typarams, ref body) => { - self.head("")?; - self.print_fn( + try!(self.head("")); + try!(self.print_fn( decl, unsafety, constness, @@ -1180,65 +1180,65 @@ impl<'a> State<'a> { Some(item.ident), typarams, &item.vis - )?; - word(&mut self.s, " ")?; - self.print_block_with_attrs(&body, &item.attrs)?; + )); + try!(word(&mut self.s, " ")); + try!(self.print_block_with_attrs(&body, &item.attrs)); } ast::ItemKind::Mod(ref _mod) => { - self.head(&visibility_qualified(&item.vis, "mod"))?; - self.print_ident(item.ident)?; - self.nbsp()?; - self.bopen()?; - self.print_mod(_mod, &item.attrs)?; - self.bclose(item.span)?; + try!(self.head(&visibility_qualified(&item.vis, "mod"))); + try!(self.print_ident(item.ident)); + try!(self.nbsp()); + try!(self.bopen()); + try!(self.print_mod(_mod, &item.attrs)); + try!(self.bclose(item.span)); } ast::ItemKind::ForeignMod(ref nmod) => { - self.head("extern")?; - self.word_nbsp(&nmod.abi.to_string())?; - self.bopen()?; - self.print_foreign_mod(nmod, &item.attrs)?; - self.bclose(item.span)?; + try!(self.head("extern")); + try!(self.word_nbsp(&nmod.abi.to_string())); + try!(self.bopen()); + try!(self.print_foreign_mod(nmod, &item.attrs)); + try!(self.bclose(item.span)); } ast::ItemKind::Ty(ref ty, ref params) => { - self.ibox(INDENT_UNIT)?; - self.ibox(0)?; - self.word_nbsp(&visibility_qualified(&item.vis, "type"))?; - self.print_ident(item.ident)?; - self.print_generics(params)?; - self.end()?; // end the inner ibox - - self.print_where_clause(¶ms.where_clause)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&ty)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer ibox + try!(self.ibox(INDENT_UNIT)); + try!(self.ibox(0)); + try!(self.word_nbsp(&visibility_qualified(&item.vis, "type"))); + try!(self.print_ident(item.ident)); + try!(self.print_generics(params)); + try!(self.end()); // end the inner ibox + + try!(self.print_where_clause(¶ms.where_clause)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_type(&ty)); + try!(word(&mut self.s, ";")); + try!(self.end()); // end the outer ibox } ast::ItemKind::Enum(ref enum_definition, ref params) => { - self.print_enum_def( + try!(self.print_enum_def( enum_definition, params, item.ident, item.span, &item.vis - )?; + )); } ast::ItemKind::Struct(ref struct_def, ref generics) => { - self.head(&visibility_qualified(&item.vis, "struct"))?; - self.print_struct(&struct_def, generics, item.ident, item.span, true)?; + try!(self.head(&visibility_qualified(&item.vis, "struct"))); + try!(self.print_struct(&struct_def, generics, item.ident, item.span, true)); } ast::ItemKind::DefaultImpl(unsafety, ref trait_ref) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("impl")?; - self.print_trait_ref(trait_ref)?; - space(&mut self.s)?; - self.word_space("for")?; - self.word_space("..")?; - self.bopen()?; - self.bclose(item.span)?; + try!(self.head("")); + try!(self.print_visibility(&item.vis)); + try!(self.print_unsafety(unsafety)); + try!(self.word_nbsp("impl")); + try!(self.print_trait_ref(trait_ref)); + try!(space(&mut self.s)); + try!(self.word_space("for")); + try!(self.word_space("..")); + try!(self.bopen()); + try!(self.bclose(item.span)); } ast::ItemKind::Impl(unsafety, polarity, @@ -1246,80 +1246,80 @@ impl<'a> State<'a> { ref opt_trait, ref ty, ref impl_items) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("impl")?; + try!(self.head("")); + try!(self.print_visibility(&item.vis)); + try!(self.print_unsafety(unsafety)); + try!(self.word_nbsp("impl")); if generics.is_parameterized() { - self.print_generics(generics)?; - space(&mut self.s)?; + try!(self.print_generics(generics)); + try!(space(&mut self.s)); } match polarity { ast::ImplPolarity::Negative => { - word(&mut self.s, "!")?; + try!(word(&mut self.s, "!")); }, _ => {} } match *opt_trait { Some(ref t) => { - self.print_trait_ref(t)?; - space(&mut self.s)?; - self.word_space("for")?; + try!(self.print_trait_ref(t)); + try!(space(&mut self.s)); + try!(self.word_space("for")); } None => {} } - self.print_type(&ty)?; - self.print_where_clause(&generics.where_clause)?; + try!(self.print_type(&ty)); + try!(self.print_where_clause(&generics.where_clause)); - space(&mut self.s)?; - self.bopen()?; - self.print_inner_attributes(&item.attrs)?; + try!(space(&mut self.s)); + try!(self.bopen()); + try!(self.print_inner_attributes(&item.attrs)); for impl_item in impl_items { - self.print_impl_item(impl_item)?; + try!(self.print_impl_item(impl_item)); } - self.bclose(item.span)?; + try!(self.bclose(item.span)); } ast::ItemKind::Trait(unsafety, ref generics, ref bounds, ref trait_items) => { - self.head("")?; - self.print_visibility(&item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("trait")?; - self.print_ident(item.ident)?; - self.print_generics(generics)?; + try!(self.head("")); + try!(self.print_visibility(&item.vis)); + try!(self.print_unsafety(unsafety)); + try!(self.word_nbsp("trait")); + try!(self.print_ident(item.ident)); + try!(self.print_generics(generics)); let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = *b { - space(&mut self.s)?; - self.word_space("for ?")?; - self.print_trait_ref(&ptr.trait_ref)?; + try!(space(&mut self.s)); + try!(self.word_space("for ?")); + try!(self.print_trait_ref(&ptr.trait_ref)); } else { real_bounds.push(b.clone()); } } - self.print_bounds(":", &real_bounds[..])?; - self.print_where_clause(&generics.where_clause)?; - word(&mut self.s, " ")?; - self.bopen()?; + try!(self.print_bounds(":", &real_bounds[..])); + try!(self.print_where_clause(&generics.where_clause)); + try!(word(&mut self.s, " ")); + try!(self.bopen()); for trait_item in trait_items { - self.print_trait_item(trait_item)?; + try!(self.print_trait_item(trait_item)); } - self.bclose(item.span)?; + try!(self.bclose(item.span)); } ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => { - self.print_visibility(&item.vis)?; - self.print_path(&node.path, false, 0)?; - word(&mut self.s, "! ")?; - self.print_ident(item.ident)?; - self.cbox(INDENT_UNIT)?; - self.popen()?; - self.print_tts(&node.tts[..])?; - self.pclose()?; - word(&mut self.s, ";")?; - self.end()?; + try!(self.print_visibility(&item.vis)); + try!(self.print_path(&node.path, false, 0)); + try!(word(&mut self.s, "! ")); + try!(self.print_ident(item.ident)); + try!(self.cbox(INDENT_UNIT)); + try!(self.popen()); + try!(self.print_tts(&node.tts[..])); + try!(self.pclose()); + try!(word(&mut self.s, ";")); + try!(self.end()); } } self.ann.post(self, NodeItem(item)) @@ -1331,22 +1331,22 @@ impl<'a> State<'a> { fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> { if !lifetimes.is_empty() { - word(&mut self.s, "for<")?; + try!(word(&mut self.s, "for<")); let mut comma = false; for lifetime_def in lifetimes { if comma { - self.word_space(",")? + try!(self.word_space(",")) } - self.print_lifetime_def(lifetime_def)?; + try!(self.print_lifetime_def(lifetime_def)); comma = true; } - word(&mut self.s, ">")?; + try!(word(&mut self.s, ">")); } Ok(()) } fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> { - self.print_formal_lifetime_list(&t.bound_lifetimes)?; + try!(self.print_formal_lifetime_list(&t.bound_lifetimes)); self.print_trait_ref(&t.trait_ref) } @@ -1354,27 +1354,27 @@ impl<'a> State<'a> { generics: &ast::Generics, ident: ast::Ident, span: codemap::Span, visibility: &ast::Visibility) -> io::Result<()> { - self.head(&visibility_qualified(visibility, "enum"))?; - self.print_ident(ident)?; - self.print_generics(generics)?; - self.print_where_clause(&generics.where_clause)?; - space(&mut self.s)?; + try!(self.head(&visibility_qualified(visibility, "enum"))); + try!(self.print_ident(ident)); + try!(self.print_generics(generics)); + try!(self.print_where_clause(&generics.where_clause)); + try!(space(&mut self.s)); self.print_variants(&enum_definition.variants, span) } pub fn print_variants(&mut self, variants: &[ast::Variant], span: codemap::Span) -> io::Result<()> { - self.bopen()?; + try!(self.bopen()); for v in variants { - self.space_if_not_bol()?; - self.maybe_print_comment(v.span.lo)?; - self.print_outer_attributes(&v.node.attrs)?; - self.ibox(INDENT_UNIT)?; - self.print_variant(v)?; - word(&mut self.s, ",")?; - self.end()?; - self.maybe_print_trailing_comment(v.span, None)?; + try!(self.space_if_not_bol()); + try!(self.maybe_print_comment(v.span.lo)); + try!(self.print_outer_attributes(&v.node.attrs)); + try!(self.ibox(INDENT_UNIT)); + try!(self.print_variant(v)); + try!(word(&mut self.s, ",")); + try!(self.end()); + try!(self.maybe_print_trailing_comment(v.span, None)); } self.bclose(span) } @@ -1395,42 +1395,43 @@ impl<'a> State<'a> { ident: ast::Ident, span: codemap::Span, print_finalizer: bool) -> io::Result<()> { - self.print_ident(ident)?; - self.print_generics(generics)?; + try!(self.print_ident(ident)); + try!(self.print_generics(generics)); if !struct_def.is_struct() { if struct_def.is_tuple() { - self.popen()?; - self.commasep( + try!(self.popen()); + try!(self.commasep( Inconsistent, struct_def.fields(), |s, field| { - s.print_visibility(&field.vis)?; - s.maybe_print_comment(field.span.lo)?; + try!(s.maybe_print_comment(field.span.lo)); + try!(s.print_outer_attributes(&field.attrs)); + try!(s.print_visibility(&field.vis)); s.print_type(&field.ty) } - )?; - self.pclose()?; + )); + try!(self.pclose()); } - self.print_where_clause(&generics.where_clause)?; + try!(self.print_where_clause(&generics.where_clause)); if print_finalizer { - word(&mut self.s, ";")?; + try!(word(&mut self.s, ";")); } - self.end()?; + try!(self.end()); self.end() // close the outer-box } else { - self.print_where_clause(&generics.where_clause)?; - self.nbsp()?; - self.bopen()?; - self.hardbreak_if_not_bol()?; + try!(self.print_where_clause(&generics.where_clause)); + try!(self.nbsp()); + try!(self.bopen()); + try!(self.hardbreak_if_not_bol()); for field in struct_def.fields() { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(field.span.lo)?; - self.print_outer_attributes(&field.attrs)?; - self.print_visibility(&field.vis)?; - self.print_ident(field.ident.unwrap())?; - self.word_nbsp(":")?; - self.print_type(&field.ty)?; - word(&mut self.s, ",")?; + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(field.span.lo)); + try!(self.print_outer_attributes(&field.attrs)); + try!(self.print_visibility(&field.vis)); + try!(self.print_ident(field.ident.unwrap())); + try!(self.word_nbsp(":")); + try!(self.print_type(&field.ty)); + try!(word(&mut self.s, ",")); } self.bclose(span) @@ -1447,7 +1448,7 @@ impl<'a> State<'a> { pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> { match *tt { TokenTree::Token(_, ref tk) => { - word(&mut self.s, &token_to_string(tk))?; + try!(word(&mut self.s, &token_to_string(tk))); match *tk { parse::token::DocComment(..) => { hardbreak(&mut self.s) @@ -1456,21 +1457,21 @@ impl<'a> State<'a> { } } TokenTree::Delimited(_, ref delimed) => { - word(&mut self.s, &token_to_string(&delimed.open_token()))?; - space(&mut self.s)?; - self.print_tts(&delimed.tts)?; - space(&mut self.s)?; + try!(word(&mut self.s, &token_to_string(&delimed.open_token()))); + try!(space(&mut self.s)); + try!(self.print_tts(&delimed.tts)); + try!(space(&mut self.s)); word(&mut self.s, &token_to_string(&delimed.close_token())) }, TokenTree::Sequence(_, ref seq) => { - word(&mut self.s, "$(")?; + try!(word(&mut self.s, "$(")); for tt_elt in &seq.tts { - self.print_tt(tt_elt)?; + try!(self.print_tt(tt_elt)); } - word(&mut self.s, ")")?; + try!(word(&mut self.s, ")")); match seq.separator { Some(ref tk) => { - word(&mut self.s, &token_to_string(tk))?; + try!(word(&mut self.s, &token_to_string(tk))); } None => {}, } @@ -1483,24 +1484,24 @@ impl<'a> State<'a> { } pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> { - self.ibox(0)?; + try!(self.ibox(0)); for (i, tt) in tts.iter().enumerate() { if i != 0 { - space(&mut self.s)?; + try!(space(&mut self.s)); } - self.print_tt(tt)?; + try!(self.print_tt(tt)); } self.end() } pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> { - self.head("")?; + try!(self.head("")); let generics = ast::Generics::default(); - self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; + try!(self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)); match v.node.disr_expr { Some(ref d) => { - space(&mut self.s)?; - self.word_space("=")?; + try!(space(&mut self.s)); + try!(self.word_space("=")); self.print_expr(&d) } _ => Ok(()) @@ -1523,103 +1524,103 @@ impl<'a> State<'a> { pub fn print_trait_item(&mut self, ti: &ast::TraitItem) -> io::Result<()> { - self.ann.pre(self, NodeSubItem(ti.id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ti.span.lo)?; - self.print_outer_attributes(&ti.attrs)?; + try!(self.ann.pre(self, NodeSubItem(ti.id))); + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(ti.span.lo)); + try!(self.print_outer_attributes(&ti.attrs)); match ti.node { ast::TraitItemKind::Const(ref ty, ref default) => { - self.print_associated_const(ti.ident, &ty, + try!(self.print_associated_const(ti.ident, &ty, default.as_ref().map(|expr| &**expr), - &ast::Visibility::Inherited)?; + &ast::Visibility::Inherited)); } ast::TraitItemKind::Method(ref sig, ref body) => { if body.is_some() { - self.head("")?; + try!(self.head("")); } - self.print_method_sig(ti.ident, sig, &ast::Visibility::Inherited)?; + try!(self.print_method_sig(ti.ident, sig, &ast::Visibility::Inherited)); if let Some(ref body) = *body { - self.nbsp()?; - self.print_block_with_attrs(body, &ti.attrs)?; + try!(self.nbsp()); + try!(self.print_block_with_attrs(body, &ti.attrs)); } else { - word(&mut self.s, ";")?; + try!(word(&mut self.s, ";")); } } ast::TraitItemKind::Type(ref bounds, ref default) => { - self.print_associated_type(ti.ident, Some(bounds), - default.as_ref().map(|ty| &**ty))?; + try!(self.print_associated_type(ti.ident, Some(bounds), + default.as_ref().map(|ty| &**ty))); } } self.ann.post(self, NodeSubItem(ti.id)) } pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> { - self.ann.pre(self, NodeSubItem(ii.id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ii.span.lo)?; - self.print_outer_attributes(&ii.attrs)?; + try!(self.ann.pre(self, NodeSubItem(ii.id))); + try!(self.hardbreak_if_not_bol()); + try!(self.maybe_print_comment(ii.span.lo)); + try!(self.print_outer_attributes(&ii.attrs)); if let ast::Defaultness::Default = ii.defaultness { - self.word_nbsp("default")?; + try!(self.word_nbsp("default")); } match ii.node { ast::ImplItemKind::Const(ref ty, ref expr) => { - self.print_associated_const(ii.ident, &ty, Some(&expr), &ii.vis)?; + try!(self.print_associated_const(ii.ident, &ty, Some(&expr), &ii.vis)); } ast::ImplItemKind::Method(ref sig, ref body) => { - self.head("")?; - self.print_method_sig(ii.ident, sig, &ii.vis)?; - self.nbsp()?; - self.print_block_with_attrs(body, &ii.attrs)?; + try!(self.head("")); + try!(self.print_method_sig(ii.ident, sig, &ii.vis)); + try!(self.nbsp()); + try!(self.print_block_with_attrs(body, &ii.attrs)); } ast::ImplItemKind::Type(ref ty) => { - self.print_associated_type(ii.ident, None, Some(ty))?; + try!(self.print_associated_type(ii.ident, None, Some(ty))); } ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => { // code copied from ItemKind::Mac: - self.print_path(&node.path, false, 0)?; - word(&mut self.s, "! ")?; - self.cbox(INDENT_UNIT)?; - self.popen()?; - self.print_tts(&node.tts[..])?; - self.pclose()?; - word(&mut self.s, ";")?; - self.end()? + try!(self.print_path(&node.path, false, 0)); + try!(word(&mut self.s, "! ")); + try!(self.cbox(INDENT_UNIT)); + try!(self.popen()); + try!(self.print_tts(&node.tts[..])); + try!(self.pclose()); + try!(word(&mut self.s, ";")); + try!(self.end()) } } self.ann.post(self, NodeSubItem(ii.id)) } pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> { - self.maybe_print_comment(st.span.lo)?; + try!(self.maybe_print_comment(st.span.lo)); match st.node { ast::StmtKind::Decl(ref decl, _) => { - self.print_decl(&decl)?; + try!(self.print_decl(&decl)); } ast::StmtKind::Expr(ref expr, _) => { - self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + try!(self.space_if_not_bol()); + try!(self.print_expr_outer_attr_style(&expr, false)); } ast::StmtKind::Semi(ref expr, _) => { - self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; - word(&mut self.s, ";")?; + try!(self.space_if_not_bol()); + try!(self.print_expr_outer_attr_style(&expr, false)); + try!(word(&mut self.s, ";")); } ast::StmtKind::Mac(ref mac, style, ref attrs) => { - self.space_if_not_bol()?; - self.print_outer_attributes(attrs.as_attr_slice())?; + try!(self.space_if_not_bol()); + try!(self.print_outer_attributes(attrs.as_attr_slice())); let delim = match style { ast::MacStmtStyle::Braces => token::Brace, _ => token::Paren }; - self.print_mac(&mac, delim)?; + try!(self.print_mac(&mac, delim)); match style { ast::MacStmtStyle::Braces => {} - _ => word(&mut self.s, ";")?, + _ => try!(word(&mut self.s, ";")), } } } if parse::classify::stmt_ends_with_semi(&st.node) { - word(&mut self.s, ";")?; + try!(word(&mut self.s, ";")); } self.maybe_print_trailing_comment(st.span, None) } @@ -1655,27 +1656,27 @@ impl<'a> State<'a> { attrs: &[ast::Attribute], close_box: bool) -> io::Result<()> { match blk.rules { - BlockCheckMode::Unsafe(..) => self.word_space("unsafe")?, + BlockCheckMode::Unsafe(..) => try!(self.word_space("unsafe")), BlockCheckMode::Default => () } - self.maybe_print_comment(blk.span.lo)?; - self.ann.pre(self, NodeBlock(blk))?; - self.bopen()?; + try!(self.maybe_print_comment(blk.span.lo)); + try!(self.ann.pre(self, NodeBlock(blk))); + try!(self.bopen()); - self.print_inner_attributes(attrs)?; + try!(self.print_inner_attributes(attrs)); for st in &blk.stmts { - self.print_stmt(st)?; + try!(self.print_stmt(st)); } match blk.expr { Some(ref expr) => { - self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; - self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?; + try!(self.space_if_not_bol()); + try!(self.print_expr_outer_attr_style(&expr, false)); + try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))); } _ => () } - self.bclose_maybe_open(blk.span, indented, close_box)?; + try!(self.bclose_maybe_open(blk.span, indented, close_box)); self.ann.post(self, NodeBlock(blk)) } @@ -1685,32 +1686,32 @@ impl<'a> State<'a> { match _else.node { // "another else-if" ast::ExprKind::If(ref i, ref then, ref e) => { - self.cbox(INDENT_UNIT - 1)?; - self.ibox(0)?; - word(&mut self.s, " else if ")?; - self.print_expr(&i)?; - space(&mut self.s)?; - self.print_block(&then)?; + try!(self.cbox(INDENT_UNIT - 1)); + try!(self.ibox(0)); + try!(word(&mut self.s, " else if ")); + try!(self.print_expr(&i)); + try!(space(&mut self.s)); + try!(self.print_block(&then)); self.print_else(e.as_ref().map(|e| &**e)) } // "another else-if-let" ast::ExprKind::IfLet(ref pat, ref expr, ref then, ref e) => { - self.cbox(INDENT_UNIT - 1)?; - self.ibox(0)?; - word(&mut self.s, " else if let ")?; - self.print_pat(&pat)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&expr)?; - space(&mut self.s)?; - self.print_block(&then)?; + try!(self.cbox(INDENT_UNIT - 1)); + try!(self.ibox(0)); + try!(word(&mut self.s, " else if let ")); + try!(self.print_pat(&pat)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_expr(&expr)); + try!(space(&mut self.s)); + try!(self.print_block(&then)); self.print_else(e.as_ref().map(|e| &**e)) } // "final else" ast::ExprKind::Block(ref b) => { - self.cbox(INDENT_UNIT - 1)?; - self.ibox(0)?; - word(&mut self.s, " else ")?; + try!(self.cbox(INDENT_UNIT - 1)); + try!(self.ibox(0)); + try!(word(&mut self.s, " else ")); self.print_block(&b) } // BLEAH, constraints would be great here @@ -1725,38 +1726,38 @@ impl<'a> State<'a> { pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block, elseopt: Option<&ast::Expr>) -> io::Result<()> { - self.head("if")?; - self.print_expr(test)?; - space(&mut self.s)?; - self.print_block(blk)?; + try!(self.head("if")); + try!(self.print_expr(test)); + try!(space(&mut self.s)); + try!(self.print_block(blk)); self.print_else(elseopt) } pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block, elseopt: Option<&ast::Expr>) -> io::Result<()> { - self.head("if let")?; - self.print_pat(pat)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(expr)?; - space(&mut self.s)?; - self.print_block(blk)?; + try!(self.head("if let")); + try!(self.print_pat(pat)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_expr(expr)); + try!(space(&mut self.s)); + try!(self.print_block(blk)); self.print_else(elseopt) } pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) -> io::Result<()> { - self.print_path(&m.node.path, false, 0)?; - word(&mut self.s, "!")?; + try!(self.print_path(&m.node.path, false, 0)); + try!(word(&mut self.s, "!")); match delim { - token::Paren => self.popen()?, - token::Bracket => word(&mut self.s, "[")?, + token::Paren => try!(self.popen()), + token::Bracket => try!(word(&mut self.s, "[")), token::Brace => { - self.head("")?; - self.bopen()?; + try!(self.head("")); + try!(self.bopen()); } } - self.print_tts(&m.node.tts)?; + try!(self.print_tts(&m.node.tts)); match delim { token::Paren => self.pclose(), token::Bracket => word(&mut self.s, "]"), @@ -1766,8 +1767,8 @@ impl<'a> State<'a> { fn print_call_post(&mut self, args: &[P]) -> io::Result<()> { - self.popen()?; - self.commasep_exprs(Inconsistent, args)?; + try!(self.popen()); + try!(self.commasep_exprs(Inconsistent, args)); self.pclose() } @@ -1789,11 +1790,11 @@ impl<'a> State<'a> { pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> { let needs_par = needs_parentheses(expr); if needs_par { - self.popen()?; + try!(self.popen()); } - self.print_expr(expr)?; + try!(self.print_expr(expr)); if needs_par { - self.pclose()?; + try!(self.pclose()); } Ok(()) } @@ -1801,19 +1802,19 @@ impl<'a> State<'a> { fn print_expr_in_place(&mut self, place: &ast::Expr, expr: &ast::Expr) -> io::Result<()> { - self.print_expr_maybe_paren(place)?; - space(&mut self.s)?; - self.word_space("<-")?; + try!(self.print_expr_maybe_paren(place)); + try!(space(&mut self.s)); + try!(self.word_space("<-")); self.print_expr_maybe_paren(expr) } fn print_expr_vec(&mut self, exprs: &[P], attrs: &[Attribute]) -> io::Result<()> { - self.ibox(INDENT_UNIT)?; - word(&mut self.s, "[")?; - self.print_inner_attributes_inline(attrs)?; - self.commasep_exprs(Inconsistent, &exprs[..])?; - word(&mut self.s, "]")?; + try!(self.ibox(INDENT_UNIT)); + try!(word(&mut self.s, "[")); + try!(self.print_inner_attributes_inline(attrs)); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); + try!(word(&mut self.s, "]")); self.end() } @@ -1821,13 +1822,13 @@ impl<'a> State<'a> { element: &ast::Expr, count: &ast::Expr, attrs: &[Attribute]) -> io::Result<()> { - self.ibox(INDENT_UNIT)?; - word(&mut self.s, "[")?; - self.print_inner_attributes_inline(attrs)?; - self.print_expr(element)?; - self.word_space(";")?; - self.print_expr(count)?; - word(&mut self.s, "]")?; + try!(self.ibox(INDENT_UNIT)); + try!(word(&mut self.s, "[")); + try!(self.print_inner_attributes_inline(attrs)); + try!(self.print_expr(element)); + try!(self.word_space(";")); + try!(self.print_expr(count)); + try!(word(&mut self.s, "]")); self.end() } @@ -1836,46 +1837,46 @@ impl<'a> State<'a> { fields: &[ast::Field], wth: &Option>, attrs: &[Attribute]) -> io::Result<()> { - self.print_path(path, true, 0)?; - word(&mut self.s, "{")?; - self.print_inner_attributes_inline(attrs)?; - self.commasep_cmnt( + try!(self.print_path(path, true, 0)); + try!(word(&mut self.s, "{")); + try!(self.print_inner_attributes_inline(attrs)); + try!(self.commasep_cmnt( Consistent, &fields[..], |s, field| { - s.ibox(INDENT_UNIT)?; - s.print_ident(field.ident.node)?; - s.word_space(":")?; - s.print_expr(&field.expr)?; + try!(s.ibox(INDENT_UNIT)); + try!(s.print_ident(field.ident.node)); + try!(s.word_space(":")); + try!(s.print_expr(&field.expr)); s.end() }, - |f| f.span)?; + |f| f.span)); match *wth { Some(ref expr) => { - self.ibox(INDENT_UNIT)?; + try!(self.ibox(INDENT_UNIT)); if !fields.is_empty() { - word(&mut self.s, ",")?; - space(&mut self.s)?; + try!(word(&mut self.s, ",")); + try!(space(&mut self.s)); } - word(&mut self.s, "..")?; - self.print_expr(&expr)?; - self.end()?; + try!(word(&mut self.s, "..")); + try!(self.print_expr(&expr)); + try!(self.end()); } _ => if !fields.is_empty() { - word(&mut self.s, ",")? + try!(word(&mut self.s, ",")) } } - word(&mut self.s, "}")?; + try!(word(&mut self.s, "}")); Ok(()) } fn print_expr_tup(&mut self, exprs: &[P], attrs: &[Attribute]) -> io::Result<()> { - self.popen()?; - self.print_inner_attributes_inline(attrs)?; - self.commasep_exprs(Inconsistent, &exprs[..])?; + try!(self.popen()); + try!(self.print_inner_attributes_inline(attrs)); + try!(self.commasep_exprs(Inconsistent, &exprs[..])); if exprs.len() == 1 { - word(&mut self.s, ",")?; + try!(word(&mut self.s, ",")); } self.pclose() } @@ -1883,7 +1884,7 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, args: &[P]) -> io::Result<()> { - self.print_expr_maybe_paren(func)?; + try!(self.print_expr_maybe_paren(func)); self.print_call_post(args) } @@ -1892,14 +1893,14 @@ impl<'a> State<'a> { tys: &[P], args: &[P]) -> io::Result<()> { let base_args = &args[1..]; - self.print_expr(&args[0])?; - word(&mut self.s, ".")?; - self.print_ident(ident.node)?; + try!(self.print_expr(&args[0])); + try!(word(&mut self.s, ".")); + try!(self.print_ident(ident.node)); if !tys.is_empty() { - word(&mut self.s, "::<")?; - self.commasep(Inconsistent, tys, - |s, ty| s.print_type(&ty))?; - word(&mut self.s, ">")?; + try!(word(&mut self.s, "::<")); + try!(self.commasep(Inconsistent, tys, + |s, ty| s.print_type(&ty))); + try!(word(&mut self.s, ">")); } self.print_call_post(base_args) } @@ -1909,12 +1910,12 @@ impl<'a> State<'a> { lhs: &ast::Expr, rhs: &ast::Expr) -> io::Result<()> { if self.check_expr_bin_needs_paren(lhs, op) { - self.print_expr_maybe_paren(lhs)?; + try!(self.print_expr_maybe_paren(lhs)); } else { - self.print_expr(lhs)?; + try!(self.print_expr(lhs)); } - space(&mut self.s)?; - self.word_space(op.node.to_string())?; + try!(space(&mut self.s)); + try!(self.word_space(op.node.to_string())); if self.check_expr_bin_needs_paren(rhs, op) { self.print_expr_maybe_paren(rhs) } else { @@ -1925,15 +1926,15 @@ impl<'a> State<'a> { fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) -> io::Result<()> { - word(&mut self.s, ast::UnOp::to_string(op))?; + try!(word(&mut self.s, ast::UnOp::to_string(op))); self.print_expr_maybe_paren(expr) } fn print_expr_addr_of(&mut self, mutability: ast::Mutability, expr: &ast::Expr) -> io::Result<()> { - word(&mut self.s, "&")?; - self.print_mutability(mutability)?; + try!(word(&mut self.s, "&")); + try!(self.print_mutability(mutability)); self.print_expr_maybe_paren(expr) } @@ -1944,139 +1945,139 @@ impl<'a> State<'a> { fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline: bool) -> io::Result<()> { - self.maybe_print_comment(expr.span.lo)?; + try!(self.maybe_print_comment(expr.span.lo)); let attrs = expr.attrs.as_attr_slice(); if is_inline { - self.print_outer_attributes_inline(attrs)?; + try!(self.print_outer_attributes_inline(attrs)); } else { - self.print_outer_attributes(attrs)?; + try!(self.print_outer_attributes(attrs)); } - self.ibox(INDENT_UNIT)?; - self.ann.pre(self, NodeExpr(expr))?; + try!(self.ibox(INDENT_UNIT)); + try!(self.ann.pre(self, NodeExpr(expr))); match expr.node { ast::ExprKind::Box(ref expr) => { - self.word_space("box")?; - self.print_expr(expr)?; + try!(self.word_space("box")); + try!(self.print_expr(expr)); } ast::ExprKind::InPlace(ref place, ref expr) => { - self.print_expr_in_place(place, expr)?; + try!(self.print_expr_in_place(place, expr)); } ast::ExprKind::Vec(ref exprs) => { - self.print_expr_vec(&exprs[..], attrs)?; + try!(self.print_expr_vec(&exprs[..], attrs)); } ast::ExprKind::Repeat(ref element, ref count) => { - self.print_expr_repeat(&element, &count, attrs)?; + try!(self.print_expr_repeat(&element, &count, attrs)); } ast::ExprKind::Struct(ref path, ref fields, ref wth) => { - self.print_expr_struct(path, &fields[..], wth, attrs)?; + try!(self.print_expr_struct(path, &fields[..], wth, attrs)); } ast::ExprKind::Tup(ref exprs) => { - self.print_expr_tup(&exprs[..], attrs)?; + try!(self.print_expr_tup(&exprs[..], attrs)); } ast::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(&func, &args[..])?; + try!(self.print_expr_call(&func, &args[..])); } ast::ExprKind::MethodCall(ident, ref tys, ref args) => { - self.print_expr_method_call(ident, &tys[..], &args[..])?; + try!(self.print_expr_method_call(ident, &tys[..], &args[..])); } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, &lhs, &rhs)?; + try!(self.print_expr_binary(op, &lhs, &rhs)); } ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, &expr)?; + try!(self.print_expr_unary(op, &expr)); } ast::ExprKind::AddrOf(m, ref expr) => { - self.print_expr_addr_of(m, &expr)?; + try!(self.print_expr_addr_of(m, &expr)); } ast::ExprKind::Lit(ref lit) => { - self.print_literal(&lit)?; + try!(self.print_literal(&lit)); } ast::ExprKind::Cast(ref expr, ref ty) => { if let ast::ExprKind::Cast(..) = expr.node { - self.print_expr(&expr)?; + try!(self.print_expr(&expr)); } else { - self.print_expr_maybe_paren(&expr)?; + try!(self.print_expr_maybe_paren(&expr)); } - space(&mut self.s)?; - self.word_space("as")?; - self.print_type(&ty)?; + try!(space(&mut self.s)); + try!(self.word_space("as")); + try!(self.print_type(&ty)); } ast::ExprKind::Type(ref expr, ref ty) => { - self.print_expr(&expr)?; - self.word_space(":")?; - self.print_type(&ty)?; + try!(self.print_expr(&expr)); + try!(self.word_space(":")); + try!(self.print_type(&ty)); } ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; + try!(self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))); } ast::ExprKind::IfLet(ref pat, ref expr, ref blk, ref elseopt) => { - self.print_if_let(&pat, &expr, &blk, elseopt.as_ref().map(|e| &**e))?; + try!(self.print_if_let(&pat, &expr, &blk, elseopt.as_ref().map(|e| &**e))); } ast::ExprKind::While(ref test, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - self.word_space(":")?; + try!(self.print_ident(ident.node)); + try!(self.word_space(":")); } - self.head("while")?; - self.print_expr(&test)?; - space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + try!(self.head("while")); + try!(self.print_expr(&test)); + try!(space(&mut self.s)); + try!(self.print_block_with_attrs(&blk, attrs)); } ast::ExprKind::WhileLet(ref pat, ref expr, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - self.word_space(":")?; + try!(self.print_ident(ident.node)); + try!(self.word_space(":")); } - self.head("while let")?; - self.print_pat(&pat)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&expr)?; - space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + try!(self.head("while let")); + try!(self.print_pat(&pat)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_expr(&expr)); + try!(space(&mut self.s)); + try!(self.print_block_with_attrs(&blk, attrs)); } ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - self.word_space(":")?; + try!(self.print_ident(ident.node)); + try!(self.word_space(":")); } - self.head("for")?; - self.print_pat(&pat)?; - space(&mut self.s)?; - self.word_space("in")?; - self.print_expr(&iter)?; - space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + try!(self.head("for")); + try!(self.print_pat(&pat)); + try!(space(&mut self.s)); + try!(self.word_space("in")); + try!(self.print_expr(&iter)); + try!(space(&mut self.s)); + try!(self.print_block_with_attrs(&blk, attrs)); } ast::ExprKind::Loop(ref blk, opt_ident) => { if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - self.word_space(":")?; + try!(self.print_ident(ident.node)); + try!(self.word_space(":")); } - self.head("loop")?; - space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + try!(self.head("loop")); + try!(space(&mut self.s)); + try!(self.print_block_with_attrs(&blk, attrs)); } ast::ExprKind::Match(ref expr, ref arms) => { - self.cbox(INDENT_UNIT)?; - self.ibox(4)?; - self.word_nbsp("match")?; - self.print_expr(&expr)?; - space(&mut self.s)?; - self.bopen()?; - self.print_inner_attributes_no_trailing_hardbreak(attrs)?; + try!(self.cbox(INDENT_UNIT)); + try!(self.ibox(4)); + try!(self.word_nbsp("match")); + try!(self.print_expr(&expr)); + try!(space(&mut self.s)); + try!(self.bopen()); + try!(self.print_inner_attributes_no_trailing_hardbreak(attrs)); for arm in arms { - self.print_arm(arm)?; + try!(self.print_arm(arm)); } - self.bclose_(expr.span, INDENT_UNIT)?; + try!(self.bclose_(expr.span, INDENT_UNIT)); } ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => { - self.print_capture_clause(capture_clause)?; + try!(self.print_capture_clause(capture_clause)); - self.print_fn_block_args(&decl)?; - space(&mut self.s)?; + try!(self.print_fn_block_args(&decl)); + try!(space(&mut self.s)); let default_return = match decl.output { ast::FunctionRetTy::Default(..) => true, @@ -2084,150 +2085,150 @@ impl<'a> State<'a> { }; if !default_return || !body.stmts.is_empty() || body.expr.is_none() { - self.print_block_unclosed(&body)?; + try!(self.print_block_unclosed(&body)); } else { // we extract the block, so as not to create another set of boxes let i_expr = body.expr.as_ref().unwrap(); match i_expr.node { ast::ExprKind::Block(ref blk) => { - self.print_block_unclosed_with_attrs( + try!(self.print_block_unclosed_with_attrs( &blk, - i_expr.attrs.as_attr_slice())?; + i_expr.attrs.as_attr_slice())); } _ => { // this is a bare expression - self.print_expr(&i_expr)?; - self.end()?; // need to close a box + try!(self.print_expr(&i_expr)); + try!(self.end()); // need to close a box } } } // a box will be closed by print_expr, but we didn't want an overall // wrapper so we closed the corresponding opening. so create an // empty box to satisfy the close. - self.ibox(0)?; + try!(self.ibox(0)); } ast::ExprKind::Block(ref blk) => { // containing cbox, will be closed by print-block at } - self.cbox(INDENT_UNIT)?; + try!(self.cbox(INDENT_UNIT)); // head-box, will be closed by print-block after { - self.ibox(0)?; - self.print_block_with_attrs(&blk, attrs)?; + try!(self.ibox(0)); + try!(self.print_block_with_attrs(&blk, attrs)); } ast::ExprKind::Assign(ref lhs, ref rhs) => { - self.print_expr(&lhs)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&rhs)?; + try!(self.print_expr(&lhs)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_expr(&rhs)); } ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { - self.print_expr(&lhs)?; - space(&mut self.s)?; - word(&mut self.s, op.node.to_string())?; - self.word_space("=")?; - self.print_expr(&rhs)?; + try!(self.print_expr(&lhs)); + try!(space(&mut self.s)); + try!(word(&mut self.s, op.node.to_string())); + try!(self.word_space("=")); + try!(self.print_expr(&rhs)); } ast::ExprKind::Field(ref expr, id) => { - self.print_expr(&expr)?; - word(&mut self.s, ".")?; - self.print_ident(id.node)?; + try!(self.print_expr(&expr)); + try!(word(&mut self.s, ".")); + try!(self.print_ident(id.node)); } ast::ExprKind::TupField(ref expr, id) => { - self.print_expr(&expr)?; - word(&mut self.s, ".")?; - self.print_usize(id.node)?; + try!(self.print_expr(&expr)); + try!(word(&mut self.s, ".")); + try!(self.print_usize(id.node)); } ast::ExprKind::Index(ref expr, ref index) => { - self.print_expr(&expr)?; - word(&mut self.s, "[")?; - self.print_expr(&index)?; - word(&mut self.s, "]")?; + try!(self.print_expr(&expr)); + try!(word(&mut self.s, "[")); + try!(self.print_expr(&index)); + try!(word(&mut self.s, "]")); } ast::ExprKind::Range(ref start, ref end, limits) => { if let &Some(ref e) = start { - self.print_expr(&e)?; + try!(self.print_expr(&e)); } if limits == ast::RangeLimits::HalfOpen { - word(&mut self.s, "..")?; + try!(word(&mut self.s, "..")); } else { - word(&mut self.s, "...")?; + try!(word(&mut self.s, "...")); } if let &Some(ref e) = end { - self.print_expr(&e)?; + try!(self.print_expr(&e)); } } ast::ExprKind::Path(None, ref path) => { - self.print_path(path, true, 0)? + try!(self.print_path(path, true, 0)) } ast::ExprKind::Path(Some(ref qself), ref path) => { - self.print_qpath(path, qself, true)? + try!(self.print_qpath(path, qself, true)) } ast::ExprKind::Break(opt_ident) => { - word(&mut self.s, "break")?; - space(&mut self.s)?; + try!(word(&mut self.s, "break")); + try!(space(&mut self.s)); if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - space(&mut self.s)?; + try!(self.print_ident(ident.node)); + try!(space(&mut self.s)); } } ast::ExprKind::Again(opt_ident) => { - word(&mut self.s, "continue")?; - space(&mut self.s)?; + try!(word(&mut self.s, "continue")); + try!(space(&mut self.s)); if let Some(ident) = opt_ident { - self.print_ident(ident.node)?; - space(&mut self.s)? + try!(self.print_ident(ident.node)); + try!(space(&mut self.s)) } } ast::ExprKind::Ret(ref result) => { - word(&mut self.s, "return")?; + try!(word(&mut self.s, "return")); match *result { Some(ref expr) => { - word(&mut self.s, " ")?; - self.print_expr(&expr)?; + try!(word(&mut self.s, " ")); + try!(self.print_expr(&expr)); } _ => () } } ast::ExprKind::InlineAsm(ref a) => { - word(&mut self.s, "asm!")?; - self.popen()?; - self.print_string(&a.asm, a.asm_str_style)?; - self.word_space(":")?; + try!(word(&mut self.s, "asm!")); + try!(self.popen()); + try!(self.print_string(&a.asm, a.asm_str_style)); + try!(self.word_space(":")); - self.commasep(Inconsistent, &a.outputs, + try!(self.commasep(Inconsistent, &a.outputs, |s, out| { let mut ch = out.constraint.chars(); match ch.next() { Some('=') if out.is_rw => { - s.print_string(&format!("+{}", ch.as_str()), - ast::StrStyle::Cooked)? + try!(s.print_string(&format!("+{}", ch.as_str()), + ast::StrStyle::Cooked)) } - _ => s.print_string(&out.constraint, - ast::StrStyle::Cooked)? + _ => try!(s.print_string(&out.constraint, + ast::StrStyle::Cooked)) } - s.popen()?; - s.print_expr(&out.expr)?; - s.pclose()?; + try!(s.popen()); + try!(s.print_expr(&out.expr)); + try!(s.pclose()); Ok(()) - })?; - space(&mut self.s)?; - self.word_space(":")?; + })); + try!(space(&mut self.s)); + try!(self.word_space(":")); - self.commasep(Inconsistent, &a.inputs, + try!(self.commasep(Inconsistent, &a.inputs, |s, &(ref co, ref o)| { - s.print_string(&co, ast::StrStyle::Cooked)?; - s.popen()?; - s.print_expr(&o)?; - s.pclose()?; + try!(s.print_string(&co, ast::StrStyle::Cooked)); + try!(s.popen()); + try!(s.print_expr(&o)); + try!(s.pclose()); Ok(()) - })?; - space(&mut self.s)?; - self.word_space(":")?; + })); + try!(space(&mut self.s)); + try!(self.word_space(":")); - self.commasep(Inconsistent, &a.clobbers, + try!(self.commasep(Inconsistent, &a.clobbers, |s, co| { - s.print_string(&co, ast::StrStyle::Cooked)?; + try!(s.print_string(&co, ast::StrStyle::Cooked)); Ok(()) - })?; + })); let mut options = vec!(); if a.volatile { @@ -2241,58 +2242,58 @@ impl<'a> State<'a> { } if !options.is_empty() { - space(&mut self.s)?; - self.word_space(":")?; - self.commasep(Inconsistent, &options, + try!(space(&mut self.s)); + try!(self.word_space(":")); + try!(self.commasep(Inconsistent, &options, |s, &co| { - s.print_string(co, ast::StrStyle::Cooked)?; + try!(s.print_string(co, ast::StrStyle::Cooked)); Ok(()) - })?; + })); } - self.pclose()?; + try!(self.pclose()); } - ast::ExprKind::Mac(ref m) => self.print_mac(m, token::Paren)?, + ast::ExprKind::Mac(ref m) => try!(self.print_mac(m, token::Paren)), ast::ExprKind::Paren(ref e) => { - self.popen()?; - self.print_inner_attributes_inline(attrs)?; - self.print_expr(&e)?; - self.pclose()?; + try!(self.popen()); + try!(self.print_inner_attributes_inline(attrs)); + try!(self.print_expr(&e)); + try!(self.pclose()); }, ast::ExprKind::Try(ref e) => { - self.print_expr(e)?; - word(&mut self.s, "?")? + try!(self.print_expr(e)); + try!(word(&mut self.s, "?")) } } - self.ann.post(self, NodeExpr(expr))?; + try!(self.ann.post(self, NodeExpr(expr))); self.end() } pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> { - self.print_pat(&loc.pat)?; + try!(self.print_pat(&loc.pat)); if let Some(ref ty) = loc.ty { - self.word_space(":")?; - self.print_type(&ty)?; + try!(self.word_space(":")); + try!(self.print_type(&ty)); } Ok(()) } pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> { - self.maybe_print_comment(decl.span.lo)?; + try!(self.maybe_print_comment(decl.span.lo)); match decl.node { ast::DeclKind::Local(ref loc) => { - self.print_outer_attributes(loc.attrs.as_attr_slice())?; - self.space_if_not_bol()?; - self.ibox(INDENT_UNIT)?; - self.word_nbsp("let")?; - - self.ibox(INDENT_UNIT)?; - self.print_local_decl(&loc)?; - self.end()?; + try!(self.print_outer_attributes(loc.attrs.as_attr_slice())); + try!(self.space_if_not_bol()); + try!(self.ibox(INDENT_UNIT)); + try!(self.word_nbsp("let")); + + try!(self.ibox(INDENT_UNIT)); + try!(self.print_local_decl(&loc)); + try!(self.end()); if let Some(ref init) = loc.init { - self.nbsp()?; - self.word_space("=")?; - self.print_expr(&init)?; + try!(self.nbsp()); + try!(self.word_space("=")); + try!(self.print_expr(&init)); } self.end() } @@ -2301,7 +2302,7 @@ impl<'a> State<'a> { } pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { - word(&mut self.s, &ident.name.as_str())?; + try!(word(&mut self.s, &ident.name.as_str())); self.ann.post(self, NodeIdent(&ident)) } @@ -2310,15 +2311,15 @@ impl<'a> State<'a> { } pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { - word(&mut self.s, &name.as_str())?; + try!(word(&mut self.s, &name.as_str())); self.ann.post(self, NodeName(&name)) } pub fn print_for_decl(&mut self, loc: &ast::Local, coll: &ast::Expr) -> io::Result<()> { - self.print_local_decl(loc)?; - space(&mut self.s)?; - self.word_space("in")?; + try!(self.print_local_decl(loc)); + try!(space(&mut self.s)); + try!(self.word_space("in")); self.print_expr(coll) } @@ -2328,19 +2329,19 @@ impl<'a> State<'a> { depth: usize) -> io::Result<()> { - self.maybe_print_comment(path.span.lo)?; + try!(self.maybe_print_comment(path.span.lo)); let mut first = !path.global; for segment in &path.segments[..path.segments.len()-depth] { if first { first = false } else { - word(&mut self.s, "::")? + try!(word(&mut self.s, "::")) } - self.print_ident(segment.identifier)?; + try!(self.print_ident(segment.identifier)); - self.print_path_parameters(&segment.parameters, colons_before_params)?; + try!(self.print_path_parameters(&segment.parameters, colons_before_params)); } Ok(()) @@ -2352,18 +2353,18 @@ impl<'a> State<'a> { colons_before_params: bool) -> io::Result<()> { - word(&mut self.s, "<")?; - self.print_type(&qself.ty)?; + try!(word(&mut self.s, "<")); + try!(self.print_type(&qself.ty)); if qself.position > 0 { - space(&mut self.s)?; - self.word_space("as")?; + try!(space(&mut self.s)); + try!(self.word_space("as")); let depth = path.segments.len() - qself.position; - self.print_path(&path, false, depth)?; + try!(self.print_path(&path, false, depth)); } - word(&mut self.s, ">")?; - word(&mut self.s, "::")?; + try!(word(&mut self.s, ">")); + try!(word(&mut self.s, "::")); let item_segment = path.segments.last().unwrap(); - self.print_ident(item_segment.identifier)?; + try!(self.print_ident(item_segment.identifier)); self.print_path_parameters(&item_segment.parameters, colons_before_params) } @@ -2377,61 +2378,61 @@ impl<'a> State<'a> { } if colons_before_params { - word(&mut self.s, "::")? + try!(word(&mut self.s, "::")) } match *parameters { ast::PathParameters::AngleBracketed(ref data) => { - word(&mut self.s, "<")?; + try!(word(&mut self.s, "<")); let mut comma = false; for lifetime in &data.lifetimes { if comma { - self.word_space(",")? + try!(self.word_space(",")) } - self.print_lifetime(lifetime)?; + try!(self.print_lifetime(lifetime)); comma = true; } if !data.types.is_empty() { if comma { - self.word_space(",")? + try!(self.word_space(",")) } - self.commasep( + try!(self.commasep( Inconsistent, &data.types, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(&ty))); comma = true; } for binding in data.bindings.iter() { if comma { - self.word_space(",")? + try!(self.word_space(",")) } - self.print_ident(binding.ident)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&binding.ty)?; + try!(self.print_ident(binding.ident)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_type(&binding.ty)); comma = true; } - word(&mut self.s, ">")? + try!(word(&mut self.s, ">")) } ast::PathParameters::Parenthesized(ref data) => { - word(&mut self.s, "(")?; - self.commasep( + try!(word(&mut self.s, "(")); + try!(self.commasep( Inconsistent, &data.inputs, - |s, ty| s.print_type(&ty))?; - word(&mut self.s, ")")?; + |s, ty| s.print_type(&ty))); + try!(word(&mut self.s, ")")); match data.output { None => { } Some(ref ty) => { - self.space_if_not_bol()?; - self.word_space("->")?; - self.print_type(&ty)?; + try!(self.space_if_not_bol()); + try!(self.word_space("->")); + try!(self.print_type(&ty)); } } } @@ -2441,136 +2442,133 @@ impl<'a> State<'a> { } pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> { - self.maybe_print_comment(pat.span.lo)?; - self.ann.pre(self, NodePat(pat))?; + try!(self.maybe_print_comment(pat.span.lo)); + try!(self.ann.pre(self, NodePat(pat))); /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ match pat.node { - PatKind::Wild => word(&mut self.s, "_")?, + PatKind::Wild => try!(word(&mut self.s, "_")), PatKind::Ident(binding_mode, ref path1, ref sub) => { match binding_mode { ast::BindingMode::ByRef(mutbl) => { - self.word_nbsp("ref")?; - self.print_mutability(mutbl)?; + try!(self.word_nbsp("ref")); + try!(self.print_mutability(mutbl)); } ast::BindingMode::ByValue(ast::Mutability::Immutable) => {} ast::BindingMode::ByValue(ast::Mutability::Mutable) => { - self.word_nbsp("mut")?; + try!(self.word_nbsp("mut")); } } - self.print_ident(path1.node)?; - match *sub { - Some(ref p) => { - word(&mut self.s, "@")?; - self.print_pat(&p)?; - } - None => () + try!(self.print_ident(path1.node)); + if let Some(ref p) = *sub { + try!(word(&mut self.s, "@")); + try!(self.print_pat(&p)); } } PatKind::TupleStruct(ref path, ref elts, ddpos) => { - self.print_path(path, true, 0)?; - self.popen()?; + try!(self.print_path(path, true, 0)); + try!(self.popen()); if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + try!(self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))); if ddpos != 0 { - self.word_space(",")?; + try!(self.word_space(",")); } - word(&mut self.s, "..")?; + try!(word(&mut self.s, "..")); if ddpos != elts.len() { - word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + try!(word(&mut self.s, ",")); + try!(self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))); } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + try!(self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))); } - self.pclose()?; + try!(self.pclose()); } PatKind::Path(ref path) => { - self.print_path(path, true, 0)?; + try!(self.print_path(path, true, 0)); } PatKind::QPath(ref qself, ref path) => { - self.print_qpath(path, qself, false)?; + try!(self.print_qpath(path, qself, false)); } PatKind::Struct(ref path, ref fields, etc) => { - self.print_path(path, true, 0)?; - self.nbsp()?; - self.word_space("{")?; - self.commasep_cmnt( + try!(self.print_path(path, true, 0)); + try!(self.nbsp()); + try!(self.word_space("{")); + try!(self.commasep_cmnt( Consistent, &fields[..], |s, f| { - s.cbox(INDENT_UNIT)?; + try!(s.cbox(INDENT_UNIT)); if !f.node.is_shorthand { - s.print_ident(f.node.ident)?; - s.word_nbsp(":")?; + try!(s.print_ident(f.node.ident)); + try!(s.word_nbsp(":")); } - s.print_pat(&f.node.pat)?; + try!(s.print_pat(&f.node.pat)); s.end() }, - |f| f.node.pat.span)?; + |f| f.node.pat.span)); if etc { - if !fields.is_empty() { self.word_space(",")?; } - word(&mut self.s, "..")?; + if !fields.is_empty() { try!(self.word_space(",")); } + try!(word(&mut self.s, "..")); } - space(&mut self.s)?; - word(&mut self.s, "}")?; + try!(space(&mut self.s)); + try!(word(&mut self.s, "}")); } PatKind::Tuple(ref elts, ddpos) => { - self.popen()?; + try!(self.popen()); if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + try!(self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))); if ddpos != 0 { - self.word_space(",")?; + try!(self.word_space(",")); } - word(&mut self.s, "..")?; + try!(word(&mut self.s, "..")); if ddpos != elts.len() { - word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + try!(word(&mut self.s, ",")); + try!(self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))); } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + try!(self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))); if elts.len() == 1 { - word(&mut self.s, ",")?; + try!(word(&mut self.s, ",")); } } - self.pclose()?; + try!(self.pclose()); } PatKind::Box(ref inner) => { - word(&mut self.s, "box ")?; - self.print_pat(&inner)?; + try!(word(&mut self.s, "box ")); + try!(self.print_pat(&inner)); } PatKind::Ref(ref inner, mutbl) => { - word(&mut self.s, "&")?; + try!(word(&mut self.s, "&")); if mutbl == ast::Mutability::Mutable { - word(&mut self.s, "mut ")?; + try!(word(&mut self.s, "mut ")); } - self.print_pat(&inner)?; + try!(self.print_pat(&inner)); } - PatKind::Lit(ref e) => self.print_expr(&**e)?, + PatKind::Lit(ref e) => try!(self.print_expr(&**e)), PatKind::Range(ref begin, ref end) => { - self.print_expr(&begin)?; - space(&mut self.s)?; - word(&mut self.s, "...")?; - self.print_expr(&end)?; + try!(self.print_expr(&begin)); + try!(space(&mut self.s)); + try!(word(&mut self.s, "...")); + try!(self.print_expr(&end)); } PatKind::Vec(ref before, ref slice, ref after) => { - word(&mut self.s, "[")?; - self.commasep(Inconsistent, + try!(word(&mut self.s, "[")); + try!(self.commasep(Inconsistent, &before[..], - |s, p| s.print_pat(&p))?; + |s, p| s.print_pat(&p))); if let Some(ref p) = *slice { - if !before.is_empty() { self.word_space(",")?; } + if !before.is_empty() { try!(self.word_space(",")); } if p.node != PatKind::Wild { - self.print_pat(&p)?; + try!(self.print_pat(&p)); } - word(&mut self.s, "..")?; - if !after.is_empty() { self.word_space(",")?; } + try!(word(&mut self.s, "..")); + if !after.is_empty() { try!(self.word_space(",")); } } - self.commasep(Inconsistent, + try!(self.commasep(Inconsistent, &after[..], - |s, p| s.print_pat(&p))?; - word(&mut self.s, "]")?; + |s, p| s.print_pat(&p))); + try!(word(&mut self.s, "]")); } - PatKind::Mac(ref m) => self.print_mac(m, token::Paren)?, + PatKind::Mac(ref m) => try!(self.print_mac(m, token::Paren)), } self.ann.post(self, NodePat(pat)) } @@ -2579,43 +2577,43 @@ impl<'a> State<'a> { // I have no idea why this check is necessary, but here it // is :( if arm.attrs.is_empty() { - space(&mut self.s)?; + try!(space(&mut self.s)); } - self.cbox(INDENT_UNIT)?; - self.ibox(0)?; - self.print_outer_attributes(&arm.attrs)?; + try!(self.cbox(INDENT_UNIT)); + try!(self.ibox(0)); + try!(self.print_outer_attributes(&arm.attrs)); let mut first = true; for p in &arm.pats { if first { first = false; } else { - space(&mut self.s)?; - self.word_space("|")?; + try!(space(&mut self.s)); + try!(self.word_space("|")); } - self.print_pat(&p)?; + try!(self.print_pat(&p)); } - space(&mut self.s)?; + try!(space(&mut self.s)); if let Some(ref e) = arm.guard { - self.word_space("if")?; - self.print_expr(&e)?; - space(&mut self.s)?; + try!(self.word_space("if")); + try!(self.print_expr(&e)); + try!(space(&mut self.s)); } - self.word_space("=>")?; + try!(self.word_space("=>")); match arm.body.node { ast::ExprKind::Block(ref blk) => { // the block will close the pattern's ibox - self.print_block_unclosed_indent(&blk, INDENT_UNIT)?; + try!(self.print_block_unclosed_indent(&blk, INDENT_UNIT)); // If it is a user-provided unsafe block, print a comma after it if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules { - word(&mut self.s, ",")?; + try!(word(&mut self.s, ",")); } } _ => { - self.end()?; // close the ibox for the pattern - self.print_expr(&arm.body)?; - word(&mut self.s, ",")?; + try!(self.end()); // close the ibox for the pattern + try!(self.print_expr(&arm.body)); + try!(word(&mut self.s, ",")); } } self.end() // close enclosing cbox @@ -2624,19 +2622,19 @@ impl<'a> State<'a> { fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) -> io::Result<()> { match explicit_self.node { SelfKind::Value(m) => { - self.print_mutability(m)?; + try!(self.print_mutability(m)); word(&mut self.s, "self") } SelfKind::Region(ref lt, m) => { - word(&mut self.s, "&")?; - self.print_opt_lifetime(lt)?; - self.print_mutability(m)?; + try!(word(&mut self.s, "&")); + try!(self.print_opt_lifetime(lt)); + try!(self.print_mutability(m)); word(&mut self.s, "self") } SelfKind::Explicit(ref typ, m) => { - self.print_mutability(m)?; - word(&mut self.s, "self")?; - self.word_space(":")?; + try!(self.print_mutability(m)); + try!(word(&mut self.s, "self")); + try!(self.word_space(":")); self.print_type(&typ) } } @@ -2650,25 +2648,25 @@ impl<'a> State<'a> { name: Option, generics: &ast::Generics, vis: &ast::Visibility) -> io::Result<()> { - self.print_fn_header_info(unsafety, constness, abi, vis)?; + try!(self.print_fn_header_info(unsafety, constness, abi, vis)); if let Some(name) = name { - self.nbsp()?; - self.print_ident(name)?; + try!(self.nbsp()); + try!(self.print_ident(name)); } - self.print_generics(generics)?; - self.print_fn_args_and_ret(decl)?; + try!(self.print_generics(generics)); + try!(self.print_fn_args_and_ret(decl)); self.print_where_clause(&generics.where_clause) } pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl) -> io::Result<()> { - self.popen()?; - self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))?; + try!(self.popen()); + try!(self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false))); if decl.variadic { - word(&mut self.s, ", ...")?; + try!(word(&mut self.s, ", ...")); } - self.pclose()?; + try!(self.pclose()); self.print_fn_output(decl) } @@ -2677,24 +2675,24 @@ impl<'a> State<'a> { &mut self, decl: &ast::FnDecl) -> io::Result<()> { - word(&mut self.s, "|")?; - self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))?; - word(&mut self.s, "|")?; + try!(word(&mut self.s, "|")); + try!(self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true))); + try!(word(&mut self.s, "|")); if let ast::FunctionRetTy::Default(..) = decl.output { return Ok(()); } - self.space_if_not_bol()?; - self.word_space("->")?; + try!(self.space_if_not_bol()); + try!(self.word_space("->")); match decl.output { ast::FunctionRetTy::Ty(ref ty) => { - self.print_type(&ty)?; + try!(self.print_type(&ty)); self.maybe_print_comment(ty.span.lo) } ast::FunctionRetTy::Default(..) => unreachable!(), ast::FunctionRetTy::None(span) => { - self.word_nbsp("!")?; + try!(self.word_nbsp("!")); self.maybe_print_comment(span.lo) } } @@ -2713,28 +2711,28 @@ impl<'a> State<'a> { bounds: &[ast::TyParamBound]) -> io::Result<()> { if !bounds.is_empty() { - word(&mut self.s, prefix)?; + try!(word(&mut self.s, prefix)); let mut first = true; for bound in bounds { - self.nbsp()?; + try!(self.nbsp()); if first { first = false; } else { - self.word_space("+")?; + try!(self.word_space("+")); } - match *bound { + try!(match *bound { TraitTyParamBound(ref tref, TraitBoundModifier::None) => { self.print_poly_trait_ref(tref) } TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => { - word(&mut self.s, "?")?; + try!(word(&mut self.s, "?")); self.print_poly_trait_ref(tref) } RegionTyParamBound(ref lt) => { self.print_lifetime(lt) } - }? + }) } Ok(()) } else { @@ -2753,11 +2751,11 @@ impl<'a> State<'a> { lifetime: &ast::LifetimeDef) -> io::Result<()> { - self.print_lifetime(&lifetime.lifetime)?; + try!(self.print_lifetime(&lifetime.lifetime)); let mut sep = ":"; for v in &lifetime.bounds { - word(&mut self.s, sep)?; - self.print_lifetime(v)?; + try!(word(&mut self.s, sep)); + try!(self.print_lifetime(v)); sep = "+"; } Ok(()) @@ -2772,14 +2770,14 @@ impl<'a> State<'a> { return Ok(()); } - word(&mut self.s, "<")?; + try!(word(&mut self.s, "<")); let mut ints = Vec::new(); for i in 0..total { ints.push(i); } - self.commasep(Inconsistent, &ints[..], |s, &idx| { + try!(self.commasep(Inconsistent, &ints[..], |s, &idx| { if idx < generics.lifetimes.len() { let lifetime = &generics.lifetimes[idx]; s.print_lifetime_def(lifetime) @@ -2788,19 +2786,19 @@ impl<'a> State<'a> { let param = &generics.ty_params[idx]; s.print_ty_param(param) } - })?; + })); - word(&mut self.s, ">")?; + try!(word(&mut self.s, ">")); Ok(()) } pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> { - self.print_ident(param.ident)?; - self.print_bounds(":", ¶m.bounds)?; + try!(self.print_ident(param.ident)); + try!(self.print_bounds(":", ¶m.bounds)); match param.default { Some(ref default) => { - space(&mut self.s)?; - self.word_space("=")?; + try!(space(&mut self.s)); + try!(self.word_space("=")); self.print_type(&default) } _ => Ok(()) @@ -2813,12 +2811,12 @@ impl<'a> State<'a> { return Ok(()) } - space(&mut self.s)?; - self.word_space("where")?; + try!(space(&mut self.s)); + try!(self.word_space("where")); for (i, predicate) in where_clause.predicates.iter().enumerate() { if i != 0 { - self.word_space(",")?; + try!(self.word_space(",")); } match *predicate { @@ -2826,29 +2824,29 @@ impl<'a> State<'a> { ref bounded_ty, ref bounds, ..}) => { - self.print_formal_lifetime_list(bound_lifetimes)?; - self.print_type(&bounded_ty)?; - self.print_bounds(":", bounds)?; + try!(self.print_formal_lifetime_list(bound_lifetimes)); + try!(self.print_type(&bounded_ty)); + try!(self.print_bounds(":", bounds)); } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime, ref bounds, ..}) => { - self.print_lifetime(lifetime)?; - word(&mut self.s, ":")?; + try!(self.print_lifetime(lifetime)); + try!(word(&mut self.s, ":")); for (i, bound) in bounds.iter().enumerate() { - self.print_lifetime(bound)?; + try!(self.print_lifetime(bound)); if i != 0 { - word(&mut self.s, ":")?; + try!(word(&mut self.s, ":")); } } } ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => { - self.print_path(path, false, 0)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&ty)?; + try!(self.print_path(path, false, 0)); + try!(space(&mut self.s)); + try!(self.word_space("=")); + try!(self.print_type(&ty)); } } } @@ -2859,52 +2857,52 @@ impl<'a> State<'a> { pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { - self.print_path(path, false, 0)?; + try!(self.print_path(path, false, 0)); if path.segments.last().unwrap().identifier.name != ident.name { - space(&mut self.s)?; - self.word_space("as")?; - self.print_ident(ident)?; + try!(space(&mut self.s)); + try!(self.word_space("as")); + try!(self.print_ident(ident)); } Ok(()) } ast::ViewPathGlob(ref path) => { - self.print_path(path, false, 0)?; + try!(self.print_path(path, false, 0)); word(&mut self.s, "::*") } ast::ViewPathList(ref path, ref idents) => { if path.segments.is_empty() { - word(&mut self.s, "{")?; + try!(word(&mut self.s, "{")); } else { - self.print_path(path, false, 0)?; - word(&mut self.s, "::{")?; + try!(self.print_path(path, false, 0)); + try!(word(&mut self.s, "::{")); } - self.commasep(Inconsistent, &idents[..], |s, w| { + try!(self.commasep(Inconsistent, &idents[..], |s, w| { match w.node { ast::PathListItemKind::Ident { name, rename, .. } => { - s.print_ident(name)?; + try!(s.print_ident(name)); if let Some(ident) = rename { - space(&mut s.s)?; - s.word_space("as")?; - s.print_ident(ident)?; + try!(space(&mut s.s)); + try!(s.word_space("as")); + try!(s.print_ident(ident)); } Ok(()) }, ast::PathListItemKind::Mod { rename, .. } => { - word(&mut s.s, "self")?; + try!(word(&mut s.s, "self")); if let Some(ident) = rename { - space(&mut s.s)?; - s.word_space("as")?; - s.print_ident(ident)?; + try!(space(&mut s.s)); + try!(s.word_space("as")); + try!(s.print_ident(ident)); } Ok(()) } } - })?; + })); word(&mut self.s, "}") } } @@ -2919,17 +2917,17 @@ impl<'a> State<'a> { } pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> { - self.print_mutability(mt.mutbl)?; + try!(self.print_mutability(mt.mutbl)); self.print_type(&mt.ty) } pub fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) -> io::Result<()> { - self.ibox(INDENT_UNIT)?; + try!(self.ibox(INDENT_UNIT)); match input.ty.node { - ast::TyKind::Infer if is_closure => self.print_pat(&input.pat)?, + ast::TyKind::Infer if is_closure => try!(self.print_pat(&input.pat)), _ => { if let Some(eself) = input.to_self() { - self.print_explicit_self(&eself)?; + try!(self.print_explicit_self(&eself)); } else { let invalid = if let PatKind::Ident(_, ident, _) = input.pat.node { ident.node.name == keywords::Invalid.name() @@ -2937,11 +2935,11 @@ impl<'a> State<'a> { false }; if !invalid { - self.print_pat(&input.pat)?; - word(&mut self.s, ":")?; - space(&mut self.s)?; + try!(self.print_pat(&input.pat)); + try!(word(&mut self.s, ":")); + try!(space(&mut self.s)); } - self.print_type(&input.ty)?; + try!(self.print_type(&input.ty)); } } } @@ -2953,17 +2951,17 @@ impl<'a> State<'a> { return Ok(()); } - self.space_if_not_bol()?; - self.ibox(INDENT_UNIT)?; - self.word_space("->")?; + try!(self.space_if_not_bol()); + try!(self.ibox(INDENT_UNIT)); + try!(self.word_space("->")); match decl.output { ast::FunctionRetTy::None(_) => - self.word_nbsp("!")?, + try!(self.word_nbsp("!")), ast::FunctionRetTy::Default(..) => unreachable!(), ast::FunctionRetTy::Ty(ref ty) => - self.print_type(&ty)? + try!(self.print_type(&ty)) } - self.end()?; + try!(self.end()); match decl.output { ast::FunctionRetTy::Ty(ref output) => self.maybe_print_comment(output.span.lo), @@ -2978,10 +2976,10 @@ impl<'a> State<'a> { name: Option, generics: &ast::Generics) -> io::Result<()> { - self.ibox(INDENT_UNIT)?; + try!(self.ibox(INDENT_UNIT)); if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { - word(&mut self.s, "for")?; - self.print_generics(generics)?; + try!(word(&mut self.s, "for")); + try!(self.print_generics(generics)); } let generics = ast::Generics { lifetimes: Vec::new(), @@ -2991,13 +2989,13 @@ impl<'a> State<'a> { predicates: Vec::new(), }, }; - self.print_fn(decl, + try!(self.print_fn(decl, unsafety, ast::Constness::NotConst, abi, name, &generics, - &ast::Visibility::Inherited)?; + &ast::Visibility::Inherited)); self.end() } @@ -3008,20 +3006,19 @@ impl<'a> State<'a> { Some(cm) => cm, _ => return Ok(()) }; - match self.next_comment() { - Some(ref cmnt) => { - if (*cmnt).style != comments::Trailing { return Ok(()) } - let span_line = cm.lookup_char_pos(span.hi); - let comment_line = cm.lookup_char_pos((*cmnt).pos); - let mut next = (*cmnt).pos + BytePos(1); - match next_pos { None => (), Some(p) => next = p } - if span.hi < (*cmnt).pos && (*cmnt).pos < next && - span_line.line == comment_line.line { - self.print_comment(cmnt)?; - self.cur_cmnt_and_lit.cur_cmnt += 1; - } + if let Some(ref cmnt) = self.next_comment() { + if (*cmnt).style != comments::Trailing { return Ok(()) } + let span_line = cm.lookup_char_pos(span.hi); + let comment_line = cm.lookup_char_pos((*cmnt).pos); + let mut next = (*cmnt).pos + BytePos(1); + if let Some(p) = next_pos { + next = p; + } + if span.hi < (*cmnt).pos && (*cmnt).pos < next && + span_line.line == comment_line.line { + self.print_comment(cmnt)?; + self.cur_cmnt_and_lit.cur_cmnt += 1; } - _ => () } Ok(()) } @@ -3030,12 +3027,12 @@ impl<'a> State<'a> { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. if self.next_comment().is_none() { - hardbreak(&mut self.s)?; + try!(hardbreak(&mut self.s)); } loop { match self.next_comment() { Some(ref cmnt) => { - self.print_comment(cmnt)?; + try!(self.print_comment(cmnt)); self.cur_cmnt_and_lit.cur_cmnt += 1; } _ => break @@ -3050,7 +3047,7 @@ impl<'a> State<'a> { match opt_abi { Some(Abi::Rust) => Ok(()), Some(abi) => { - self.word_nbsp("extern")?; + try!(self.word_nbsp("extern")); self.word_nbsp(&abi.to_string()) } None => Ok(()) @@ -3061,7 +3058,7 @@ impl<'a> State<'a> { opt_abi: Option) -> io::Result<()> { match opt_abi { Some(abi) => { - self.word_nbsp("extern")?; + try!(self.word_nbsp("extern")); self.word_nbsp(&abi.to_string()) } None => Ok(()) @@ -3073,18 +3070,18 @@ impl<'a> State<'a> { constness: ast::Constness, abi: Abi, vis: &ast::Visibility) -> io::Result<()> { - word(&mut self.s, &visibility_qualified(vis, ""))?; + try!(word(&mut self.s, &visibility_qualified(vis, ""))); match constness { ast::Constness::NotConst => {} - ast::Constness::Const => self.word_nbsp("const")? + ast::Constness::Const => try!(self.word_nbsp("const")) } - self.print_unsafety(unsafety)?; + try!(self.print_unsafety(unsafety)); if abi != Abi::Rust { - self.word_nbsp("extern")?; - self.word_nbsp(&abi.to_string())?; + try!(self.word_nbsp("extern")); + try!(self.word_nbsp(&abi.to_string())); } word(&mut self.s, "fn") diff --git a/syntex_syntax/src/std_inject.rs b/syntex_syntax/src/std_inject.rs index 84a7b144..8834c026 100644 --- a/syntex_syntax/src/std_inject.rs +++ b/syntex_syntax/src/std_inject.rs @@ -12,12 +12,9 @@ use ast; use attr; use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; use codemap; -use fold::Folder; -use fold; use parse::token::{intern, InternedString, keywords}; use parse::{token, ParseSess}; use ptr::P; -use util::small_vector::SmallVector; /// Craft a span that will be ignored by the stability lint's /// call to codemap's is_internal check. @@ -37,33 +34,6 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span { return sp; } -pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option) - -> ast::Crate { - if no_core(&krate) { - krate - } else { - let name = if no_std(&krate) {"core"} else {"std"}; - let mut fold = CrateInjector { - item_name: token::str_to_ident(name), - crate_name: token::intern(&alt_std_name.unwrap_or(name.to_string())), - }; - fold.fold_crate(krate) - } -} - -pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate { - if no_core(&krate) { - krate - } else { - let name = if no_std(&krate) {"core"} else {"std"}; - let mut fold = PreludeInjector { - span: ignored_span(sess, DUMMY_SP), - crate_identifier: token::str_to_ident(name), - }; - fold.fold_crate(krate) - } -} - pub fn no_core(krate: &ast::Crate) -> bool { attr::contains_name(&krate.attrs, "no_core") } @@ -72,102 +42,54 @@ pub fn no_std(krate: &ast::Crate) -> bool { attr::contains_name(&krate.attrs, "no_std") || no_core(krate) } -fn no_prelude(attrs: &[ast::Attribute]) -> bool { - attr::contains_name(attrs, "no_implicit_prelude") -} - -struct CrateInjector { - item_name: ast::Ident, - crate_name: ast::Name, -} - -impl fold::Folder for CrateInjector { - fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { - krate.module.items.insert(0, P(ast::Item { - id: ast::DUMMY_NODE_ID, - ident: self.item_name, - attrs: vec!( - attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item( - InternedString::new("macro_use")))), - node: ast::ItemKind::ExternCrate(Some(self.crate_name)), - vis: ast::Visibility::Inherited, - span: DUMMY_SP - })); - - krate - } -} - -struct PreludeInjector { - span: Span, - crate_identifier: ast::Ident, -} - -impl fold::Folder for PreludeInjector { - fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { - // only add `use std::prelude::*;` if there wasn't a - // `#![no_implicit_prelude]` at the crate level. - // fold_mod() will insert glob path. - if !no_prelude(&krate.attrs) { - krate.module = self.fold_mod(krate.module); - } - krate - } - - fn fold_item(&mut self, item: P) -> SmallVector> { - if !no_prelude(&item.attrs) { - // only recur if there wasn't `#![no_implicit_prelude]` - // on this item, i.e. this means that the prelude is not - // implicitly imported though the whole subtree - fold::noop_fold_item(item, self) - } else { - SmallVector::one(item) - } +pub fn maybe_inject_crates_ref(sess: &ParseSess, + mut krate: ast::Crate, + alt_std_name: Option) + -> ast::Crate { + if no_core(&krate) { + return krate; } - fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod { - let prelude_path = ast::Path { - span: self.span, + let name = if no_std(&krate) { "core" } else { "std" }; + let crate_name = token::intern(&alt_std_name.unwrap_or(name.to_string())); + + krate.module.items.insert(0, P(ast::Item { + attrs: vec![attr::mk_attr_outer(attr::mk_attr_id(), + attr::mk_word_item(InternedString::new("macro_use")))], + vis: ast::Visibility::Inherited, + node: ast::ItemKind::ExternCrate(Some(crate_name)), + ident: token::str_to_ident(name), + id: ast::DUMMY_NODE_ID, + span: DUMMY_SP, + })); + + let span = ignored_span(sess, DUMMY_SP); + krate.module.items.insert(0, P(ast::Item { + attrs: vec![ast::Attribute { + node: ast::Attribute_ { + style: ast::AttrStyle::Outer, + value: P(ast::MetaItem { + node: ast::MetaItemKind::Word(token::intern_and_get_ident("prelude_import")), + span: span, + }), + id: attr::mk_attr_id(), + is_sugared_doc: false, + }, + span: span, + }], + vis: ast::Visibility::Inherited, + node: ast::ItemKind::Use(P(codemap::dummy_spanned(ast::ViewPathGlob(ast::Path { global: false, - segments: vec![ - ast::PathSegment { - identifier: self.crate_identifier, - parameters: ast::PathParameters::none(), - }, - ast::PathSegment { - identifier: token::str_to_ident("prelude"), - parameters: ast::PathParameters::none(), - }, - ast::PathSegment { - identifier: token::str_to_ident("v1"), - parameters: ast::PathParameters::none(), - }, - ], - }; - - let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path))); - mod_.items.insert(0, P(ast::Item { - id: ast::DUMMY_NODE_ID, - ident: keywords::Invalid.ident(), - node: ast::ItemKind::Use(vp), - attrs: vec![ast::Attribute { - span: self.span, - node: ast::Attribute_ { - id: attr::mk_attr_id(), - style: ast::AttrStyle::Outer, - value: P(ast::MetaItem { - span: self.span, - node: ast::MetaItemKind::Word( - token::intern_and_get_ident("prelude_import") - ), - }), - is_sugared_doc: false, - }, - }], - vis: ast::Visibility::Inherited, - span: self.span, - })); - - fold::noop_fold_mod(mod_, self) - } + segments: vec![name, "prelude", "v1"].into_iter().map(|name| ast::PathSegment { + identifier: token::str_to_ident(name), + parameters: ast::PathParameters::none(), + }).collect(), + span: span, + })))), + id: ast::DUMMY_NODE_ID, + ident: keywords::Invalid.ident(), + span: span, + })); + + krate } diff --git a/syntex_syntax/src/test.rs b/syntex_syntax/src/test.rs index 6fbbed2e..ca6ed76d 100644 --- a/syntex_syntax/src/test.rs +++ b/syntex_syntax/src/test.rs @@ -25,7 +25,7 @@ use codemap; use errors; use config; use entry::{self, EntryPointType}; -use ext::base::ExtCtxt; +use ext::base::{ExtCtxt, DummyMacroLoader}; use ext::build::AstBuilder; use ext::expand::ExpansionConfig; use fold::Folder; @@ -81,7 +81,7 @@ pub fn modify_for_testing(sess: &ParseSess, if should_test { generate_test_harness(sess, reexport_test_harness_main, krate, span_diagnostic) } else { - strip_test_functions(krate) + krate } } @@ -270,13 +270,13 @@ fn generate_test_harness(sess: &ParseSess, let mut cleaner = EntryPointCleaner { depth: 0 }; let krate = cleaner.fold_crate(krate); - let mut feature_gated_cfgs = vec![]; + let mut loader = DummyMacroLoader; let mut cx: TestCtxt = TestCtxt { sess: sess, span_diagnostic: sd, ext_cx: ExtCtxt::new(sess, vec![], ExpansionConfig::default("test".to_string()), - &mut feature_gated_cfgs), + &mut loader), path: Vec::new(), testfns: Vec::new(), reexport_test_harness_main: reexport_test_harness_main, @@ -304,19 +304,6 @@ fn generate_test_harness(sess: &ParseSess, return res; } -fn strip_test_functions(krate: ast::Crate) -> ast::Crate { - // When not compiling with --test we should not compile the - // #[test] functions - struct StripTests; - impl config::CfgFolder for StripTests { - fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool { - !attr::contains_name(attrs, "test") && !attr::contains_name(attrs, "bench") - } - } - - StripTests.fold_crate(krate) -} - /// Craft a span that will be ignored by the stability lint's /// call to codemap's is_internal check. /// The expanded code calls some unstable functions in the test crate. diff --git a/syntex_syntax/src/util/interner.rs b/syntex_syntax/src/util/interner.rs index 8e203580..7295b36a 100644 --- a/syntex_syntax/src/util/interner.rs +++ b/syntex_syntax/src/util/interner.rs @@ -47,9 +47,8 @@ impl Interner { pub fn intern(&self, val: T) -> Name { let mut map = self.map.borrow_mut(); - match (*map).get(&val) { - Some(&idx) => return idx, - None => (), + if let Some(&idx) = (*map).get(&val) { + return idx; } let mut vect = self.vect.borrow_mut(); @@ -161,9 +160,8 @@ impl StrInterner { pub fn intern(&self, val: &str) -> Name { let mut map = self.map.borrow_mut(); - match map.get(val) { - Some(&idx) => return idx, - None => (), + if let Some(&idx) = map.get(val) { + return idx; } let new_idx = Name(self.len() as u32); diff --git a/syntex_syntax/src/util/parser_testing.rs b/syntex_syntax/src/util/parser_testing.rs index 8358af69..06264196 100644 --- a/syntex_syntax/src/util/parser_testing.rs +++ b/syntex_syntax/src/util/parser_testing.rs @@ -19,7 +19,7 @@ use std::iter::Peekable; /// Map a string to tts, using a made-up filename: pub fn string_to_tts(source_str: String) -> Vec { let ps = ParseSess::new(); - filemap_to_tts(&ps, ps.codemap().new_filemap("bogofile".to_string(), source_str)) + filemap_to_tts(&ps, ps.codemap().new_filemap("bogofile".to_string(), None, source_str)) } /// Map string to parser (via tts) diff --git a/syntex_syntax/src/util/small_vector.rs b/syntex_syntax/src/util/small_vector.rs index 8b07b21c..893646f1 100644 --- a/syntex_syntax/src/util/small_vector.rs +++ b/syntex_syntax/src/util/small_vector.rs @@ -29,6 +29,16 @@ enum SmallVectorRepr { Many(Vec), } +impl Into> for SmallVector { + fn into(self) -> Vec { + match self.repr { + Zero => Vec::new(), + One(t) => vec![t], + Many(vec) => vec, + } + } +} + impl FromIterator for SmallVector { fn from_iter>(iter: I) -> SmallVector { let mut v = SmallVector::zero(); @@ -136,6 +146,15 @@ impl SmallVector { } pub fn is_empty(&self) -> bool { self.len() == 0 } + + pub fn map U>(self, mut f: F) -> SmallVector { + let repr = match self.repr { + Zero => Zero, + One(t) => One(f(t)), + Many(vec) => Many(vec.into_iter().map(f).collect()), + }; + SmallVector { repr: repr } + } } impl IntoIterator for SmallVector { diff --git a/syntex_syntax/src/visit.rs b/syntex_syntax/src/visit.rs index a1d8e056..07a63177 100644 --- a/syntex_syntax/src/visit.rs +++ b/syntex_syntax/src/visit.rs @@ -185,6 +185,9 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { } pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { + for attr in local.attrs.as_attr_slice() { + visitor.visit_attribute(attr); + } visitor.visit_pat(&local.pat); walk_list!(visitor, visit_ty, &local.ty); walk_list!(visitor, visit_expr, &local.init); @@ -635,6 +638,9 @@ pub fn walk_mac<'v, V: Visitor<'v>>(_: &mut V, _: &'v Mac) { } pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { + for attr in expression.attrs.as_attr_slice() { + visitor.visit_attribute(attr); + } match expression.node { ExprKind::Box(ref subexpression) => { visitor.visit_expr(subexpression)