diff options
| author | Matthew <mjjasper1@gmail.com> | 2017-05-23 14:00:20 +0100 |
|---|---|---|
| committer | Matthew <mjjasper1@gmail.com> | 2017-05-23 14:00:20 +0100 |
| commit | 6627ef228c1396c045b3e9f24edaf66b76516cbd (patch) | |
| tree | fbead309f0165e668a895b2b33ce607aa0f4d2cb /src/libsyntax | |
| parent | 158b085f06a41004ebf36d87afa3548f8b60861a (diff) | |
| parent | 852b7cb91ed44f6cc77f855bd8281da4accbd2fb (diff) | |
| download | rust-6627ef228c1396c045b3e9f24edaf66b76516cbd.tar.gz rust-6627ef228c1396c045b3e9f24edaf66b76516cbd.zip | |
Stabilize in 1.19
Diffstat (limited to 'src/libsyntax')
39 files changed, 896 insertions, 789 deletions
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 97d37266130..82e7cfa0032 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["dylib"] [dependencies] serialize = { path = "../libserialize" } log = "0.3" -rustc_bitflags = { path = "../librustc_bitflags" } +bitflags = "0.8" syntax_pos = { path = "../libsyntax_pos" } rustc_errors = { path = "../librustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 131adfe47af..24ce99208ed 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -715,7 +715,7 @@ impl Stmt { StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, _style, attrs)| { (mac, MacStmtStyle::Semicolon, attrs) })), - node @ _ => node, + node => node, }; self } @@ -1076,16 +1076,16 @@ impl LitKind { pub fn is_unsuffixed(&self) -> bool { match *self { // unsuffixed variants - LitKind::Str(..) => true, - LitKind::ByteStr(..) => true, - LitKind::Byte(..) => true, - LitKind::Char(..) => true, - LitKind::Int(_, LitIntType::Unsuffixed) => true, - LitKind::FloatUnsuffixed(..) => true, + LitKind::Str(..) | + LitKind::ByteStr(..) | + LitKind::Byte(..) | + LitKind::Char(..) | + LitKind::Int(_, LitIntType::Unsuffixed) | + LitKind::FloatUnsuffixed(..) | LitKind::Bool(..) => true, // suffixed variants - LitKind::Int(_, LitIntType::Signed(..)) => false, - LitKind::Int(_, LitIntType::Unsigned(..)) => false, + LitKind::Int(_, LitIntType::Signed(..)) | + LitKind::Int(_, LitIntType::Unsigned(..)) | LitKind::Float(..) => false, } } @@ -1852,6 +1852,7 @@ pub enum ItemKind { /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }` Impl(Unsafety, ImplPolarity, + Defaultness, Generics, Option<TraitRef>, // (optional) trait this impl implements P<Ty>, // self diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 82492d97627..45f891d8dc5 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -112,7 +112,7 @@ impl NestedMetaItem { /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem. pub fn meta_item(&self) -> Option<&MetaItem> { match self.node { - NestedMetaItemKind::MetaItem(ref item) => Some(&item), + NestedMetaItemKind::MetaItem(ref item) => Some(item), _ => None } } @@ -120,7 +120,7 @@ impl NestedMetaItem { /// Returns the Lit if self is a NestedMetaItemKind::Literal. pub fn literal(&self) -> Option<&Lit> { match self.node { - NestedMetaItemKind::Literal(ref lit) => Some(&lit), + NestedMetaItemKind::Literal(ref lit) => Some(lit), _ => None } } @@ -259,7 +259,7 @@ impl MetaItem { match self.node { MetaItemKind::NameValue(ref v) => { match v.node { - LitKind::Str(ref s, _) => Some((*s).clone()), + LitKind::Str(ref s, _) => Some(*s), _ => None, } }, @@ -511,8 +511,7 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Symb } else { struct_span_err!(diag, attr.span, E0558, "export_name attribute has invalid format") - .span_label(attr.span, - &format!("did you mean #[export_name=\"*\"]?")) + .span_label(attr.span, "did you mean #[export_name=\"*\"]?") .emit(); None } @@ -1218,9 +1217,10 @@ impl LitKind { Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) } LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None), - LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(match value { - true => "true", - false => "false", + LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value { + "true" + } else { + "false" }))), } } @@ -1262,7 +1262,7 @@ impl<T: HasAttrs> HasAttrs for Spanned<T> { impl HasAttrs for Vec<Attribute> { fn attrs(&self) -> &[Attribute] { - &self + self } fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self { f(self) @@ -1271,7 +1271,7 @@ impl HasAttrs for Vec<Attribute> { impl HasAttrs for ThinVec<Attribute> { fn attrs(&self) -> &[Attribute] { - &self + self } fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self { f(self.into()).into() diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index da2d0a33d1a..d32c3ec5f46 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -21,8 +21,8 @@ pub use syntax_pos::*; pub use syntax_pos::hygiene::{ExpnFormat, ExpnInfo, NameAndSpan}; pub use self::ExpnFormat::*; -use std::cell::RefCell; -use std::path::{Path,PathBuf}; +use std::cell::{RefCell, Ref}; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::env; @@ -103,33 +103,69 @@ impl FileLoader for RealFileLoader { // pub struct CodeMap { - pub files: RefCell<Vec<Rc<FileMap>>>, - file_loader: Box<FileLoader> + // The `files` field should not be visible outside of libsyntax so that we + // can do proper dependency tracking. + pub(super) files: RefCell<Vec<Rc<FileMap>>>, + file_loader: Box<FileLoader>, + // This is used to apply the file path remapping as specified via + // -Zremap-path-prefix to all FileMaps allocated within this CodeMap. + path_mapping: FilePathMapping, + // The CodeMap will invoke this callback whenever a specific FileMap is + // accessed. The callback starts out as a no-op but when the dependency + // graph becomes available later during the compilation process, it is + // be replaced with something that notifies the dep-tracking system. + dep_tracking_callback: RefCell<Box<Fn(&FileMap)>>, } impl CodeMap { - pub fn new() -> CodeMap { + pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), - file_loader: Box::new(RealFileLoader) + file_loader: Box::new(RealFileLoader), + path_mapping: path_mapping, + dep_tracking_callback: RefCell::new(Box::new(|_| {})), } } - pub fn with_file_loader(file_loader: Box<FileLoader>) -> CodeMap { + pub fn with_file_loader(file_loader: Box<FileLoader>, + path_mapping: FilePathMapping) + -> CodeMap { CodeMap { files: RefCell::new(Vec::new()), - file_loader: file_loader + file_loader: file_loader, + path_mapping: path_mapping, + dep_tracking_callback: RefCell::new(Box::new(|_| {})), } } + pub fn path_mapping(&self) -> &FilePathMapping { + &self.path_mapping + } + + pub fn set_dep_tracking_callback(&self, cb: Box<Fn(&FileMap)>) { + *self.dep_tracking_callback.borrow_mut() = cb; + } + pub fn file_exists(&self, path: &Path) -> bool { self.file_loader.file_exists(path) } pub fn load_file(&self, path: &Path) -> io::Result<Rc<FileMap>> { let src = self.file_loader.read_file(path)?; - 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)) + Ok(self.new_filemap(path.to_str().unwrap().to_string(), src)) + } + + pub fn files(&self) -> Ref<Vec<Rc<FileMap>>> { + let files = self.files.borrow(); + for file in files.iter() { + (self.dep_tracking_callback.borrow())(file); + } + files + } + + /// Only use this if you do your own dependency tracking! + pub fn files_untracked(&self) -> Ref<Vec<Rc<FileMap>>> { + self.files.borrow() } fn next_start_pos(&self) -> usize { @@ -144,8 +180,7 @@ 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, abs_path: Option<FileName>, - mut src: String) -> Rc<FileMap> { + pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc<FileMap> { let start_pos = self.next_start_pos(); let mut files = self.files.borrow_mut(); @@ -156,9 +191,12 @@ impl CodeMap { let end_pos = start_pos + src.len(); + let (filename, was_remapped) = self.path_mapping.map_prefix(filename); + let filemap = Rc::new(FileMap { name: filename, - abs_path: abs_path, + name_was_remapped: was_remapped, + crate_of_origin: 0, src: Some(Rc::new(src)), start_pos: Pos::from_usize(start_pos), end_pos: Pos::from_usize(end_pos), @@ -172,11 +210,8 @@ impl CodeMap { } /// Creates a new filemap and sets its line information. - pub fn new_filemap_and_lines(&self, filename: &str, abs_path: Option<&str>, - src: &str) -> Rc<FileMap> { - let fm = self.new_filemap(filename.to_string(), - abs_path.map(|s| s.to_owned()), - src.to_owned()); + pub fn new_filemap_and_lines(&self, filename: &str, src: &str) -> Rc<FileMap> { + let fm = self.new_filemap(filename.to_string(), src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; for line in src.lines() { // register the start of this line @@ -195,7 +230,8 @@ impl CodeMap { /// information for things inlined from other crates. pub fn new_imported_filemap(&self, filename: FileName, - abs_path: Option<FileName>, + name_was_remapped: bool, + crate_of_origin: u32, source_len: usize, mut file_local_lines: Vec<BytePos>, mut file_local_multibyte_chars: Vec<MultiByteChar>) @@ -216,7 +252,8 @@ impl CodeMap { let filemap = Rc::new(FileMap { name: filename, - abs_path: abs_path, + name_was_remapped: name_was_remapped, + crate_of_origin: crate_of_origin, src: None, start_pos: start_pos, end_pos: end_pos, @@ -274,6 +311,8 @@ impl CodeMap { let files = self.files.borrow(); let f = (*files)[idx].clone(); + (self.dep_tracking_callback.borrow())(&f); + match f.lookup_line(pos) { Some(line) => Ok(FileMapAndLine { fm: f, line: line }), None => Err(f) @@ -446,7 +485,7 @@ impl CodeMap { match self.span_to_snippet(sp) { Ok(snippet) => { let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right(); - if snippet.len() > 0 && !snippet.contains('\n') { + if !snippet.is_empty() && !snippet.contains('\n') { Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp } } else { sp @@ -463,6 +502,7 @@ impl CodeMap { pub fn get_filemap(&self, filename: &str) -> Option<Rc<FileMap>> { for fm in self.files.borrow().iter() { if filename == fm.name { + (self.dep_tracking_callback.borrow())(fm); return Some(fm.clone()); } } @@ -473,6 +513,7 @@ impl CodeMap { pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); let fm = (*self.files.borrow())[idx].clone(); + (self.dep_tracking_callback.borrow())(&fm); let offset = bpos - fm.start_pos; FileMapAndBytePos {fm: fm, pos: offset} } @@ -483,6 +524,8 @@ impl CodeMap { let files = self.files.borrow(); let map = &(*files)[idx]; + (self.dep_tracking_callback.borrow())(map); + // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; @@ -528,7 +571,7 @@ impl CodeMap { } pub fn count_lines(&self) -> usize { - self.files.borrow().iter().fold(0, |a, f| a + f.count_lines()) + self.files().iter().fold(0, |a, f| a + f.count_lines()) } } @@ -550,6 +593,42 @@ impl CodeMapper for CodeMap { } } +#[derive(Clone)] +pub struct FilePathMapping { + mapping: Vec<(String, String)>, +} + +impl FilePathMapping { + pub fn empty() -> FilePathMapping { + FilePathMapping { + mapping: vec![] + } + } + + pub fn new(mapping: Vec<(String, String)>) -> FilePathMapping { + FilePathMapping { + mapping: mapping + } + } + + /// Applies any path prefix substitution as defined by the mapping. + /// The return value is the remapped path and a boolean indicating whether + /// the path was affected by the mapping. + pub fn map_prefix(&self, path: String) -> (String, bool) { + // NOTE: We are iterating over the mapping entries from last to first + // because entries specified later on the command line should + // take precedence. + for &(ref from, ref to) in self.mapping.iter().rev() { + if path.starts_with(from) { + let mapped = path.replacen(from, to, 1); + return (mapped, true); + } + } + + (path, false) + } +} + // _____________________________________________________________________________ // Tests // @@ -561,9 +640,8 @@ mod tests { #[test] fn t1 () { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); 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. @@ -578,9 +656,8 @@ mod tests { #[test] #[should_panic] fn t2 () { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); 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)); @@ -589,15 +666,12 @@ mod tests { } fn init_code_map() -> CodeMap { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); 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)); @@ -656,14 +730,12 @@ mod tests { } fn init_code_map_mbc() -> CodeMap { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); // € 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)); @@ -728,10 +800,10 @@ mod tests { /// lines in the middle of a file. #[test] fn span_to_snippet_and_lines_spanning_multiple_lines() { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n"; let selection = " \n ~~\n~~~\n~~~~~ \n \n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); + cm.new_filemap_and_lines("blork.rs", inputtext); let span = span_from_selection(inputtext, selection); // check that we are extracting the text we thought we were extracting @@ -770,11 +842,11 @@ mod tests { /// Test failing to merge two spans on different lines #[test] fn span_merging_fail() { - let cm = CodeMap::new(); + let cm = CodeMap::new(FilePathMapping::empty()); let inputtext = "bbbb BB\ncc CCC\n"; let selection1 = " ~~\n \n"; let selection2 = " \n ~~~\n"; - cm.new_filemap_and_lines("blork.rs", None, inputtext); + cm.new_filemap_and_lines("blork.rs", inputtext); let span1 = span_from_selection(inputtext, selection1); let span2 = span_from_selection(inputtext, selection2); diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index ede8a33df65..2e98c7d9626 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -123,7 +123,7 @@ impl<'a> StripUnconfigured<'a> { return false; } - let mis = if !is_cfg(&attr) { + let mis = if !is_cfg(attr) { return true; } else if let Some(mis) = attr.meta_item_list() { mis @@ -150,7 +150,7 @@ impl<'a> StripUnconfigured<'a> { // flag the offending attributes for attr in attrs.iter() { if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { - let mut err = feature_err(&self.sess, + let mut err = feature_err(self.sess, "stmt_expr_attributes", attr.span, GateIssue::Language, @@ -258,7 +258,7 @@ impl<'a> StripUnconfigured<'a> { pub fn configure_struct_expr_field(&mut self, field: ast::Field) -> Option<ast::Field> { if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { if !field.attrs.is_empty() { - let mut err = feature_err(&self.sess, + let mut err = feature_err(self.sess, "struct_field_attributes", field.span, GateIssue::Language, @@ -290,7 +290,7 @@ impl<'a> StripUnconfigured<'a> { for attr in attrs.iter() { if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { let mut err = feature_err( - &self.sess, + self.sess, "struct_field_attributes", attr.span, GateIssue::Language, diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index fe5cb87ad59..73aeb40df84 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -120,7 +120,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, // URLs can be unavoidably longer than the line limit, so we allow them. // Allowed format is: `[name]: https://www.rust-lang.org/` - let is_url = |l: &str| l.starts_with('[') && l.contains("]:") && l.contains("http"); + let is_url = |l: &str| l.starts_with("[") && l.contains("]:") && l.contains("http"); if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH && !is_url(line)) { ecx.span_err(span, &format!( @@ -177,7 +177,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, if let Err(e) = output_metadata(ecx, &target_triple, &crate_name.name.as_str(), - &diagnostics) { + diagnostics) { ecx.span_bug(span, &format!( "error writing metadata for triple `{}` and crate `{}`, error: {}, \ cause: {:?}", @@ -227,7 +227,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, MacEager::items(SmallVector::many(vec![ P(ast::Item { - ident: name.clone(), + ident: *name, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemKind::Const( diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index fda026fec64..1930f61121b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -24,6 +24,7 @@ use ptr::P; use symbol::Symbol; use util::small_vector::SmallVector; +use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; use std::default::Default; @@ -534,7 +535,7 @@ pub enum SyntaxExtension { /// /// The `bool` dictates whether the contents of the macro can /// directly use `#[unstable]` things (true == yes). - NormalTT(Box<TTMacroExpander>, Option<Span>, bool), + NormalTT(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>, bool), /// A function-like syntax extension that has an extra ident before /// the block. @@ -588,6 +589,7 @@ pub trait Resolver { -> Result<Option<Rc<SyntaxExtension>>, Determinacy>; fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result<Rc<SyntaxExtension>, Determinacy>; + fn check_unused_macros(&self); } #[derive(Copy, Clone, Debug)] @@ -617,6 +619,7 @@ impl Resolver for DummyResolver { _force: bool) -> Result<Rc<SyntaxExtension>, Determinacy> { Err(Determinacy::Determined) } + fn check_unused_macros(&self) {} } #[derive(Clone)] @@ -634,8 +637,8 @@ pub struct ExpansionData { } /// 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. +/// when a macro expansion occurs, the resulting nodes have the `backtrace() +/// -> expn_info` of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub ecfg: expand::ExpansionConfig<'a>, @@ -643,6 +646,7 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut Resolver, pub resolve_err_count: usize, pub current_expansion: ExpansionData, + pub expansions: HashMap<Span, Vec<String>>, } impl<'a> ExtCtxt<'a> { @@ -662,6 +666,7 @@ impl<'a> ExtCtxt<'a> { module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned, }, + expansions: HashMap::new(), } } @@ -695,7 +700,7 @@ impl<'a> ExtCtxt<'a> { /// Returns span for the macro which originally caused the current expansion to happen. /// /// Stops backtracing at include! boundary. - pub fn expansion_cause(&self) -> Span { + pub fn expansion_cause(&self) -> Option<Span> { let mut ctxt = self.backtrace(); let mut last_macro = None; loop { @@ -706,12 +711,12 @@ impl<'a> ExtCtxt<'a> { } ctxt = info.call_site.ctxt; last_macro = Some(info.call_site); - return Some(()); + Some(()) }).is_none() { break } } - last_macro.expect("missing expansion backtrace") + last_macro } pub fn struct_span_warn(&self, @@ -765,6 +770,15 @@ impl<'a> ExtCtxt<'a> { pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } + pub fn trace_macros_diag(&self) { + for (sp, notes) in self.expansions.iter() { + let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro"); + for note in notes { + db.note(note); + } + db.emit(); + } + } pub fn bug(&self, msg: &str) -> ! { self.parse_sess.span_diagnostic.bug(msg); } @@ -783,11 +797,15 @@ impl<'a> ExtCtxt<'a> { v.push(self.ident_of(s)); } v.extend(components.iter().map(|s| self.ident_of(s))); - return v + v } pub fn name_of(&self, st: &str) -> ast::Name { Symbol::intern(st) } + + pub fn check_unused_macros(&self) { + self.resolver.check_unused_macros(); + } } /// Extract a string literal from the macro expanded version of `expr`, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index e0fb46ff5eb..09f22e8691e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -52,7 +52,7 @@ pub trait AstBuilder { fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy; fn ty(&self, span: Span, ty: ast::TyKind) -> P<ast::Ty>; - fn ty_path(&self, ast::Path) -> P<ast::Ty>; + fn ty_path(&self, path: ast::Path) -> P<ast::Ty>; fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>; fn ty_rptr(&self, span: Span, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 842398ea02b..25e0aed220a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -231,7 +231,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }, _ => unreachable!(), }; - + self.cx.trace_macros_diag(); krate } @@ -415,19 +415,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { MultiModifier(ref mac) => { - let meta = panictry!(attr.parse_meta(&self.cx.parse_sess)); + let meta = panictry!(attr.parse_meta(self.cx.parse_sess)); let item = mac.expand(self.cx, attr.span, &meta, item); kind.expect_from_annotatables(item) } MultiDecorator(ref mac) => { let mut items = Vec::new(); - let meta = panictry!(attr.parse_meta(&self.cx.parse_sess)); + let meta = panictry!(attr.parse_meta(self.cx.parse_sess)); mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); items.push(item); kind.expect_from_annotatables(items) } SyntaxExtension::AttrProcMacro(ref mac) => { - let item_toks = stream_for_item(&item, &self.cx.parse_sess); + let item_toks = stream_for_item(&item, self.cx.parse_sess); let span = Span { ctxt: self.cx.backtrace(), ..attr.span }; let tok_result = mac.expand(self.cx, attr.span, attr.tokens, item_toks); @@ -439,7 +439,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => { let msg = &format!("macro `{}` may not be used in attributes", attr.path); - self.cx.span_err(attr.span, &msg); + self.cx.span_err(attr.span, msg); kind.dummy(attr.span) } } @@ -454,7 +454,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let path = &mac.node.path; - let ident = ident.unwrap_or(keywords::Invalid.ident()); + let ident = ident.unwrap_or_else(|| keywords::Invalid.ident()); let marked_tts = noop_fold_tts(mac.node.stream(), &mut Marker(mark)); let opt_expanded = match *ext { NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { @@ -469,7 +469,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { call_site: span, callee: NameAndSpan { format: MacroBang(Symbol::intern(&format!("{}", path))), - span: exp_span, + span: exp_span.map(|(_, s)| s), allow_internal_unstable: allow_internal_unstable, }, }); @@ -591,7 +591,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => { let msg = &format!("macro `{}` may not be used for derive attributes", attr.path); - self.cx.span_err(span, &msg); + self.cx.span_err(span, msg); kind.dummy(span) } } @@ -749,19 +749,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn check_attributes(&mut self, attrs: &[ast::Attribute]) { let features = self.cx.ecfg.features.unwrap(); for attr in attrs.iter() { - feature_gate::check_attribute(&attr, &self.cx.parse_sess, features); + feature_gate::check_attribute(attr, self.cx.parse_sess, features); } } } pub fn find_attr_invoc(attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> { - for i in 0 .. attrs.len() { - if !attr::is_known(&attrs[i]) && !is_builtin_attr(&attrs[i]) { - return Some(attrs.remove(i)); - } - } - - None + attrs.iter() + .position(|a| !attr::is_known(a) && !is_builtin_attr(a)) + .map(|i| attrs.remove(i)) } // These are pretty nasty. Ideally, we would keep the tokens around, linked from @@ -783,7 +779,7 @@ fn stream_for_item(item: &Annotatable, parse_sess: &ParseSess) -> TokenStream { fn string_to_stream(text: String, parse_sess: &ParseSess) -> TokenStream { let filename = String::from("<macro expansion>"); - filemap_to_stream(parse_sess, parse_sess.codemap().new_filemap(filename, None, text)) + filemap_to_stream(parse_sess, parse_sess.codemap().new_filemap(filename, text)) } impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { @@ -923,7 +919,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let result = noop_fold_item(item, self); self.cx.current_expansion.module = orig_module; self.cx.current_expansion.directory_ownership = orig_directory_ownership; - return result; + result } // Ensure that test functions are accessible from the test harness. ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => { @@ -1038,7 +1034,7 @@ impl<'feat> ExpansionConfig<'feat> { ExpansionConfig { crate_name: crate_name, features: None, - recursion_limit: 64, + recursion_limit: 1024, trace_mac: false, should_test: false, single_step: false, diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index d7a85baa3ff..f8fac847a05 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -23,7 +23,7 @@ use tokenstream::{TokenStream, TokenTree}; /// /// This is registered as a set of expression syntax extension called quote! /// that lifts its argument token-tree to an AST representing the -/// construction of the same token tree, with token::SubstNt interpreted +/// construction of the same token tree, with `token::SubstNt` interpreted /// as antiquotes (splices). pub mod rt { @@ -389,7 +389,7 @@ pub fn unflatten(tts: Vec<TokenTree>) -> Vec<TokenTree> { result = results.pop().unwrap(); result.push(tree); } - tree @ _ => result.push(tree), + tree => result.push(tree), } } result @@ -612,8 +612,11 @@ fn mk_delim(cx: &ExtCtxt, sp: Span, delim: token::DelimToken) -> P<ast::Expr> { #[allow(non_upper_case_globals)] fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { macro_rules! mk_lit { - ($name: expr, $suffix: expr, $($args: expr),*) => {{ - let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]); + ($name: expr, $suffix: expr, $content: expr $(, $count: expr)*) => {{ + let name = mk_name(cx, sp, ast::Ident::with_empty_ctxt($content)); + let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![ + name $(, cx.expr_usize(sp, $count))* + ]); let suffix = match $suffix { Some(name) => cx.expr_some(sp, mk_name(cx, sp, ast::Ident::with_empty_ctxt(name))), None => cx.expr_none(sp) @@ -621,7 +624,8 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { cx.expr_call(sp, mk_token_path(cx, sp, "Literal"), vec![inner, suffix]) }} } - match *tok { + + let name = match *tok { token::BinOp(binop) => { return cx.expr_call(sp, mk_token_path(cx, sp, "BinOp"), vec![mk_binop(cx, sp, binop)]); } @@ -639,34 +643,14 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { vec![mk_delim(cx, sp, delim)]); } - token::Literal(token::Byte(i), suf) => { - let e_byte = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Byte", suf, e_byte); - } - - token::Literal(token::Char(i), suf) => { - let e_char = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Char", suf, e_char); - } - - token::Literal(token::Integer(i), suf) => { - let e_int = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Integer", suf, e_int); - } - - token::Literal(token::Float(fident), suf) => { - let e_fident = mk_name(cx, sp, ast::Ident::with_empty_ctxt(fident)); - return mk_lit!("Float", suf, e_fident); - } - - token::Literal(token::Str_(ident), suf) => { - return mk_lit!("Str_", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident))) - } - - token::Literal(token::StrRaw(ident, n), suf) => { - return mk_lit!("StrRaw", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident)), - cx.expr_usize(sp, n)) - } + token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), + token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), + token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), + token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), + token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), + token::Literal(token::StrRaw(i, n), suf) => return mk_lit!("StrRaw", suf, i, n), + token::Literal(token::ByteStr(i), suf) => return mk_lit!("ByteStr", suf, i), + token::Literal(token::ByteStrRaw(i, n), suf) => return mk_lit!("ByteStrRaw", suf, i, n), token::Ident(ident) => { return cx.expr_call(sp, @@ -688,10 +672,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { token::Interpolated(_) => panic!("quote! with interpolated token"), - _ => () - } - - let name = match *tok { token::Eq => "Eq", token::Lt => "Lt", token::Le => "Le", @@ -706,6 +686,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { token::At => "At", token::Dot => "Dot", token::DotDot => "DotDot", + token::DotDotDot => "DotDotDot", token::Comma => "Comma", token::Semi => "Semi", token::Colon => "Colon", @@ -718,7 +699,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> { token::Question => "Question", token::Underscore => "Underscore", token::Eof => "Eof", - _ => panic!("unhandled token in quote!"), + + token::Whitespace | token::SubstNt(_) | token::Comment | token::Shebang(_) => { + panic!("unhandled token in quote!"); + } }; mk_token_path(cx, sp, name) } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 0103d6ea959..3cdd3a4b2c3 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32)) @@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "column!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32)) @@ -59,7 +59,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name))) } @@ -142,7 +142,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT // Add this input file to the code map to make it available as // dependency information let filename = format!("{}", file.display()); - cx.codemap().new_filemap_and_lines(&filename, None, &src); + cx.codemap().new_filemap_and_lines(&filename, &src); base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&src))) } @@ -150,7 +150,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display())); - return DummyResult::expr(sp); + DummyResult::expr(sp) } } } @@ -167,13 +167,13 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Toke Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); - return DummyResult::expr(sp); + DummyResult::expr(sp) } Ok(..) => { // 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, None, ""); + cx.codemap().new_filemap_and_lines(&filename, ""); base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Rc::new(bytes)))) } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index eb0b7c29f8d..bf66aa0f00b 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -36,43 +36,47 @@ //! repetitions indicated by Kleene stars. It only advances or calls out to the //! real Rust parser when no `cur_eis` items remain //! -//! Example: Start parsing `a a a a b` against [· a $( a )* a b]. +//! Example: //! -//! Remaining input: `a a a a b` +//! ```text, ignore +//! Start parsing a a a a b against [· a $( a )* a b]. +//! +//! Remaining input: a a a a b //! next_eis: [· a $( a )* a b] //! -//! - - - Advance over an `a`. - - - +//! - - - Advance over an a. - - - //! -//! Remaining input: `a a a b` +//! Remaining input: a a a b //! cur: [a · $( a )* a b] //! Descend/Skip (first item). //! next: [a $( · a )* a b] [a $( a )* · a b]. //! -//! - - - Advance over an `a`. - - - +//! - - - Advance over an a. - - - //! -//! Remaining input: `a a b` +//! Remaining input: a a b //! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) //! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] //! -//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! - - - Advance over an a. - - - (this looks exactly like the last step) //! -//! Remaining input: `a b` +//! Remaining input: a b //! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) //! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] //! -//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! - - - Advance over an a. - - - (this looks exactly like the last step) //! -//! Remaining input: `b` +//! Remaining input: b //! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) //! next: [a $( a )* · a b] [a $( · a )* a b] //! -//! - - - Advance over a `b`. - - - +//! - - - Advance over a b. - - - //! -//! Remaining input: `` +//! Remaining input: '' //! eof: [a $( a )* a b ·] +//! ``` pub use self::NamedMatch::*; pub use self::ParseResult::*; @@ -178,20 +182,20 @@ fn initial_matcher_pos(ms: Vec<TokenTree>, lo: BytePos) -> Box<MatcherPos> { }) } -/// NamedMatch is a pattern-match result for a single token::MATCH_NONTERMINAL: +/// `NamedMatch` is a pattern-match result for a single `token::MATCH_NONTERMINAL`: /// so it is associated with a single ident in a parse, and all -/// `MatchedNonterminal`s in the NamedMatch have the same nonterminal type -/// (expr, item, etc). Each leaf in a single NamedMatch corresponds to a -/// single token::MATCH_NONTERMINAL in the TokenTree that produced it. +/// `MatchedNonterminal`s in the `NamedMatch` have the same nonterminal type +/// (expr, item, etc). Each leaf in a single `NamedMatch` corresponds to a +/// single `token::MATCH_NONTERMINAL` in the `TokenTree` that produced it. /// -/// The in-memory structure of a particular NamedMatch represents the match +/// The in-memory structure of a particular `NamedMatch` represents the match /// that occurred when a particular subset of a matcher was applied to a /// particular token tree. /// -/// The width of each MatchedSeq in the NamedMatch, and the identity of the -/// `MatchedNonterminal`s, will depend on the token tree it was applied to: -/// each MatchedSeq corresponds to a single TTSeq in the originating -/// token tree. The depth of the NamedMatch structure will therefore depend +/// The width of each `MatchedSeq` in the `NamedMatch`, and the identity of +/// the `MatchedNonterminal`s, will depend on the token tree it was applied +/// to: each `MatchedSeq` corresponds to a single `TTSeq` in the originating +/// token tree. The depth of the `NamedMatch` structure will therefore depend /// only on the nesting depth of `ast::TTSeq`s in the originating /// token tree it was derived from. @@ -267,11 +271,12 @@ pub fn parse_failure_msg(tok: Token) -> String { /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { - match (t1,t2) { - (&token::Ident(id1),&token::Ident(id2)) - | (&token::Lifetime(id1),&token::Lifetime(id2)) => - id1.name == id2.name, - _ => *t1 == *t2 + if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { + id1.name == id2.name + } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { + id1.name == id2.name + } else { + *t1 == *t2 } } @@ -334,7 +339,7 @@ fn inner_parse_loop(sess: &ParseSess, // Check if we need a separator if idx == len && ei.sep.is_some() { // We have a separator, and it is the current token. - if ei.sep.as_ref().map(|ref sep| token_name_eq(&token, sep)).unwrap_or(false) { + if ei.sep.as_ref().map(|sep| token_name_eq(token, sep)).unwrap_or(false) { ei.idx += 1; next_eis.push(ei); } @@ -401,7 +406,7 @@ fn inner_parse_loop(sess: &ParseSess, cur_eis.push(ei); } TokenTree::Token(_, ref t) => { - if token_name_eq(t, &token) { + if token_name_eq(t, token) { ei.idx += 1; next_eis.push(ei); } @@ -485,11 +490,8 @@ pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Op } fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { - match name { - "tt" => { - return token::NtTT(p.parse_token_tree()); - } - _ => {} + if name == "tt" { + return token::NtTT(p.parse_token_tree()); } // check at the beginning and the parser checks after each bump p.process_potential_macro_variable(); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index be979960725..a208f530602 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -27,8 +27,8 @@ use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use std::cell::RefCell; -use std::collections::{HashMap}; -use std::collections::hash_map::{Entry}; +use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::rc::Rc; pub struct ParserAnyMacro<'a> { @@ -85,7 +85,7 @@ impl TTMacroExpander for MacroRulesMacroExpander { } /// Given `lhses` and `rhses`, this is the new macro we create -fn generic_extension<'cx>(cx: &'cx ExtCtxt, +fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: ast::Ident, arg: TokenStream, @@ -93,7 +93,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, rhses: &[quoted::TokenTree]) -> Box<MacResult+'cx> { if cx.trace_macros() { - println!("{}! {{ {} }}", name, arg); + let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); + let mut values: &mut Vec<String> = cx.expansions.entry(sp).or_insert_with(Vec::new); + values.push(format!("expands to `{}! {{ {} }}`", name, arg)); } // Which arm's failure should we report? (the one furthest along) @@ -204,7 +206,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item) let mut valid = true; // Extract the arguments: - let lhses = match **argument_map.get(&lhs_nm).unwrap() { + let lhses = match *argument_map[&lhs_nm] { MatchedSeq(ref s, _) => { s.iter().map(|m| { if let MatchedNonterminal(ref nt) = **m { @@ -220,7 +222,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item) _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") }; - let rhses = match **argument_map.get(&rhs_nm).unwrap() { + let rhses = match *argument_map[&rhs_nm] { MatchedSeq(ref s, _) => { s.iter().map(|m| { if let MatchedNonterminal(ref nt) = **m { @@ -250,7 +252,9 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item) valid: valid, }); - NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable")) + NormalTT(exp, + Some((def.id, def.span)), + attr::contains_name(&def.attrs, "allow_internal_unstable")) } fn check_lhs_nt_follows(sess: &ParseSess, @@ -258,13 +262,12 @@ fn check_lhs_nt_follows(sess: &ParseSess, lhs: "ed::TokenTree) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. - match lhs { - "ed::TokenTree::Delimited(_, ref tts) => check_matcher(sess, features, &tts.tts), - _ => { - let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; - sess.span_diagnostic.span_err(lhs.span(), msg); - false - } + if let quoted::TokenTree::Delimited(_, ref tts) = *lhs { + check_matcher(sess, features, &tts.tts) + } else { + let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; + sess.span_diagnostic.span_err(lhs.span(), msg); + false } // we don't abort on errors on rejection, the driver will do that for us // after parsing/expansion. we can report every error in every macro this way. @@ -281,17 +284,15 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { return false; }, TokenTree::Sequence(span, ref seq) => { - if seq.separator.is_none() { - if seq.tts.iter().all(|seq_tt| { - match *seq_tt { - TokenTree::Sequence(_, ref sub_seq) => - sub_seq.op == quoted::KleeneOp::ZeroOrMore, - _ => false, - } - }) { - sess.span_diagnostic.span_err(span, "repetition matches empty token tree"); - return false; + if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| { + match *seq_tt { + TokenTree::Sequence(_, ref sub_seq) => + sub_seq.op == quoted::KleeneOp::ZeroOrMore, + _ => false, } + }) { + sess.span_diagnostic.span_err(span, "repetition matches empty token tree"); + return false; } if !check_lhs_no_empty_seq(sess, &seq.tts) { return false; @@ -405,7 +406,7 @@ impl FirstSets { } } - return first; + first } } @@ -467,7 +468,7 @@ impl FirstSets { // we only exit the loop if `tts` was empty or if every // element of `tts` matches the empty sequence. assert!(first.maybe_empty); - return first; + first } } @@ -577,7 +578,7 @@ fn check_matcher_core(sess: &ParseSess, let build_suffix_first = || { let mut s = first_sets.first(suffix); if s.maybe_empty { s.add_all(follow); } - return s; + s }; // (we build `suffix_first` on demand below; you can tell @@ -859,6 +860,7 @@ fn quoted_tt_to_string(tt: "ed::TokenTree) -> String { match *tt { quoted::TokenTree::Token(_, ref tok) => ::print::pprust::token_to_string(tok), quoted::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), - _ => panic!("unexpected quoted::TokenTree::{Sequence or Delimited} in follow set checker"), + _ => panic!("unexpected quoted::TokenTree::{{Sequence or Delimited}} \ + in follow set checker"), } } diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index d216effbd45..fa65e9501c2 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -96,6 +96,17 @@ impl TokenTree { } } + pub fn is_empty(&self) -> bool { + match *self { + TokenTree::Delimited(_, ref delimed) => match delimed.delim { + token::NoDelim => delimed.tts.is_empty(), + _ => false, + }, + TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(), + _ => true, + } + } + pub fn get_tt(&self, index: usize) -> TokenTree { match (self, index) { (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { @@ -144,9 +155,9 @@ pub fn parse(input: tokenstream::TokenStream, expect_matchers: bool, sess: &Pars } _ => end_sp, }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), }; sess.missing_fragment_specifiers.borrow_mut().insert(span); result.push(TokenTree::MetaVarDecl(span, ident, keywords::Invalid.ident())); @@ -228,10 +239,10 @@ fn parse_sep_and_kleene_op<I>(input: &mut I, span: Span, sess: &ParseSess) Some(op) => return (Some(tok), op), None => span, }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), } }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), }; sess.span_diagnostic.span_err(span, "expected `*` or `+`"); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 947089b0b9a..2a435bdea10 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -121,20 +121,20 @@ pub fn transcribe(sp_diag: &Handler, &repeats) { LockstepIterSize::Unconstrained => { panic!(sp_diag.span_fatal( - sp.clone(), /* blame macro writer */ + sp, /* blame macro writer */ "attempted to repeat an expression \ containing no syntax \ variables matched as repeating at this depth")); } LockstepIterSize::Contradiction(ref msg) => { // FIXME #2887 blame macro invoker instead - panic!(sp_diag.span_fatal(sp.clone(), &msg[..])); + panic!(sp_diag.span_fatal(sp, &msg[..])); } LockstepIterSize::Constraint(len, _) => { if len == 0 { if seq.op == quoted::KleeneOp::OneOrMore { // FIXME #2887 blame invoker - panic!(sp_diag.span_fatal(sp.clone(), + panic!(sp_diag.span_fatal(sp, "this must repeat at least once")); } } else { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa0e45194dc..6acf27f314a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -294,9 +294,6 @@ declare_features! ( (active, use_extern_macros, "1.15.0", Some(35896)), - // Allows `break {expr}` with a value inside `loop`s. - (active, loop_break_value, "1.14.0", Some(37339)), - // Allows #[target_feature(...)] (active, target_feature, "1.15.0", None), @@ -407,7 +404,7 @@ declare_features! ( (accepted, question_mark, "1.13.0", Some(31436)), // Allows `..` in tuple (struct) patterns (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627)), - (accepted, item_like_imports, "1.14.0", Some(35120)), + (accepted, item_like_imports, "1.15.0", Some(35120)), // Allows using `Self` and associated types in struct expressions and patterns. (accepted, more_struct_aliases, "1.16.0", Some(37544)), // elide `'static` lifetimes in `static`s and `const`s @@ -420,8 +417,10 @@ declare_features! ( (accepted, pub_restricted, "1.18.0", Some(32409)), // The #![windows_subsystem] attribute (accepted, windows_subsystem, "1.18.0", Some(37499)), + // Allows `break {expr}` with a value inside `loop`s. + (accepted, loop_break_value, "1.19.0", Some(37339)), // Permits numeric fields in struct expressions and patterns. - (accepted, relaxed_adts, "1.18.0", Some(35626)), + (accepted, relaxed_adts, "1.19.0", Some(35626)), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -472,7 +471,7 @@ pub enum Stability { impl ::std::fmt::Debug for AttributeGate { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { match *self { - Gated(ref stab, ref name, ref expl, _) => + Gated(ref stab, name, expl, _) => write!(fmt, "Gated({:?}, {}, {})", stab, name, expl), Ungated => write!(fmt, "Ungated") } @@ -816,7 +815,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG ]; // cfg(...)'s that are feature gated -const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] = &[ +const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ // (name in cfg, feature, function to check if the feature is enabled) ("target_feature", "cfg_target_feature", cfg_fn!(cfg_target_feature)), ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), @@ -881,7 +880,7 @@ impl<'a> Context<'a> { let name = unwrap_or!(attr.name(), return).as_str(); for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES { if name == n { - if let &Gated(_, ref name, ref desc, ref has_feature) = gateage { + if let Gated(_, name, desc, ref has_feature) = *gateage { gate_feature_fn!(self, has_feature, attr.span, name, desc); } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); @@ -1098,7 +1097,7 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool { NameValue(ref lit) => !lit.node.is_str(), List(ref list) => list.iter().any(|li| { match li.node { - MetaItem(ref mi) => contains_novel_literal(&mi), + MetaItem(ref mi) => contains_novel_literal(mi), Literal(_) => true, } }), @@ -1116,7 +1115,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { return } - let meta = panictry!(attr.parse_meta(&self.context.parse_sess)); + let meta = panictry!(attr.parse_meta(self.context.parse_sess)); if contains_novel_literal(&meta) { gate_feature_post!(&self, attr_literals, attr.span, "non-string literals in attributes, or string \ @@ -1211,15 +1210,18 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { and possibly buggy"); } - ast::ItemKind::Impl(_, polarity, _, _, _, _) => { - match polarity { - ast::ImplPolarity::Negative => { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "negative trait bounds are not yet fully implemented; \ - use marker types for now"); - }, - _ => {} + ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { + if polarity == ast::ImplPolarity::Negative { + gate_feature_post!(&self, optin_builtin_traits, + i.span, + "negative trait bounds are not yet fully implemented; \ + use marker types for now"); + } + + if let ast::Defaultness::Default = defaultness { + gate_feature_post!(&self, specialization, + i.span, + "specialization is unstable"); } } @@ -1262,11 +1264,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { - match output_ty.node { - ast::TyKind::Never => return, - _ => (), - }; - self.visit_ty(output_ty) + if output_ty.node != ast::TyKind::Never { + self.visit_ty(output_ty) + } } } @@ -1287,10 +1287,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ExprKind::InPlace(..) => { gate_feature_post!(&self, placement_in_syntax, e.span, EXPLAIN_PLACEMENT_IN); } - ast::ExprKind::Break(_, Some(_)) => { - gate_feature_post!(&self, loop_break_value, e.span, - "`break` with a value is experimental"); - } ast::ExprKind::Lit(ref lit) => { if let ast::LitKind::Int(_, ref ty) = lit.node { match *ty { @@ -1345,17 +1341,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { span: Span, _node_id: NodeId) { // check for const fn declarations - match fn_kind { - FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) => { - gate_feature_post!(&self, const_fn, span, "const fn is unstable"); - } - _ => { - // stability of const fn methods are covered in - // visit_trait_item and visit_impl_item below; this is - // because default methods don't pass through this - // point. - } + if let FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) = + fn_kind { + gate_feature_post!(&self, const_fn, span, "const fn is unstable"); } + // stability of const fn methods are covered in + // visit_trait_item and visit_impl_item below; this is + // because default methods don't pass through this + // point. match fn_kind { FnKind::ItemFn(_, _, _, _, abi, _, _) | diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index f39399a62e8..58cf50cdc00 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -897,9 +897,16 @@ pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind { ItemKind::DefaultImpl(unsafety, ref trait_ref) => { ItemKind::DefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone())) } - ItemKind::Impl(unsafety, polarity, generics, ifce, ty, impl_items) => ItemKind::Impl( + ItemKind::Impl(unsafety, + polarity, + defaultness, + generics, + ifce, + ty, + impl_items) => ItemKind::Impl( unsafety, polarity, + defaultness, folder.fold_generics(generics), ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())), folder.fold_ty(ty), diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index dec1b7d1d87..f37dcfdde89 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -19,7 +19,7 @@ // FIXME spec the JSON output properly. -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan}; use errors::registry::Registry; use errors::{DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion, CodeMapper}; @@ -48,7 +48,8 @@ impl JsonEmitter { } pub fn basic() -> JsonEmitter { - JsonEmitter::stderr(None, Rc::new(CodeMap::new())) + let file_path_mapping = FilePathMapping::empty(); + JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping))) } pub fn new(dst: Box<Write + Send>, @@ -152,6 +153,18 @@ impl Diagnostic { fn from_diagnostic_builder(db: &DiagnosticBuilder, je: &JsonEmitter) -> Diagnostic { + let sugg = db.suggestions.iter().flat_map(|sugg| { + je.render(sugg).into_iter().map(move |rendered| { + Diagnostic { + message: sugg.msg.clone(), + code: None, + level: "help", + spans: DiagnosticSpan::from_suggestion(sugg, je), + children: vec![], + rendered: Some(rendered), + } + }) + }); Diagnostic { message: db.message(), code: DiagnosticCode::map_opt_string(db.code.clone(), je), @@ -159,7 +172,7 @@ impl Diagnostic { spans: DiagnosticSpan::from_multispan(&db.span, je), children: db.children.iter().map(|c| { Diagnostic::from_sub_diagnostic(c, je) - }).collect(), + }).chain(sugg).collect(), rendered: None, } } @@ -173,8 +186,7 @@ impl Diagnostic { .map(|sp| DiagnosticSpan::from_render_span(sp, je)) .unwrap_or_else(|| DiagnosticSpan::from_multispan(&db.span, je)), children: vec![], - rendered: db.render_span.as_ref() - .and_then(|rsp| je.render(rsp)), + rendered: None, } } } @@ -267,14 +279,19 @@ impl DiagnosticSpan { fn from_suggestion(suggestion: &CodeSuggestion, je: &JsonEmitter) -> Vec<DiagnosticSpan> { - assert_eq!(suggestion.msp.span_labels().len(), suggestion.substitutes.len()); - suggestion.msp.span_labels() - .into_iter() - .zip(&suggestion.substitutes) - .map(|(span_label, suggestion)| { - DiagnosticSpan::from_span_label(span_label, - Some(suggestion), - je) + suggestion.substitution_parts + .iter() + .flat_map(|substitution| { + substitution.substitutions.iter().map(move |suggestion| { + let span_label = SpanLabel { + span: substitution.span, + is_primary: true, + label: None, + }; + DiagnosticSpan::from_span_label(span_label, + Some(suggestion), + je) + }) }) .collect() } @@ -283,8 +300,9 @@ impl DiagnosticSpan { match *rsp { RenderSpan::FullSpan(ref msp) => DiagnosticSpan::from_multispan(msp, je), - RenderSpan::Suggestion(ref suggestion) => - DiagnosticSpan::from_suggestion(suggestion, je), + // regular diagnostics don't produce this anymore + // FIXME(oli_obk): remove it entirely + RenderSpan::Suggestion(_) => unreachable!(), } } } @@ -319,7 +337,7 @@ impl DiagnosticSpanLine { }) .collect() }) - .unwrap_or(vec![]) + .unwrap_or_else(|_| vec![]) } } @@ -340,17 +358,8 @@ impl DiagnosticCode { } impl JsonEmitter { - fn render(&self, render_span: &RenderSpan) -> Option<String> { - use std::borrow::Borrow; - - match *render_span { - RenderSpan::FullSpan(_) => { - None - } - RenderSpan::Suggestion(ref suggestion) => { - Some(suggestion.splice_lines(self.cm.borrow())) - } - } + fn render(&self, suggestion: &CodeSuggestion) -> Vec<String> { + suggestion.splice_lines(&*self.cm) } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 86ee1c5336d..32dafcdb582 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -15,7 +15,6 @@ //! This API is completely unstable and subject to change. #![crate_name = "syntax"] -#![unstable(feature = "rustc_private", issue = "27812")] #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", @@ -24,20 +23,17 @@ test(attr(deny(warnings))))] #![deny(warnings)] -#![feature(associated_consts)] -#![feature(const_fn)] -#![feature(optin_builtin_traits)] -#![feature(rustc_private)] -#![feature(staged_api)] -#![feature(str_escape)] #![feature(unicode)] #![feature(rustc_diagnostic_macros)] -#![feature(specialization)] #![feature(i128_type)] +#![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))] +#![cfg_attr(stage0, feature(rustc_private))] +#![cfg_attr(stage0, feature(staged_api))] + extern crate serialize; #[macro_use] extern crate log; -#[macro_use] #[no_link] extern crate rustc_bitflags; +#[macro_use] extern crate bitflags; extern crate std_unicode; pub extern crate rustc_errors as errors; extern crate syntax_pos; diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 92cec462ffb..082930777e5 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { _ => break, } } - return Ok(attrs); + Ok(attrs) } /// Matches `attribute = # ! [ meta_item ]` @@ -182,7 +182,7 @@ impl<'a> Parser<'a> { } let attr = self.parse_attribute(true)?; - assert!(attr.style == ast::AttrStyle::Inner); + assert_eq!(attr.style, ast::AttrStyle::Inner); attrs.push(attr); } token::DocComment(s) => { diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 4fe4ec7e4c0..0c6f09ba766 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -43,14 +43,14 @@ pub fn expr_is_simple_block(e: &ast::Expr) -> bool { } /// this statement requires a semicolon after it. -/// note that in one case (stmt_semi), we've already +/// note that in one case (`stmt_semi`), we've already /// seen the semicolon, and thus don't need another. pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool { match *stmt { ast::StmtKind::Local(_) => true, - ast::StmtKind::Item(_) => false, ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e), - ast::StmtKind::Semi(..) => false, + ast::StmtKind::Item(_) | + ast::StmtKind::Semi(..) | ast::StmtKind::Mac(..) => false, } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index b57708f9193..fe931f7cf6a 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -12,7 +12,7 @@ use parse::token; -/// SeqSep : a sequence separator (token) +/// `SeqSep` : a sequence separator (token) /// and whether a trailing separator is allowed. pub struct SeqSep { pub sep: Option<token::Token>, diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index c97b8ddf919..8b545d3b909 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -77,7 +77,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { while j > i && lines[j - 1].trim().is_empty() { j -= 1; } - lines[i..j].iter().cloned().collect() + lines[i..j].to_vec() } /// remove a "[ \t]*\*" block from each line, if possible @@ -348,8 +348,8 @@ pub fn gather_comments_and_literals(sess: &ParseSess, path: String, srdr: &mut R let mut src = Vec::new(); srdr.read_to_end(&mut src).unwrap(); let src = String::from_utf8(src).unwrap(); - let cm = CodeMap::new(); - let filemap = cm.new_filemap(path, None, src); + let cm = CodeMap::new(sess.codemap().path_mapping().clone()); + let filemap = cm.new_filemap(path, src); let mut rdr = lexer::StringReader::new_raw(sess, filemap); let mut comments: Vec<Comment> = Vec::new(); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 920b2c401e2..0bcd4578518 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -10,7 +10,7 @@ use ast::{self, Ident}; use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION}; -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use errors::{FatalError, DiagnosticBuilder}; use parse::{token, ParseSess}; use str::char_at; @@ -73,7 +73,7 @@ fn mk_sp(lo: BytePos, hi: BytePos) -> Span { } impl<'a> StringReader<'a> { - fn next_token(&mut self) -> TokenAndSpan where Self: Sized { + fn next_token(&mut self) -> TokenAndSpan { let res = self.try_next_token(); self.unwrap_or_abort(res) } @@ -144,7 +144,7 @@ impl<'a> StringReader<'a> { impl<'a> StringReader<'a> { /// For comments.rs, which hackily pokes into next_pos and ch - pub fn new_raw<'b>(sess: &'a ParseSess, filemap: Rc<syntax_pos::FileMap>) -> Self { + pub fn new_raw(sess: &'a ParseSess, filemap: Rc<syntax_pos::FileMap>) -> Self { let mut sr = StringReader::new_raw_internal(sess, filemap); sr.bump(); sr @@ -180,7 +180,7 @@ impl<'a> StringReader<'a> { pub fn new(sess: &'a ParseSess, filemap: Rc<syntax_pos::FileMap>) -> Self { let mut sr = StringReader::new_raw(sess, filemap); - if let Err(_) = sr.advance_token() { + if sr.advance_token().is_err() { sr.emit_fatal_errors(); panic!(FatalError); } @@ -205,7 +205,7 @@ impl<'a> StringReader<'a> { sr.bump(); - if let Err(_) = sr.advance_token() { + if sr.advance_token().is_err() { sr.emit_fatal_errors(); panic!(FatalError); } @@ -504,7 +504,7 @@ impl<'a> StringReader<'a> { self.bump(); // line comments starting with "///" or "//!" are doc-comments - let doc_comment = self.ch_is('/') || self.ch_is('!'); + let doc_comment = (self.ch_is('/') && !self.nextch_is('/')) || self.ch_is('!'); let start_bpos = self.pos - BytePos(2); while !self.is_eof() { @@ -525,7 +525,7 @@ impl<'a> StringReader<'a> { self.bump(); } - return if doc_comment { + if doc_comment { self.with_str_from(start_bpos, |string| { // comments with only more "/"s are not doc comments let tok = if is_doc_comment(string) { @@ -544,7 +544,7 @@ impl<'a> StringReader<'a> { tok: token::Comment, sp: mk_sp(start_bpos, self.pos), }) - }; + } } Some('*') => { self.bump(); @@ -563,7 +563,7 @@ impl<'a> StringReader<'a> { // I guess this is the only way to figure out if // we're at the beginning of the file... - let cmap = CodeMap::new(); + let cmap = CodeMap::new(FilePathMapping::empty()); cmap.files.borrow_mut().push(self.filemap.clone()); let loc = cmap.lookup_char_pos_adj(self.pos); debug!("Skipping a shebang"); @@ -754,9 +754,7 @@ impl<'a> StringReader<'a> { // integer literal followed by field/method access or a range pattern // (`0..2` and `12.foo()`) if self.ch_is('.') && !self.nextch_is('.') && - !self.nextch() - .unwrap_or('\0') - .is_xid_start() { + !ident_start(self.nextch()) { // might have stuff after the ., and if it does, it needs to start // with a number self.bump(); @@ -766,7 +764,7 @@ impl<'a> StringReader<'a> { } let pos = self.pos; self.check_float_base(start_bpos, pos, base); - return token::Float(self.name_from(start_bpos)); + token::Float(self.name_from(start_bpos)) } else { // it might be a float if it has an exponent if self.ch_is('e') || self.ch_is('E') { @@ -776,7 +774,7 @@ impl<'a> StringReader<'a> { return token::Float(self.name_from(start_bpos)); } // but we certainly have an integer! - return token::Integer(self.name_from(start_bpos)); + token::Integer(self.name_from(start_bpos)) } } @@ -1053,9 +1051,9 @@ impl<'a> StringReader<'a> { self.bump(); if self.ch_is('=') { self.bump(); - return token::BinOpEq(op); + token::BinOpEq(op) } else { - return token::BinOp(op); + token::BinOp(op) } } @@ -1102,15 +1100,15 @@ impl<'a> StringReader<'a> { // One-byte tokens. ';' => { self.bump(); - return Ok(token::Semi); + Ok(token::Semi) } ',' => { self.bump(); - return Ok(token::Comma); + Ok(token::Comma) } '.' => { self.bump(); - return if self.ch_is('.') { + if self.ch_is('.') { self.bump(); if self.ch_is('.') { self.bump(); @@ -1120,61 +1118,61 @@ impl<'a> StringReader<'a> { } } else { Ok(token::Dot) - }; + } } '(' => { self.bump(); - return Ok(token::OpenDelim(token::Paren)); + Ok(token::OpenDelim(token::Paren)) } ')' => { self.bump(); - return Ok(token::CloseDelim(token::Paren)); + Ok(token::CloseDelim(token::Paren)) } '{' => { self.bump(); - return Ok(token::OpenDelim(token::Brace)); + Ok(token::OpenDelim(token::Brace)) } '}' => { self.bump(); - return Ok(token::CloseDelim(token::Brace)); + Ok(token::CloseDelim(token::Brace)) } '[' => { self.bump(); - return Ok(token::OpenDelim(token::Bracket)); + Ok(token::OpenDelim(token::Bracket)) } ']' => { self.bump(); - return Ok(token::CloseDelim(token::Bracket)); + Ok(token::CloseDelim(token::Bracket)) } '@' => { self.bump(); - return Ok(token::At); + Ok(token::At) } '#' => { self.bump(); - return Ok(token::Pound); + Ok(token::Pound) } '~' => { self.bump(); - return Ok(token::Tilde); + Ok(token::Tilde) } '?' => { self.bump(); - return Ok(token::Question); + Ok(token::Question) } ':' => { self.bump(); if self.ch_is(':') { self.bump(); - return Ok(token::ModSep); + Ok(token::ModSep) } else { - return Ok(token::Colon); + Ok(token::Colon) } } '$' => { self.bump(); - return Ok(token::Dollar); + Ok(token::Dollar) } // Multi-byte tokens. @@ -1182,21 +1180,21 @@ impl<'a> StringReader<'a> { self.bump(); if self.ch_is('=') { self.bump(); - return Ok(token::EqEq); + Ok(token::EqEq) } else if self.ch_is('>') { self.bump(); - return Ok(token::FatArrow); + Ok(token::FatArrow) } else { - return Ok(token::Eq); + Ok(token::Eq) } } '!' => { self.bump(); if self.ch_is('=') { self.bump(); - return Ok(token::Ne); + Ok(token::Ne) } else { - return Ok(token::Not); + Ok(token::Not) } } '<' => { @@ -1204,21 +1202,21 @@ impl<'a> StringReader<'a> { match self.ch.unwrap_or('\x00') { '=' => { self.bump(); - return Ok(token::Le); + Ok(token::Le) } '<' => { - return Ok(self.binop(token::Shl)); + Ok(self.binop(token::Shl)) } '-' => { self.bump(); match self.ch.unwrap_or('\x00') { _ => { - return Ok(token::LArrow); + Ok(token::LArrow) } } } _ => { - return Ok(token::Lt); + Ok(token::Lt) } } } @@ -1227,13 +1225,13 @@ impl<'a> StringReader<'a> { match self.ch.unwrap_or('\x00') { '=' => { self.bump(); - return Ok(token::Ge); + Ok(token::Ge) } '>' => { - return Ok(self.binop(token::Shr)); + Ok(self.binop(token::Shr)) } _ => { - return Ok(token::Gt); + Ok(token::Gt) } } } @@ -1303,7 +1301,7 @@ impl<'a> StringReader<'a> { }; self.bump(); // advance ch past token let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::Char(id), suffix)); + Ok(token::Literal(token::Char(id), suffix)) } 'b' => { self.bump(); @@ -1314,7 +1312,7 @@ impl<'a> StringReader<'a> { _ => unreachable!(), // Should have been a token::Ident above. }; let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(lit, suffix)); + Ok(token::Literal(lit, suffix)) } '"' => { let start_bpos = self.pos; @@ -1345,7 +1343,7 @@ impl<'a> StringReader<'a> { }; self.bump(); let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::Str_(id), suffix)); + Ok(token::Literal(token::Str_(id), suffix)) } 'r' => { let start_bpos = self.pos; @@ -1416,24 +1414,24 @@ impl<'a> StringReader<'a> { Symbol::intern("??") }; let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::StrRaw(id, hash_count), suffix)); + Ok(token::Literal(token::StrRaw(id, hash_count), suffix)) } '-' => { if self.nextch_is('>') { self.bump(); self.bump(); - return Ok(token::RArrow); + Ok(token::RArrow) } else { - return Ok(self.binop(token::Minus)); + Ok(self.binop(token::Minus)) } } '&' => { if self.nextch_is('&') { self.bump(); self.bump(); - return Ok(token::AndAnd); + Ok(token::AndAnd) } else { - return Ok(self.binop(token::And)); + Ok(self.binop(token::And)) } } '|' => { @@ -1441,27 +1439,27 @@ impl<'a> StringReader<'a> { Some('|') => { self.bump(); self.bump(); - return Ok(token::OrOr); + Ok(token::OrOr) } _ => { - return Ok(self.binop(token::Or)); + Ok(self.binop(token::Or)) } } } '+' => { - return Ok(self.binop(token::Plus)); + Ok(self.binop(token::Plus)) } '*' => { - return Ok(self.binop(token::Star)); + Ok(self.binop(token::Star)) } '/' => { - return Ok(self.binop(token::Slash)); + Ok(self.binop(token::Slash)) } '^' => { - return Ok(self.binop(token::Caret)); + Ok(self.binop(token::Caret)) } '%' => { - return Ok(self.binop(token::Percent)); + Ok(self.binop(token::Percent)) } c => { let last_bpos = self.pos; @@ -1470,7 +1468,7 @@ impl<'a> StringReader<'a> { bpos, "unknown start of token", c); - unicode_chars::check_for_substitution(&self, c, &mut err); + unicode_chars::check_for_substitution(self, c, &mut err); self.fatal_errs.push(err); Err(()) } @@ -1492,14 +1490,14 @@ impl<'a> StringReader<'a> { if self.ch_is('\n') { self.bump(); } - return val; + val } fn read_one_line_comment(&mut self) -> String { let val = self.read_to_eol(); assert!((val.as_bytes()[0] == b'/' && val.as_bytes()[1] == b'/') || (val.as_bytes()[0] == b'#' && val.as_bytes()[1] == b'!')); - return val; + val } fn consume_non_eol_whitespace(&mut self) { @@ -1543,7 +1541,7 @@ impl<'a> StringReader<'a> { Symbol::intern("?") }; self.bump(); // advance ch past token - return token::Byte(id); + token::Byte(id) } fn scan_byte_escape(&mut self, delim: char, below_0x7f_only: bool) -> bool { @@ -1576,7 +1574,7 @@ impl<'a> StringReader<'a> { Symbol::intern("??") }; self.bump(); - return token::ByteStr(id); + token::ByteStr(id) } fn scan_raw_byte_string(&mut self) -> token::Lit { @@ -1629,8 +1627,8 @@ impl<'a> StringReader<'a> { self.bump(); } self.bump(); - return token::ByteStrRaw(self.name_from_to(content_start_bpos, content_end_bpos), - hash_count); + token::ByteStrRaw(self.name_from_to(content_start_bpos, content_end_bpos), + hash_count) } } @@ -1648,7 +1646,7 @@ fn in_range(c: Option<char>, lo: char, hi: char) -> bool { } fn is_dec_digit(c: Option<char>) -> bool { - return in_range(c, '0', '9'); + in_range(c, '0', '9') } pub fn is_doc_comment(s: &str) -> bool { @@ -1718,13 +1716,13 @@ mod tests { sess: &'a ParseSess, teststr: String) -> StringReader<'a> { - let fm = cm.new_filemap("zebra.rs".to_string(), None, teststr); + let fm = cm.new_filemap("zebra.rs".to_string(), teststr); StringReader::new(sess, fm) } #[test] fn t1() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut string_reader = setup(&cm, &sh, @@ -1776,7 +1774,7 @@ mod tests { #[test] fn doublecolonparsing() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a b".to_string()), vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); @@ -1784,7 +1782,7 @@ mod tests { #[test] fn dcparsing_2() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a::b".to_string()), vec![mk_ident("a"), token::ModSep, mk_ident("b")]); @@ -1792,7 +1790,7 @@ mod tests { #[test] fn dcparsing_3() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a ::b".to_string()), vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); @@ -1800,7 +1798,7 @@ mod tests { #[test] fn dcparsing_4() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); check_tokenization(setup(&cm, &sh, "a:: b".to_string()), vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); @@ -1808,7 +1806,7 @@ mod tests { #[test] fn character_a() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern("a")), None)); @@ -1816,7 +1814,7 @@ mod tests { #[test] fn character_space() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern(" ")), None)); @@ -1824,7 +1822,7 @@ mod tests { #[test] fn character_escaped() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok, token::Literal(token::Char(Symbol::intern("\\n")), None)); @@ -1832,7 +1830,7 @@ mod tests { #[test] fn lifetime_name() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok, token::Lifetime(Ident::from_str("'abc"))); @@ -1840,7 +1838,7 @@ mod tests { #[test] fn raw_string() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); assert_eq!(setup(&cm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()) .next_token() @@ -1850,7 +1848,7 @@ mod tests { #[test] fn literal_suffixes() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); macro_rules! test { ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ @@ -1894,7 +1892,7 @@ mod tests { #[test] fn nested_block_comments() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut lexer = setup(&cm, &sh, "/* /* */ */'a'".to_string()); match lexer.next_token().tok { @@ -1907,7 +1905,7 @@ mod tests { #[test] fn crlf_comments() { - let cm = Rc::new(CodeMap::new()); + let cm = Rc::new(CodeMap::new(FilePathMapping::empty())); let sh = mk_sess(cm.clone()); let mut lexer = setup(&cm, &sh, "// test\r\n/// test\r\n".to_string()); let comment = lexer.next_token(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index c63a6524f74..1eff819d755 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -11,7 +11,7 @@ //! The main parser interface use ast::{self, CrateConfig}; -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use syntax_pos::{self, Span, FileMap, NO_EXPANSION}; use errors::{Handler, ColorConfig, DiagnosticBuilder}; use feature_gate::UnstableFeatures; @@ -53,8 +53,8 @@ pub struct ParseSess { } impl ParseSess { - pub fn new() -> Self { - let cm = Rc::new(CodeMap::new()); + pub fn new(file_path_mapping: FilePathMapping) -> Self { + let cm = Rc::new(CodeMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, @@ -107,18 +107,18 @@ pub fn parse_crate_attrs_from_file<'a>(input: &Path, sess: &'a ParseSess) parser.parse_inner_attributes() } -pub fn parse_crate_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, ast::Crate> { +pub fn parse_crate_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<ast::Crate> { new_parser_from_source_str(sess, name, source).parse_crate_mod() } -pub fn parse_crate_attrs_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Vec<ast::Attribute>> { +pub fn parse_crate_attrs_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<Vec<ast::Attribute>> { new_parser_from_source_str(sess, name, source).parse_inner_attributes() } -pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, P<ast::Expr>> { +pub fn parse_expr_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<P<ast::Expr>> { new_parser_from_source_str(sess, name, source).parse_expr() } @@ -126,30 +126,30 @@ pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a Pa /// /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err` /// when a syntax error occurred. -pub fn parse_item_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Option<P<ast::Item>>> { +pub fn parse_item_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<Option<P<ast::Item>>> { new_parser_from_source_str(sess, name, source).parse_item() } -pub fn parse_meta_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, ast::MetaItem> { +pub fn parse_meta_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<ast::MetaItem> { new_parser_from_source_str(sess, name, source).parse_meta_item() } -pub fn parse_stmt_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Option<ast::Stmt>> { +pub fn parse_stmt_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult<Option<ast::Stmt>> { new_parser_from_source_str(sess, name, source).parse_stmt() } -pub fn parse_stream_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) +pub fn parse_stream_from_source_str(name: String, source: String, sess: &ParseSess) -> TokenStream { - filemap_to_stream(sess, sess.codemap().new_filemap(name, None, source)) + filemap_to_stream(sess, sess.codemap().new_filemap(name, source)) } // Create a new parser from a source string -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, None, source)) +pub fn new_parser_from_source_str(sess: &ParseSess, name: String, source: String) + -> Parser { + filemap_to_parser(sess, sess.codemap().new_filemap(name, source)) } /// Create a new parser, handling errors as appropriate @@ -173,7 +173,7 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, } /// Given a filemap and config, return a parser -pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc<FileMap>, ) -> Parser<'a> { +pub fn filemap_to_parser(sess: & ParseSess, filemap: Rc<FileMap>, ) -> Parser { let end_pos = filemap.end_pos; let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap)); @@ -186,7 +186,7 @@ pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc<FileMap>, ) -> Par // must preserve old name for now, because quote! from the *existing* // compiler expands into it -pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec<TokenTree>) -> Parser<'a> { +pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser { stream_to_parser(sess, tts.into_iter().collect()) } @@ -216,8 +216,8 @@ pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc<FileMap>) -> TokenStream panictry!(srdr.parse_all_token_trees()) } -/// Given stream and the ParseSess, produce a parser -pub fn stream_to_parser<'a>(sess: &'a ParseSess, stream: TokenStream) -> Parser<'a> { +/// Given stream and the `ParseSess`, produce a parser +pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser { Parser::new(sess, stream, None, false) } @@ -251,7 +251,7 @@ pub fn char_lit(lit: &str) -> (char, isize) { (c, 4) } 'u' => { - assert!(lit.as_bytes()[2] == b'{'); + assert_eq!(lit.as_bytes()[2], b'{'); let idx = lit.find('}').unwrap(); let v = u32::from_str_radix(&lit[3..idx], 16).unwrap(); let c = char::from_u32(v).unwrap(); @@ -261,10 +261,14 @@ pub fn char_lit(lit: &str) -> (char, isize) { } } +pub fn escape_default(s: &str) -> String { + s.chars().map(char::escape_default).flat_map(|x| x).collect() +} + /// Parse a string representing a string literal into its final form. Does /// unescaping. pub fn str_lit(lit: &str) -> String { - debug!("parse_str_lit: given {}", lit.escape_default()); + debug!("parse_str_lit: given {}", escape_default(lit)); let mut res = String::with_capacity(lit.len()); // FIXME #8372: This could be a for-loop if it didn't borrow the iterator @@ -283,51 +287,46 @@ pub fn str_lit(lit: &str) -> String { } let mut chars = lit.char_indices().peekable(); - loop { - match chars.next() { - Some((i, c)) => { - match c { - '\\' => { - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; - - if ch == '\n' { - eat(&mut chars); - } else if ch == '\r' { - chars.next(); - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; - - if ch != '\n' { - panic!("lexer accepted bare CR"); - } - eat(&mut chars); - } else { - // otherwise, a normal escape - let (c, n) = char_lit(&lit[i..]); - for _ in 0..n - 1 { // we don't need to move past the first \ - chars.next(); - } - res.push(c); - } - }, - '\r' => { - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; + while let Some((i, c)) = chars.next() { + match c { + '\\' => { + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; + + if ch == '\n' { + eat(&mut chars); + } else if ch == '\r' { + chars.next(); + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; - if ch != '\n' { - panic!("lexer accepted bare CR"); - } + if ch != '\n' { + panic!("lexer accepted bare CR"); + } + eat(&mut chars); + } else { + // otherwise, a normal escape + let (c, n) = char_lit(&lit[i..]); + for _ in 0..n - 1 { // we don't need to move past the first \ chars.next(); - res.push('\n'); } - c => res.push(c), + res.push(c); } }, - None => break + '\r' => { + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; + + if ch != '\n' { + panic!("lexer accepted bare CR"); + } + chars.next(); + res.push('\n'); + } + c => res.push(c), } } @@ -339,25 +338,19 @@ pub fn str_lit(lit: &str) -> String { /// Parse a string representing a raw string literal into its final form. The /// only operation this does is convert embedded CRLF into a single LF. pub fn raw_str_lit(lit: &str) -> String { - debug!("raw_str_lit: given {}", lit.escape_default()); + debug!("raw_str_lit: given {}", escape_default(lit)); let mut res = String::with_capacity(lit.len()); - // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let mut chars = lit.chars().peekable(); - loop { - match chars.next() { - Some(c) => { - if c == '\r' { - if *chars.peek().unwrap() != '\n' { - panic!("lexer accepted bare CR"); - } - chars.next(); - res.push('\n'); - } else { - res.push(c); - } - }, - None => break + while let Some(c) = chars.next() { + if c == '\r' { + if *chars.peek().unwrap() != '\n' { + panic!("lexer accepted bare CR"); + } + chars.next(); + res.push('\n'); + } else { + res.push(c); } } @@ -455,7 +448,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { if lit.len() == 1 { (lit.as_bytes()[0], 1) } else { - assert!(lit.as_bytes()[0] == b'\\', err(0)); + assert_eq!(lit.as_bytes()[0], b'\\', "{}", err(0)); let b = match lit.as_bytes()[1] { b'"' => b'"', b'n' => b'\n', @@ -476,7 +469,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { } } }; - return (b, 2); + (b, 2) } } @@ -487,7 +480,7 @@ pub fn byte_str_lit(lit: &str) -> Rc<Vec<u8>> { let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace - fn eat<'a, I: Iterator<Item=(usize, u8)>>(it: &mut iter::Peekable<I>) { + fn eat<I: Iterator<Item=(usize, u8)>>(it: &mut iter::Peekable<I>) { loop { match it.peek().map(|x| x.1) { Some(b' ') | Some(b'\n') | Some(b'\r') | Some(b'\t') => { @@ -574,7 +567,7 @@ pub fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler if let Some(err) = err { err!(diag, |span, diag| diag.span_err(span, err)); } - return filtered_float_lit(Symbol::intern(&s), Some(suf), diag) + return filtered_float_lit(Symbol::intern(s), Some(suf), diag) } } @@ -828,7 +821,7 @@ mod tests { } #[test] fn parse_ident_pat () { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let mut parser = string_to_parser(&sess, "b".to_string()); assert!(panictry!(parser.parse_pat()) == P(ast::Pat{ @@ -998,7 +991,7 @@ mod tests { } #[test] fn crlf_doc_comments() { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let name = "<source>".to_string(); let source = "/// doc comment\r\nfn foo() {}".to_string(); @@ -1023,7 +1016,7 @@ mod tests { #[test] fn ttdelim_span() { - let sess = ParseSess::new(); + let sess = ParseSess::new(FilePathMapping::empty()); let expr = parse::parse_expr_from_source_str("foo".to_string(), "foo!( fn main() { body } )".to_string(), &sess).unwrap(); diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index d5baec675e4..078e86aa294 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -59,7 +59,7 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { if !self.obsolete_set.contains(&kind) && (error || self.sess.span_diagnostic.can_emit_warnings) { - err.note(&format!("{}", desc)); + err.note(desc); self.obsolete_set.insert(kind); } err.emit(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1baf0d1b54c..4741f896d3c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -57,12 +57,14 @@ use tokenstream::{self, Delimited, ThinTokenStream, TokenTree, TokenStream}; use symbol::{Symbol, keywords}; use util::ThinVec; +use std::cmp; use std::collections::HashSet; -use std::{cmp, mem, slice}; +use std::mem; use std::path::{self, Path, PathBuf}; +use std::slice; bitflags! { - flags Restrictions: u8 { + pub flags Restrictions: u8 { const RESTRICTION_STMT_EXPR = 1 << 0, const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1, } @@ -246,7 +248,7 @@ impl TokenCursor { fn next_desugared(&mut self) -> TokenAndSpan { let (sp, name) = match self.next() { TokenAndSpan { sp, tok: token::DocComment(name) } => (sp, name), - tok @ _ => return tok, + tok => return tok, }; let stripped = strip_doc_comment_decoration(&name.as_str()); @@ -352,7 +354,7 @@ pub enum Error { } impl Error { - pub fn span_err<'a>(self, sp: Span, handler: &'a errors::Handler) -> DiagnosticBuilder<'a> { + pub fn span_err(self, sp: Span, handler: &errors::Handler) -> DiagnosticBuilder { match self { Error::FileNotFoundForModule { ref mod_name, ref default_path, @@ -476,9 +478,10 @@ impl<'a> Parser<'a> { } fn next_tok(&mut self) -> TokenAndSpan { - let mut next = match self.desugar_doc_comments { - true => self.token_cursor.next_desugared(), - false => self.token_cursor.next(), + let mut next = if self.desugar_doc_comments { + self.token_cursor.next_desugared() + } else { + self.token_cursor.next() }; if next.sp == syntax_pos::DUMMY_SP { next.sp = self.prev_span; @@ -549,7 +552,7 @@ impl<'a> Parser<'a> { // This might be a sign we need a connect method on Iterator. let b = i.next() .map_or("".to_string(), |t| t.to_string()); - i.enumerate().fold(b, |mut b, (i, ref a)| { + i.enumerate().fold(b, |mut b, (i, a)| { if tokens.len() > 2 && i == tokens.len() - 2 { b.push_str(", or "); } else if tokens.len() == 2 && i == tokens.len() - 2 { @@ -600,10 +603,10 @@ impl<'a> Parser<'a> { label_sp }; if self.span.contains(sp) { - err.span_label(self.span, &label_exp); + err.span_label(self.span, label_exp); } else { - err.span_label(sp, &label_exp); - err.span_label(self.span, &"unexpected token"); + err.span_label(sp, label_exp); + err.span_label(self.span, "unexpected token"); } Err(err) } @@ -983,18 +986,15 @@ impl<'a> Parser<'a> { token::CloseDelim(..) | token::Eof => break, _ => {} }; - match sep.sep { - Some(ref t) => { - if first { - first = false; - } else { - if let Err(e) = self.expect(t) { - fe(e); - break; - } + if let Some(ref t) = sep.sep { + if first { + first = false; + } else { + if let Err(e) = self.expect(t) { + fe(e); + break; } } - _ => () } if sep.trailing_sep_allowed && kets.iter().any(|k| self.check(k)) { break; @@ -1451,9 +1451,9 @@ impl<'a> Parser<'a> { } else if self.eat_keyword(keywords::Impl) { // FIXME: figure out priority of `+` in `impl Trait1 + Trait2` (#34511). TyKind::ImplTrait(self.parse_ty_param_bounds()?) - } else if self.check(&token::Question) { + } else if self.check(&token::Question) || + self.check_lifetime() && self.look_ahead(1, |t| t == &token::BinOp(token::Plus)){ // Bound list (trait object type) - // Bound lists starting with `'lt` are not currently supported (#40043) TyKind::TraitObject(self.parse_ty_param_bounds_common(allow_plus)?) } else { let msg = format!("expected type, found {}", self.this_token_descr()); @@ -1490,9 +1490,8 @@ impl<'a> Parser<'a> { let bounds = self.parse_ty_param_bounds()?; let sum_span = ty.span.to(self.prev_span); - let mut err = struct_span_err!(self.sess.span_diagnostic, ty.span, E0178, - "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(&ty)); - err.span_label(ty.span, &format!("expected a path")); + let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178, + "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(ty)); match ty.node { TyKind::Rptr(ref lifetime, ref mut_ty) => { @@ -1511,9 +1510,11 @@ impl<'a> Parser<'a> { err.span_suggestion(sum_span, "try adding parentheses:", sum_with_parens); } TyKind::Ptr(..) | TyKind::BareFn(..) => { - help!(&mut err, "perhaps you forgot parentheses?"); + err.span_label(sum_span, "perhaps you forgot parentheses?"); } - _ => {} + _ => { + err.span_label(sum_span, "expected a path"); + }, } err.emit(); Ok(()) @@ -1544,7 +1545,7 @@ impl<'a> Parser<'a> { pub fn is_named_argument(&mut self) -> bool { let offset = match self.token { - token::BinOp(token::And) => 1, + token::BinOp(token::And) | token::AndAnd => 1, _ if self.token.is_keyword(keywords::Mut) => 1, _ => 0 @@ -2288,7 +2289,7 @@ impl<'a> Parser<'a> { let e = if self.token.can_begin_expr() && !(self.token == token::OpenDelim(token::Brace) && self.restrictions.contains( - Restrictions::RESTRICTION_NO_STRUCT_LITERAL)) { + RESTRICTION_NO_STRUCT_LITERAL)) { Some(self.parse_expr()?) } else { None @@ -2315,7 +2316,7 @@ impl<'a> Parser<'a> { // This is a struct literal, unless we're prohibited // from parsing struct literals here. let prohibited = self.restrictions.contains( - Restrictions::RESTRICTION_NO_STRUCT_LITERAL + RESTRICTION_NO_STRUCT_LITERAL ); if !prohibited { return self.parse_struct_expr(lo, pth, attrs); @@ -2553,7 +2554,7 @@ impl<'a> Parser<'a> { let fstr = n.as_str(); let mut err = self.diagnostic().struct_span_err(self.prev_span, &format!("unexpected token: `{}`", n)); - err.span_label(self.prev_span, &"unexpected token"); + err.span_label(self.prev_span, "unexpected token"); if fstr.chars().all(|x| "0123456789.".contains(x)) { let float = match fstr.parse::<f64>().ok() { Some(f) => f, @@ -2697,6 +2698,19 @@ impl<'a> Parser<'a> { let (span, e) = self.interpolated_or_expr_span(e)?; (span, self.mk_unary(UnOp::Not, e)) } + // Suggest `!` for bitwise negation when encountering a `~` + token::Tilde => { + self.bump(); + let e = self.parse_prefix_expr(None); + let (span, e) = self.interpolated_or_expr_span(e)?; + let span_of_tilde = lo; + let mut err = self.diagnostic().struct_span_err(span_of_tilde, + "`~` can not be used as a unary operator"); + err.span_label(span_of_tilde, "did you mean `!`?"); + err.help("use `!` instead of `~` if you meant to perform bitwise negation"); + err.emit(); + (span, self.mk_unary(UnOp::Not, e)) + } token::BinOp(token::Minus) => { self.bump(); let e = self.parse_prefix_expr(None); @@ -2719,7 +2733,7 @@ impl<'a> Parser<'a> { token::Ident(..) if self.token.is_keyword(keywords::In) => { self.bump(); let place = self.parse_expr_res( - Restrictions::RESTRICTION_NO_STRUCT_LITERAL, + RESTRICTION_NO_STRUCT_LITERAL, None, )?; let blk = self.parse_block()?; @@ -2782,7 +2796,7 @@ impl<'a> Parser<'a> { let cur_op_span = self.span; let restrictions = if op.is_assign_like() { - self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL + self.restrictions & RESTRICTION_NO_STRUCT_LITERAL } else { self.restrictions }; @@ -2832,13 +2846,13 @@ impl<'a> Parser<'a> { let rhs = match op.fixity() { Fixity::Right => self.with_res( - restrictions - Restrictions::RESTRICTION_STMT_EXPR, + restrictions - RESTRICTION_STMT_EXPR, |this| { this.parse_assoc_expr_with(op.precedence(), LhsExpr::NotYetParsed) }), Fixity::Left => self.with_res( - restrictions - Restrictions::RESTRICTION_STMT_EXPR, + restrictions - RESTRICTION_STMT_EXPR, |this| { this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed) @@ -2846,7 +2860,7 @@ impl<'a> Parser<'a> { // We currently have no non-associative operators that are not handled above by // the special cases. The code is here only for future convenience. Fixity::None => self.with_res( - restrictions - Restrictions::RESTRICTION_STMT_EXPR, + restrictions - RESTRICTION_STMT_EXPR, |this| { this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed) @@ -2956,7 +2970,7 @@ impl<'a> Parser<'a> { if self.token.can_begin_expr() { // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`. if self.token == token::OpenDelim(token::Brace) { - return !self.restrictions.contains(Restrictions::RESTRICTION_NO_STRUCT_LITERAL); + return !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL); } true } else { @@ -2970,7 +2984,7 @@ impl<'a> Parser<'a> { return self.parse_if_let_expr(attrs); } let lo = self.prev_span; - let cond = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?; + let cond = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; let thn = self.parse_block()?; let mut els: Option<P<Expr>> = None; let mut hi = thn.span; @@ -2989,7 +3003,7 @@ impl<'a> Parser<'a> { self.expect_keyword(keywords::Let)?; let pat = self.parse_pat()?; self.expect(&token::Eq)?; - let expr = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?; + let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; let thn = self.parse_block()?; let (hi, els) = if self.eat_keyword(keywords::Else) { let expr = self.parse_else_expr()?; @@ -3043,7 +3057,7 @@ impl<'a> Parser<'a> { let pat = self.parse_pat()?; self.expect_keyword(keywords::In)?; - let expr = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?; + let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); @@ -3058,7 +3072,7 @@ impl<'a> Parser<'a> { if self.token.is_keyword(keywords::Let) { return self.parse_while_let_expr(opt_ident, span_lo, attrs); } - let cond = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?; + let cond = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); let span = span_lo.to(body.span); @@ -3072,7 +3086,7 @@ impl<'a> Parser<'a> { self.expect_keyword(keywords::Let)?; let pat = self.parse_pat()?; self.expect(&token::Eq)?; - let expr = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)?; + let expr = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); let span = span_lo.to(body.span); @@ -3102,7 +3116,7 @@ impl<'a> Parser<'a> { fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> { let match_span = self.prev_span; let lo = self.prev_span; - let discriminant = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, + let discriminant = self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL, None)?; if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) { if self.token == token::Token::Semi { @@ -3138,12 +3152,13 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; let pats = self.parse_pats()?; - let mut guard = None; - if self.eat_keyword(keywords::If) { - guard = Some(self.parse_expr()?); - } + let guard = if self.eat_keyword(keywords::If) { + Some(self.parse_expr()?) + } else { + None + }; self.expect(&token::FatArrow)?; - let expr = self.parse_expr_res(Restrictions::RESTRICTION_STMT_EXPR, None)?; + let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR, None)?; let require_comma = !classify::expr_is_simple_block(&expr) @@ -3584,10 +3599,11 @@ impl<'a> Parser<'a> { let lo = self.span; let pat = self.parse_pat()?; - let mut ty = None; - if self.eat(&token::Colon) { - ty = Some(self.parse_ty()?); - } + let ty = if self.eat(&token::Colon) { + Some(self.parse_ty()?) + } else { + None + }; let init = self.parse_initializer()?; Ok(P(ast::Local { ty: ty, @@ -3724,7 +3740,7 @@ impl<'a> Parser<'a> { self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) && // prevent `while catch {} {}`, `if catch {} {} else {}`, etc. - !self.restrictions.contains(Restrictions::RESTRICTION_NO_STRUCT_LITERAL) + !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL) } fn is_union_item(&self) -> bool { @@ -3796,7 +3812,7 @@ impl<'a> Parser<'a> { self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new()) }; - let expr = self.with_res(Restrictions::RESTRICTION_STMT_EXPR, |this| { + let expr = self.with_res(RESTRICTION_STMT_EXPR, |this| { let expr = this.parse_dot_or_call_expr_with(expr, lo, attrs.into())?; this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr)) })?; @@ -3913,7 +3929,7 @@ impl<'a> Parser<'a> { }, None => { let unused_attrs = |attrs: &[_], s: &mut Self| { - if attrs.len() > 0 { + if !attrs.is_empty() { if s.prev_token_kind == PrevTokenKind::DocComment { s.span_fatal_err(s.prev_span, Error::UselessDocComment).emit(); } else { @@ -3936,7 +3952,7 @@ impl<'a> Parser<'a> { // Remainder are line-expr stmts. let e = self.parse_expr_res( - Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into()))?; + RESTRICTION_STMT_EXPR, Some(attrs.into()))?; Stmt { id: ast::DUMMY_NODE_ID, span: lo.to(e.span), @@ -3949,7 +3965,7 @@ impl<'a> Parser<'a> { /// Is this expression a successfully-parsed statement? fn expr_is_complete(&mut self, e: &Expr) -> bool { - self.restrictions.contains(Restrictions::RESTRICTION_STMT_EXPR) && + self.restrictions.contains(RESTRICTION_STMT_EXPR) && !classify::expr_requires_semi_to_be_stmt(e) } @@ -4776,7 +4792,7 @@ impl<'a> Parser<'a> { sp, &format!("missing `fn`, `type`, or `const` for {}-item declaration", item_type)); - err.span_label(sp, &"missing `fn`, `type`, or `const`"); + err.span_label(sp, "missing `fn`, `type`, or `const`"); err } @@ -4799,7 +4815,7 @@ impl<'a> Parser<'a> { self.expect(&token::Not)?; } - self.complain_if_pub_macro(&vis, prev_span); + self.complain_if_pub_macro(vis, prev_span); // eat a matched-delimiter token tree: *at_end = true; @@ -4863,7 +4879,9 @@ impl<'a> Parser<'a> { /// impl<T> Foo { ... } /// impl<T> ToString for &'static T { ... } /// impl Send for .. {} - fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> { + fn parse_item_impl(&mut self, + unsafety: ast::Unsafety, + defaultness: Defaultness) -> PResult<'a, ItemInfo> { let impl_span = self.span; // First, parse type parameters if necessary. @@ -4899,13 +4917,10 @@ impl<'a> Parser<'a> { } } } else { - match polarity { - ast::ImplPolarity::Negative => { - // This is a negated type implementation - // `impl !MyType {}`, which is not allowed. - self.span_err(neg_span, "inherent implementation can't be negated"); - }, - _ => {} + if polarity == ast::ImplPolarity::Negative { + // This is a negated type implementation + // `impl !MyType {}`, which is not allowed. + self.span_err(neg_span, "inherent implementation can't be negated"); } None }; @@ -4916,6 +4931,11 @@ impl<'a> Parser<'a> { allowed to have generics"); } + if let ast::Defaultness::Default = defaultness { + self.span_err(impl_span, "`default impl` is not allowed for \ + default trait implementations"); + } + self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::CloseDelim(token::Brace))?; Ok((keywords::Invalid.ident(), @@ -4944,7 +4964,7 @@ impl<'a> Parser<'a> { } Ok((keywords::Invalid.ident(), - ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items), + ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items), Some(attrs))) } } @@ -5122,7 +5142,6 @@ impl<'a> Parser<'a> { } if self.check(&token::OpenDelim(token::Paren)) { - let start_span = self.span; // We don't `self.bump()` the `(` yet because this might be a struct definition where // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`. // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so @@ -5161,12 +5180,9 @@ impl<'a> Parser<'a> { `pub(in path::to::module)`: visible only on the specified path"##; let path = self.parse_path(PathStyle::Mod)?; let path_span = self.prev_span; - let help_msg = format!("to make this visible only to module `{}`, add `in` before \ - the path:", - path); + let help_msg = format!("make this visible only to module `{}` with `in`:", path); self.expect(&token::CloseDelim(token::Paren))?; // `)` - let sp = start_span.to(self.prev_span); - let mut err = self.span_fatal_help(sp, &msg, &suggestion); + let mut err = self.span_fatal_help(path_span, msg, suggestion); err.span_suggestion(path_span, &help_msg, format!("in {}", path)); err.emit(); // emit diagnostic, but continue with public visibility } @@ -5363,24 +5379,25 @@ impl<'a> Parser<'a> { } let mut err = self.diagnostic().struct_span_err(id_sp, "cannot declare a new module at this location"); - let this_module = match self.directory.path.file_name() { - Some(file_name) => file_name.to_str().unwrap().to_owned(), - None => self.root_module_name.as_ref().unwrap().clone(), - }; - err.span_note(id_sp, - &format!("maybe move this module `{0}` to its own directory \ - via `{0}{1}mod.rs`", - this_module, - path::MAIN_SEPARATOR)); + if id_sp != syntax_pos::DUMMY_SP { + let src_path = PathBuf::from(self.sess.codemap().span_to_filename(id_sp)); + if let Some(stem) = src_path.file_stem() { + let mut dest_path = src_path.clone(); + dest_path.set_file_name(stem); + dest_path.push("mod.rs"); + err.span_note(id_sp, + &format!("maybe move this module `{}` to its own \ + directory via `{}`", src_path.to_string_lossy(), + dest_path.to_string_lossy())); + } + } if paths.path_exists { err.span_note(id_sp, &format!("... or maybe `use` the module `{}` instead \ of possibly redeclaring it", paths.name)); - Err(err) - } else { - Err(err) } + Err(err) } else { paths.result.map_err(|err| self.span_fatal_err(id_sp, err)) } @@ -5756,13 +5773,19 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } - if self.check_keyword(keywords::Unsafe) && - self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) + if (self.check_keyword(keywords::Unsafe) && + self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) || + (self.check_keyword(keywords::Default) && + self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) && + self.look_ahead(2, |t| t.is_keyword(keywords::Impl))) { // IMPL ITEM + let defaultness = self.parse_defaultness()?; self.expect_keyword(keywords::Unsafe)?; self.expect_keyword(keywords::Impl)?; - let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe)?; + let (ident, + item_, + extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe, defaultness)?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -5856,9 +5879,16 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } - if self.eat_keyword(keywords::Impl) { + if (self.check_keyword(keywords::Impl)) || + (self.check_keyword(keywords::Default) && + self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) + { // IMPL ITEM - let (ident, item_, extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal)?; + let defaultness = self.parse_defaultness()?; + self.expect_keyword(keywords::Impl)?; + let (ident, + item_, + extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal, defaultness)?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 25cabef70c1..77db604c56e 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -53,6 +53,10 @@ impl DelimToken { pub fn len(self) -> usize { if self == NoDelim { 0 } else { 1 } } + + pub fn is_empty(self) -> bool { + self == NoDelim + } } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] @@ -198,17 +202,17 @@ impl Token { pub fn can_begin_expr(&self) -> bool { match *self { Ident(ident) => ident_can_begin_expr(ident), // value name or keyword - OpenDelim(..) => true, // tuple, array or block - Literal(..) => true, // literal - Not => true, // operator not - BinOp(Minus) => true, // unary minus - BinOp(Star) => true, // dereference - BinOp(Or) | OrOr => true, // closure - BinOp(And) => true, // reference - AndAnd => true, // double reference - DotDot | DotDotDot => true, // range notation - Lt | BinOp(Shl) => true, // associated path - ModSep => true, // global path + OpenDelim(..) | // tuple, array or block + Literal(..) | // literal + Not | // operator not + BinOp(Minus) | // unary minus + BinOp(Star) | // dereference + BinOp(Or) | OrOr | // closure + BinOp(And) | // reference + AndAnd | // double reference + DotDot | DotDotDot | // range notation + Lt | BinOp(Shl) | // associated path + ModSep | // global path Pound => true, // expression attributes Interpolated(ref nt) => match **nt { NtIdent(..) | NtExpr(..) | NtBlock(..) | NtPath(..) => true, @@ -222,16 +226,16 @@ impl Token { pub fn can_begin_type(&self) -> bool { match *self { Ident(ident) => ident_can_begin_type(ident), // type name or keyword - OpenDelim(Paren) => true, // tuple - OpenDelim(Bracket) => true, // array - Underscore => true, // placeholder - Not => true, // never - BinOp(Star) => true, // raw pointer - BinOp(And) => true, // reference - AndAnd => true, // double reference - Question => true, // maybe bound in trait object - Lifetime(..) => true, // lifetime bound in trait object - Lt | BinOp(Shl) => true, // associated path + OpenDelim(Paren) | // tuple + OpenDelim(Bracket) | // array + Underscore | // placeholder + Not | // never + BinOp(Star) | // raw pointer + BinOp(And) | // reference + AndAnd | // double reference + Question | // maybe bound in trait object + Lifetime(..) | // lifetime bound in trait object + Lt | BinOp(Shl) | // associated path ModSep => true, // global path Interpolated(ref nt) => match **nt { NtIdent(..) | NtTy(..) | NtPath(..) => true, diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 1d67c2a2c2b..e893c859247 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -113,22 +113,22 @@ //! between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer //! and point-in-infinite-stream senses freely. //! -//! There is a parallel ring buffer, 'size', that holds the calculated size of +//! There is a parallel ring buffer, `size`, that holds the calculated size of //! each token. Why calculated? Because for Begin/End pairs, the "size" //! includes everything between the pair. That is, the "size" of Begin is //! actually the sum of the sizes of everything between Begin and the paired -//! End that follows. Since that is arbitrarily far in the future, 'size' is +//! End that follows. Since that is arbitrarily far in the future, `size` is //! being rewritten regularly while the printer runs; in fact most of the -//! machinery is here to work out 'size' entries on the fly (and give up when +//! machinery is here to work out `size` entries on the fly (and give up when //! they're so obviously over-long that "infinity" is a good enough //! approximation for purposes of line breaking). //! //! The "input side" of the printer is managed as an abstract process called -//! SCAN, which uses 'scan_stack', to manage calculating 'size'. SCAN is, in +//! SCAN, which uses `scan_stack`, to manage calculating `size`. SCAN is, in //! other words, the process of calculating 'size' entries. //! //! The "output side" of the printer is managed by an abstract process called -//! PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to +//! PRINT, which uses `print_stack`, `margin` and `space` to figure out what to //! do with each token/size pair it consumes as it goes. It's trying to consume //! the entire buffered window, but can't output anything until the size is >= //! 0 (sizes are set to negative while they're pending calculation). @@ -409,7 +409,7 @@ impl<'a> Printer<'a> { pub fn advance_right(&mut self) { self.right += 1; self.right %= self.buf_len; - assert!(self.right != self.left); + assert_ne!(self.right, self.left); } pub fn advance_left(&mut self) -> io::Result<()> { debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index be1d26f8fe4..83c289ff80b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -233,7 +233,7 @@ pub fn token_to_string(tok: &Token) -> String { token::CloseDelim(token::Bracket) => "]".to_string(), token::OpenDelim(token::Brace) => "{".to_string(), token::CloseDelim(token::Brace) => "}".to_string(), - token::OpenDelim(token::NoDelim) => " ".to_string(), + token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => " ".to_string(), token::Pound => "#".to_string(), token::Dollar => "$".to_string(), @@ -244,7 +244,7 @@ pub fn token_to_string(tok: &Token) -> String { let mut out = match lit { token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), - token::Float(c) => c.to_string(), + token::Float(c) | token::Integer(c) => c.to_string(), token::Str_(s) => format!("\"{}\"", s), token::StrRaw(s, n) => format!("r{delim}\"{string}\"{delim}", @@ -277,23 +277,23 @@ pub fn token_to_string(tok: &Token) -> String { token::Shebang(s) => format!("/* shebang: {}*/", s), token::Interpolated(ref nt) => match **nt { - token::NtExpr(ref e) => expr_to_string(&e), - token::NtMeta(ref e) => meta_item_to_string(&e), - token::NtTy(ref e) => ty_to_string(&e), - token::NtPath(ref e) => path_to_string(&e), - token::NtItem(ref e) => item_to_string(&e), - token::NtBlock(ref e) => block_to_string(&e), - token::NtStmt(ref e) => stmt_to_string(&e), - token::NtPat(ref e) => pat_to_string(&e), + token::NtExpr(ref e) => expr_to_string(e), + token::NtMeta(ref e) => meta_item_to_string(e), + token::NtTy(ref e) => ty_to_string(e), + token::NtPath(ref e) => path_to_string(e), + token::NtItem(ref e) => item_to_string(e), + token::NtBlock(ref e) => block_to_string(e), + token::NtStmt(ref e) => stmt_to_string(e), + token::NtPat(ref e) => pat_to_string(e), token::NtIdent(ref e) => ident_to_string(e.node), token::NtTT(ref tree) => tt_to_string(tree.clone()), - token::NtArm(ref e) => arm_to_string(&e), - token::NtImplItem(ref e) => impl_item_to_string(&e), - token::NtTraitItem(ref e) => trait_item_to_string(&e), - token::NtGenerics(ref e) => generics_to_string(&e), - token::NtWhereClause(ref e) => where_clause_to_string(&e), - token::NtArg(ref e) => arg_to_string(&e), - token::NtVis(ref e) => vis_to_string(&e), + token::NtArm(ref e) => arm_to_string(e), + token::NtImplItem(ref e) => impl_item_to_string(e), + token::NtTraitItem(ref e) => trait_item_to_string(e), + token::NtGenerics(ref e) => generics_to_string(e), + token::NtWhereClause(ref e) => where_clause_to_string(e), + token::NtArg(ref e) => arg_to_string(e), + token::NtVis(ref e) => vis_to_string(e), } } } @@ -520,8 +520,7 @@ pub trait PrintState<'a> { let mut result = None; - if let &Some(ref lits) = self.literals() - { + if let Some(ref lits) = *self.literals() { while cur_lit < lits.len() { let ltrl = (*lits)[cur_lit].clone(); if ltrl.pos > pos { break; } @@ -618,11 +617,8 @@ pub trait PrintState<'a> { fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { self.maybe_print_comment(lit.span.lo)?; - match self.next_lit(lit.span.lo) { - Some(ref ltrl) => { - return word(self.writer(), &(*ltrl).lit); - } - _ => () + if let Some(ref ltrl) = self.next_lit(lit.span.lo) { + return word(self.writer(), &(*ltrl).lit); } match lit.node { ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), @@ -677,7 +673,7 @@ pub trait PrintState<'a> { style: ast::StrStyle) -> io::Result<()> { let st = match style { ast::StrStyle::Cooked => { - (format!("\"{}\"", st.escape_default())) + (format!("\"{}\"", parse::escape_default(st))) } ast::StrStyle::Raw(n) => { (format!("r{delim}\"{string}\"{delim}", @@ -799,7 +795,7 @@ pub trait PrintState<'a> { self.popen()?; self.commasep(Consistent, &items[..], - |s, i| s.print_meta_list_item(&i))?; + |s, i| s.print_meta_list_item(i))?; self.pclose()?; } } @@ -982,14 +978,14 @@ impl<'a> State<'a> { pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) -> io::Result<()> { - self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span) + self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span) } pub fn print_mod(&mut self, _mod: &ast::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { self.print_inner_attributes(attrs)?; for item in &_mod.items { - self.print_item(&item)?; + self.print_item(item)?; } Ok(()) } @@ -1018,7 +1014,7 @@ impl<'a> State<'a> { match ty.node { ast::TyKind::Slice(ref ty) => { word(&mut self.s, "[")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, "]")?; } ast::TyKind::Ptr(ref mt) => { @@ -1040,7 +1036,7 @@ impl<'a> State<'a> { ast::TyKind::Tup(ref elts) => { self.popen()?; self.commasep(Inconsistent, &elts[..], - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; if elts.len() == 1 { word(&mut self.s, ",")?; } @@ -1048,7 +1044,7 @@ impl<'a> State<'a> { } ast::TyKind::Paren(ref typ) => { self.popen()?; - self.print_type(&typ)?; + self.print_type(typ)?; self.pclose()?; } ast::TyKind::BareFn(ref f) => { @@ -1081,14 +1077,14 @@ impl<'a> State<'a> { } ast::TyKind::Array(ref ty, ref v) => { word(&mut self.s, "[")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, "; ")?; - self.print_expr(&v)?; + self.print_expr(v)?; word(&mut self.s, "]")?; } ast::TyKind::Typeof(ref e) => { word(&mut self.s, "typeof(")?; - self.print_expr(&e)?; + self.print_expr(e)?; word(&mut self.s, ")")?; } ast::TyKind::Infer => { @@ -1130,7 +1126,7 @@ impl<'a> State<'a> { } self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&t)?; + self.print_type(t)?; word(&mut self.s, ";")?; self.end()?; // end the head-ibox self.end() // end the outer cbox @@ -1187,7 +1183,7 @@ impl<'a> State<'a> { self.head(&visibility_qualified(&item.vis, "extern crate"))?; if let Some(p) = *optional_path { let val = p.as_str(); - if val.contains("-") { + if val.contains('-') { self.print_string(&val, ast::StrStyle::Cooked)?; } else { self.print_name(p)?; @@ -1203,7 +1199,7 @@ impl<'a> State<'a> { } ast::ItemKind::Use(ref vp) => { self.head(&visibility_qualified(&item.vis, "use"))?; - self.print_view_path(&vp)?; + self.print_view_path(vp)?; word(&mut self.s, ";")?; self.end()?; // end inner head-block self.end()?; // end outer head-block @@ -1215,12 +1211,12 @@ impl<'a> State<'a> { } self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; space(&mut self.s)?; self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } @@ -1228,12 +1224,12 @@ impl<'a> State<'a> { self.head(&visibility_qualified(&item.vis, "const"))?; self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; space(&mut self.s)?; self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } @@ -1249,7 +1245,7 @@ impl<'a> State<'a> { &item.vis )?; word(&mut self.s, " ")?; - self.print_block_with_attrs(&body, &item.attrs)?; + self.print_block_with_attrs(body, &item.attrs)?; } ast::ItemKind::Mod(ref _mod) => { self.head(&visibility_qualified(&item.vis, "mod"))?; @@ -1282,7 +1278,7 @@ impl<'a> State<'a> { self.print_where_clause(¶ms.where_clause)?; space(&mut self.s)?; self.word_space("=")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, ";")?; self.end()?; // end the outer ibox } @@ -1297,11 +1293,11 @@ impl<'a> State<'a> { } 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)?; + self.print_struct(struct_def, generics, item.ident, item.span, true)?; } ast::ItemKind::Union(ref struct_def, ref generics) => { self.head(&visibility_qualified(&item.vis, "union"))?; - self.print_struct(&struct_def, generics, item.ident, item.span, true)?; + self.print_struct(struct_def, generics, item.ident, item.span, true)?; } ast::ItemKind::DefaultImpl(unsafety, ref trait_ref) => { self.head("")?; @@ -1317,12 +1313,14 @@ impl<'a> State<'a> { } ast::ItemKind::Impl(unsafety, polarity, + defaultness, ref generics, ref opt_trait, ref ty, ref impl_items) => { self.head("")?; self.print_visibility(&item.vis)?; + self.print_defaultness(defaultness)?; self.print_unsafety(unsafety)?; self.word_nbsp("impl")?; @@ -1331,11 +1329,8 @@ impl<'a> State<'a> { space(&mut self.s)?; } - match polarity { - ast::ImplPolarity::Negative => { - word(&mut self.s, "!")?; - }, - _ => {} + if polarity == ast::ImplPolarity::Negative { + word(&mut self.s, "!")?; } if let Some(ref t) = *opt_trait { @@ -1344,7 +1339,7 @@ impl<'a> State<'a> { self.word_space("for")?; } - self.print_type(&ty)?; + self.print_type(ty)?; self.print_where_clause(&generics.where_clause)?; space(&mut self.s)?; @@ -1477,6 +1472,13 @@ impl<'a> State<'a> { } } + pub fn print_defaultness(&mut self, defatulness: ast::Defaultness) -> io::Result<()> { + if let ast::Defaultness::Default = defatulness { + try!(self.word_nbsp("default")); + } + Ok(()) + } + pub fn print_struct(&mut self, struct_def: &ast::VariantData, generics: &ast::Generics, @@ -1534,7 +1536,7 @@ impl<'a> State<'a> { Some(ref d) => { space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&d) + self.print_expr(d) } _ => Ok(()) } @@ -1562,7 +1564,7 @@ impl<'a> State<'a> { self.print_outer_attributes(&ti.attrs)?; match ti.node { ast::TraitItemKind::Const(ref ty, ref default) => { - self.print_associated_const(ti.ident, &ty, + self.print_associated_const(ti.ident, ty, default.as_ref().map(|expr| &**expr), &ast::Visibility::Inherited)?; } @@ -1602,12 +1604,10 @@ impl<'a> State<'a> { self.hardbreak_if_not_bol()?; self.maybe_print_comment(ii.span.lo)?; self.print_outer_attributes(&ii.attrs)?; - if let ast::Defaultness::Default = ii.defaultness { - self.word_nbsp("default")?; - } + self.print_defaultness(ii.defaultness)?; match ii.node { ast::ImplItemKind::Const(ref ty, ref expr) => { - self.print_associated_const(ii.ident, &ty, Some(&expr), &ii.vis)?; + self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis)?; } ast::ImplItemKind::Method(ref sig, ref body) => { self.head("")?; @@ -1643,38 +1643,38 @@ impl<'a> State<'a> { self.word_nbsp("let")?; self.ibox(INDENT_UNIT)?; - self.print_local_decl(&loc)?; + self.print_local_decl(loc)?; self.end()?; if let Some(ref init) = loc.init { self.nbsp()?; self.word_space("=")?; - self.print_expr(&init)?; + self.print_expr(init)?; } word(&mut self.s, ";")?; self.end()?; } - ast::StmtKind::Item(ref item) => self.print_item(&item)?, + ast::StmtKind::Item(ref item) => self.print_item(item)?, ast::StmtKind::Expr(ref expr) => { self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; if parse::classify::expr_requires_semi_to_be_stmt(expr) { word(&mut self.s, ";")?; } } ast::StmtKind::Semi(ref expr) => { self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; word(&mut self.s, ";")?; } ast::StmtKind::Mac(ref mac) => { let (ref mac, style, ref attrs) = **mac; self.space_if_not_bol()?; - self.print_outer_attributes(&attrs)?; + self.print_outer_attributes(attrs)?; let delim = match style { ast::MacStmtStyle::Braces => token::Brace, _ => token::Paren }; - self.print_mac(&mac, delim)?; + self.print_mac(mac, delim)?; if style == ast::MacStmtStyle::Semicolon { word(&mut self.s, ";")?; } @@ -1728,7 +1728,7 @@ impl<'a> State<'a> { ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { self.maybe_print_comment(st.span.lo)?; self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?; } _ => self.print_stmt(st)?, @@ -1748,9 +1748,9 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else if ")?; - self.print_expr(&i)?; + self.print_expr(i)?; space(&mut self.s)?; - self.print_block(&then)?; + self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } // "another else-if-let" @@ -1758,12 +1758,12 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else if let ")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; space(&mut self.s)?; - self.print_block(&then)?; + self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } // "final else" @@ -1771,7 +1771,7 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else ")?; - self.print_block(&b) + self.print_block(b) } // BLEAH, constraints would be great here _ => { @@ -1837,12 +1837,8 @@ impl<'a> State<'a> { binop: ast::BinOp) -> bool { match sub_expr.node { ast::ExprKind::Binary(ref sub_op, _, _) => { - if AssocOp::from_ast_binop(sub_op.node).precedence() < - AssocOp::from_ast_binop(binop.node).precedence() { - true - } else { - false - } + AssocOp::from_ast_binop(sub_op.node).precedence() < + AssocOp::from_ast_binop(binop.node).precedence() } _ => true } @@ -1922,7 +1918,7 @@ impl<'a> State<'a> { space(&mut self.s)?; } word(&mut self.s, "..")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; self.end()?; } _ => if !fields.is_empty() { @@ -1962,7 +1958,7 @@ impl<'a> State<'a> { if !tys.is_empty() { word(&mut self.s, "::<")?; self.commasep(Inconsistent, tys, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; word(&mut self.s, ">")?; } self.print_call_post(base_args) @@ -2031,7 +2027,7 @@ impl<'a> State<'a> { self.print_expr_vec(&exprs[..], attrs)?; } ast::ExprKind::Repeat(ref element, ref count) => { - self.print_expr_repeat(&element, &count, attrs)?; + self.print_expr_repeat(element, count, attrs)?; } ast::ExprKind::Struct(ref path, ref fields, ref wth) => { self.print_expr_struct(path, &fields[..], wth, attrs)?; @@ -2040,43 +2036,43 @@ impl<'a> State<'a> { self.print_expr_tup(&exprs[..], attrs)?; } ast::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(&func, &args[..])?; + self.print_expr_call(func, &args[..])?; } ast::ExprKind::MethodCall(ident, ref tys, ref args) => { self.print_expr_method_call(ident, &tys[..], &args[..])?; } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, &lhs, &rhs)?; + self.print_expr_binary(op, lhs, rhs)?; } ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, &expr)?; + self.print_expr_unary(op, expr)?; } ast::ExprKind::AddrOf(m, ref expr) => { - self.print_expr_addr_of(m, &expr)?; + self.print_expr_addr_of(m, expr)?; } ast::ExprKind::Lit(ref lit) => { - self.print_literal(&lit)?; + self.print_literal(lit)?; } ast::ExprKind::Cast(ref expr, ref ty) => { if let ast::ExprKind::Cast(..) = expr.node { - self.print_expr(&expr)?; + self.print_expr(expr)?; } else { - self.print_expr_maybe_paren(&expr)?; + self.print_expr_maybe_paren(expr)?; } space(&mut self.s)?; self.word_space("as")?; - self.print_type(&ty)?; + self.print_type(ty)?; } ast::ExprKind::Type(ref expr, ref ty) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; } ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; + 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))?; + 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 { @@ -2084,9 +2080,9 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("while")?; - self.print_expr(&test)?; + self.print_expr(test)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::WhileLet(ref pat, ref expr, ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2094,12 +2090,12 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("while let")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2107,12 +2103,12 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("for")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("in")?; - self.print_expr(&iter)?; + self.print_expr(iter)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Loop(ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2121,13 +2117,13 @@ impl<'a> State<'a> { } self.head("loop")?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + 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)?; + self.print_expr(expr)?; space(&mut self.s)?; self.bopen()?; self.print_inner_attributes_no_trailing_hardbreak(attrs)?; @@ -2139,7 +2135,7 @@ impl<'a> State<'a> { ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => { self.print_capture_clause(capture_clause)?; - self.print_fn_block_args(&decl)?; + self.print_fn_block_args(decl)?; space(&mut self.s)?; self.print_expr(body)?; self.end()?; // need to close a box @@ -2154,48 +2150,48 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT)?; // head-box, will be closed by print-block after { self.ibox(0)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Assign(ref lhs, ref rhs) => { - self.print_expr(&lhs)?; + self.print_expr(lhs)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&rhs)?; + self.print_expr(rhs)?; } ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { - self.print_expr(&lhs)?; + self.print_expr(lhs)?; space(&mut self.s)?; word(&mut self.s, op.node.to_string())?; self.word_space("=")?; - self.print_expr(&rhs)?; + self.print_expr(rhs)?; } ast::ExprKind::Field(ref expr, id) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ".")?; self.print_ident(id.node)?; } ast::ExprKind::TupField(ref expr, id) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ".")?; self.print_usize(id.node)?; } ast::ExprKind::Index(ref expr, ref index) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, "[")?; - self.print_expr(&index)?; + self.print_expr(index)?; word(&mut self.s, "]")?; } ast::ExprKind::Range(ref start, ref end, limits) => { - if let &Some(ref e) = start { - self.print_expr(&e)?; + if let Some(ref e) = *start { + self.print_expr(e)?; } if limits == ast::RangeLimits::HalfOpen { word(&mut self.s, "..")?; } else { word(&mut self.s, "...")?; } - if let &Some(ref e) = end { - self.print_expr(&e)?; + if let Some(ref e) = *end { + self.print_expr(e)?; } } ast::ExprKind::Path(None, ref path) => { @@ -2226,12 +2222,9 @@ impl<'a> State<'a> { } ast::ExprKind::Ret(ref result) => { word(&mut self.s, "return")?; - match *result { - Some(ref expr) => { - word(&mut self.s, " ")?; - self.print_expr(&expr)?; - } - _ => () + if let Some(ref expr) = *result { + word(&mut self.s, " ")?; + self.print_expr(expr)?; } } ast::ExprKind::InlineAsm(ref a) => { @@ -2261,7 +2254,7 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| { s.print_string(&co.as_str(), ast::StrStyle::Cooked)?; s.popen()?; - s.print_expr(&o)?; + s.print_expr(o)?; s.pclose()?; Ok(()) })?; @@ -2301,7 +2294,7 @@ impl<'a> State<'a> { ast::ExprKind::Paren(ref e) => { self.popen()?; self.print_inner_attributes_inline(attrs)?; - self.print_expr(&e)?; + self.print_expr(e)?; self.pclose()?; }, ast::ExprKind::Try(ref e) => { @@ -2311,7 +2304,7 @@ impl<'a> State<'a> { ast::ExprKind::Catch(ref blk) => { self.head("do catch")?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)? + self.print_block_with_attrs(blk, attrs)? } } self.ann.post(self, NodeExpr(expr))?; @@ -2322,7 +2315,7 @@ impl<'a> State<'a> { self.print_pat(&loc.pat)?; if let Some(ref ty) = loc.ty { self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; } Ok(()) } @@ -2390,7 +2383,7 @@ impl<'a> State<'a> { space(&mut self.s)?; self.word_space("as")?; let depth = path.segments.len() - qself.position; - self.print_path(&path, false, depth, false)?; + self.print_path(path, false, depth, false)?; } word(&mut self.s, ">")?; word(&mut self.s, "::")?; @@ -2431,7 +2424,7 @@ impl<'a> State<'a> { self.commasep( Inconsistent, &data.types, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; comma = true; } @@ -2454,13 +2447,13 @@ impl<'a> State<'a> { self.commasep( Inconsistent, &data.inputs, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; word(&mut self.s, ")")?; if let Some(ref ty) = data.output { self.space_if_not_bol()?; self.word_space("->")?; - self.print_type(&ty)?; + self.print_type(ty)?; } } } @@ -2489,24 +2482,24 @@ impl<'a> State<'a> { self.print_ident(path1.node)?; if let Some(ref p) = *sub { word(&mut self.s, "@")?; - self.print_pat(&p)?; + self.print_pat(p)?; } } PatKind::TupleStruct(ref path, ref elts, ddpos) => { self.print_path(path, true, 0, false)?; self.popen()?; if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?; if ddpos != 0 { self.word_space(",")?; } word(&mut self.s, "..")?; if ddpos != elts.len() { word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?; } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?; } self.pclose()?; } @@ -2542,17 +2535,17 @@ impl<'a> State<'a> { PatKind::Tuple(ref elts, ddpos) => { self.popen()?; if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?; if ddpos != 0 { self.word_space(",")?; } word(&mut self.s, "..")?; if ddpos != elts.len() { word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?; } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?; if elts.len() == 1 { word(&mut self.s, ",")?; } @@ -2561,41 +2554,41 @@ impl<'a> State<'a> { } PatKind::Box(ref inner) => { word(&mut self.s, "box ")?; - self.print_pat(&inner)?; + self.print_pat(inner)?; } PatKind::Ref(ref inner, mutbl) => { word(&mut self.s, "&")?; if mutbl == ast::Mutability::Mutable { word(&mut self.s, "mut ")?; } - self.print_pat(&inner)?; + self.print_pat(inner)?; } PatKind::Lit(ref e) => self.print_expr(&**e)?, PatKind::Range(ref begin, ref end, ref end_kind) => { - self.print_expr(&begin)?; + self.print_expr(begin)?; space(&mut self.s)?; match *end_kind { RangeEnd::Included => word(&mut self.s, "...")?, RangeEnd::Excluded => word(&mut self.s, "..")?, } - self.print_expr(&end)?; + self.print_expr(end)?; } PatKind::Slice(ref before, ref slice, ref after) => { word(&mut self.s, "[")?; 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 p.node != PatKind::Wild { - self.print_pat(&p)?; + self.print_pat(p)?; } word(&mut self.s, "..")?; if !after.is_empty() { self.word_space(",")?; } } self.commasep(Inconsistent, &after[..], - |s, p| s.print_pat(&p))?; + |s, p| s.print_pat(p))?; word(&mut self.s, "]")?; } PatKind::Mac(ref m) => self.print_mac(m, token::Paren)?, @@ -2621,12 +2614,12 @@ impl<'a> State<'a> { space(&mut self.s)?; self.word_space("|")?; } - self.print_pat(&p)?; + self.print_pat(p)?; } space(&mut self.s)?; if let Some(ref e) = arm.guard { self.word_space("if")?; - self.print_expr(&e)?; + self.print_expr(e)?; space(&mut self.s)?; } self.word_space("=>")?; @@ -2634,7 +2627,7 @@ impl<'a> State<'a> { 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)?; + 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 { @@ -2666,7 +2659,7 @@ impl<'a> State<'a> { self.print_mutability(m)?; word(&mut self.s, "self")?; self.word_space(":")?; - self.print_type(&typ) + self.print_type(typ) } } } @@ -2718,7 +2711,7 @@ impl<'a> State<'a> { self.word_space("->")?; match decl.output { ast::FunctionRetTy::Ty(ref ty) => { - self.print_type(&ty)?; + self.print_type(ty)?; self.maybe_print_comment(ty.span.lo) } ast::FunctionRetTy::Default(..) => unreachable!(), @@ -2832,7 +2825,7 @@ impl<'a> State<'a> { Some(ref default) => { space(&mut self.s)?; self.word_space("=")?; - self.print_type(&default) + self.print_type(default) } _ => Ok(()) } @@ -2858,7 +2851,7 @@ impl<'a> State<'a> { ref bounds, ..}) => { self.print_formal_lifetime_list(bound_lifetimes)?; - self.print_type(&bounded_ty)?; + self.print_type(bounded_ty)?; self.print_bounds(":", bounds)?; } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime, @@ -2970,7 +2963,7 @@ impl<'a> State<'a> { match decl.output { ast::FunctionRetTy::Default(..) => unreachable!(), ast::FunctionRetTy::Ty(ref ty) => - self.print_type(&ty)? + self.print_type(ty)? } self.end()?; @@ -3037,14 +3030,9 @@ impl<'a> State<'a> { if self.next_comment().is_none() { hardbreak(&mut self.s)?; } - loop { - match self.next_comment() { - Some(ref cmnt) => { - self.print_comment(cmnt)?; - self.cur_cmnt_and_lit.cur_cmnt += 1; - } - _ => break - } + while let Some(ref cmnt) = self.next_comment() { + self.print_comment(cmnt)?; + self.cur_cmnt_and_lit.cur_cmnt += 1; } Ok(()) } diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index c7820a15fb3..8e257102e1c 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -18,7 +18,7 @@ use ptr::P; use tokenstream::TokenStream; /// Craft a span that will be ignored by the stability lint's -/// call to codemap's is_internal check. +/// call to codemap's `is_internal` check. /// The expanded code uses the unstable `#[prelude_import]` attribute. fn ignored_span(sp: Span) -> Span { let mark = Mark::fresh(); @@ -49,7 +49,7 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<Strin None => return krate, }; - let crate_name = Symbol::intern(&alt_std_name.unwrap_or(name.to_string())); + let crate_name = Symbol::intern(&alt_std_name.unwrap_or_else(|| name.to_string())); krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer(DUMMY_SP, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 50380626d7f..bb1a6ff65a5 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -106,9 +106,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { // Add a special __test module to the crate that will contain code // generated for the test harness let (mod_, reexport) = mk_test_module(&mut self.cx); - match reexport { - Some(re) => folded.module.items.push(re), - None => {} + if let Some(re) = reexport { + folded.module.items.push(re) } folded.module.items.push(mod_); folded @@ -257,7 +256,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt, let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent }; cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent); let it = cx.ext_cx.monotonic_expander().fold_item(P(ast::Item { - ident: sym.clone(), + ident: sym, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemKind::Mod(reexport_mod), @@ -308,7 +307,7 @@ fn generate_test_harness(sess: &ParseSess, } /// Craft a span that will be ignored by the stability lint's -/// call to codemap's is_internal check. +/// call to codemap's `is_internal` check. /// The expanded code calls some unstable functions in the test crate. fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { Span { ctxt: cx.ctxt, ..sp } @@ -354,7 +353,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { } } - return has_test_attr && has_test_signature(i) == Yes; + has_test_attr && has_test_signature(i) == Yes } fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { @@ -385,7 +384,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { `fn(&mut Bencher) -> ()`"); } - return has_bench_attr && has_test_signature(i); + has_bench_attr && has_test_signature(i) } fn is_ignored(i: &ast::Item) -> bool { @@ -442,7 +441,7 @@ We're going to be building a module that looks more or less like: mod __test { extern crate test (name = "test", vers = "..."); fn main() { - test::test_main_static(&::os::args()[], tests) + test::test_main_static(&::os::args()[], tests, test::Options::new()) } static tests : &'static [test::TestDescAndFn] = &[ @@ -478,7 +477,7 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> { // pub fn main() { // #![main] // use std::slice::AsSlice; - // test::test_main_static(::std::os::args().as_slice(), TESTS); + // test::test_main_static(::std::os::args().as_slice(), TESTS, test::Options::new()); // } let sp = ignored_span(cx, DUMMY_SP); @@ -504,16 +503,14 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> { ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), ::abi::Abi::Rust, ast::Generics::default(), main_body); - let main = P(ast::Item { + P(ast::Item { ident: Ident::from_str("main"), attrs: vec![main_attr], id: ast::DUMMY_NODE_ID, node: main, vis: ast::Visibility::Public, span: sp - }); - - return main; + }) } fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) { diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index dc9b22c37e2..b3fa1e97376 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use codemap::CodeMap; +use codemap::{CodeMap, FilePathMapping}; use errors::Handler; use errors::emitter::EmitterWriter; use std::io; @@ -47,8 +47,8 @@ impl<T: Write> Write for Shared<T> { fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) { let output = Arc::new(Mutex::new(Vec::new())); - let code_map = Rc::new(CodeMap::new()); - code_map.new_filemap_and_lines("test.rs", None, &file_text); + let code_map = Rc::new(CodeMap::new(FilePathMapping::empty())); + code_map.new_filemap_and_lines("test.rs", &file_text); let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); let mut msp = MultiSpan::from_span(primary_span); diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 86bfdebe42b..9c1371a31fe 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -10,16 +10,16 @@ //! # Token Streams //! -//! TokenStreams represent syntactic objects before they are converted into ASTs. +//! `TokenStream`s represent syntactic objects before they are converted into ASTs. //! A `TokenStream` is, roughly speaking, a sequence (eg stream) of `TokenTree`s, //! which are themselves a single `Token` or a `Delimited` subsequence of tokens. //! //! ## Ownership -//! TokenStreams are persistent data structures constructed as ropes with reference -//! counted-children. In general, this means that calling an operation on a TokenStream -//! (such as `slice`) produces an entirely new TokenStream from the borrowed reference to -//! the original. This essentially coerces TokenStreams into 'views' of their subparts, -//! and a borrowed TokenStream is sufficient to build an owned TokenStream without taking +//! `TokenStreams` are persistent data structures constructed as ropes with reference +//! counted-children. In general, this means that calling an operation on a `TokenStream` +//! (such as `slice`) produces an entirely new `TokenStream` from the borrowed reference to +//! the original. This essentially coerces `TokenStream`s into 'views' of their subparts, +//! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. use syntax_pos::{BytePos, Span, DUMMY_SP}; @@ -88,7 +88,7 @@ impl Delimited { /// If the syntax extension is an MBE macro, it will attempt to match its /// LHS token tree against the provided token tree, and if it finds a /// match, will transcribe the RHS token tree, splicing in any captured -/// macro_parser::matched_nonterminals into the `SubstNt`s it finds. +/// `macro_parser::matched_nonterminals` into the `SubstNt`s it finds. /// /// The RHS of an MBE macro is the only place `SubstNt`s are substituted. /// Nothing special happens to misnamed or misplaced `SubstNt`s. diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index a6fff2d7074..9307f3c58d4 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -53,9 +53,10 @@ pub fn find_best_match_for_name<'a, T>(iter_names: T, iter_names .filter_map(|&name| { let dist = lev_distance(lookup, &name.as_str()); - match dist <= max_dist { // filter the unwanted cases - true => Some((name, dist)), - false => None, + if dist <= max_dist { // filter the unwanted cases + Some((name, dist)) + } else { + None } }) .min_by_key(|&(_, val)| val) // extract the tuple containing the minimum edit distance diff --git a/src/libsyntax/util/move_map.rs b/src/libsyntax/util/move_map.rs index fe05e2958b3..8cc37afa354 100644 --- a/src/libsyntax/util/move_map.rs +++ b/src/libsyntax/util/move_map.rs @@ -37,10 +37,10 @@ impl<T> MoveMap<T> for Vec<T> { // move the read_i'th item out of the vector and map it // to an iterator let e = ptr::read(self.get_unchecked(read_i)); - let mut iter = f(e).into_iter(); + let iter = f(e).into_iter(); read_i += 1; - while let Some(e) = iter.next() { + for e in iter { if write_i < read_i { ptr::write(self.get_unchecked_mut(write_i), e); write_i += 1; @@ -93,10 +93,10 @@ impl<T> MoveMap<T> for SmallVector<T> { // move the read_i'th item out of the vector and map it // to an iterator let e = ptr::read(self.get_unchecked(read_i)); - let mut iter = f(e).into_iter(); + let iter = f(e).into_iter(); read_i += 1; - while let Some(e) = iter.next() { + for e in iter { if write_i < read_i { ptr::write(self.get_unchecked_mut(write_i), e); write_i += 1; diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index 9d9957a0f45..0a5d0c2e7fe 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -31,7 +31,7 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_ident(self, span, ident); } - fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) { + fn visit_mod(&mut self, m: &Mod, _s: Span, _a: &[Attribute], _n: NodeId) { self.count += 1; walk_mod(self, m) } diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 51eb295b502..2727ab79ebf 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -9,6 +9,7 @@ // except according to those terms. use ast::{self, Ident}; +use codemap::FilePathMapping; use parse::{ParseSess, PResult, filemap_to_stream}; use parse::{lexer, new_parser_from_source_str}; use parse::parser::Parser; @@ -18,8 +19,8 @@ use std::iter::Peekable; /// Map a string to tts, using a made-up filename: pub fn string_to_stream(source_str: String) -> TokenStream { - let ps = ParseSess::new(); - filemap_to_stream(&ps, ps.codemap().new_filemap("bogofile".to_string(), None, source_str)) + let ps = ParseSess::new(FilePathMapping::empty()); + filemap_to_stream(&ps, ps.codemap().new_filemap("bogofile".to_string(), source_str)) } /// Map string to parser (via tts) @@ -38,7 +39,7 @@ fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T /// Parse a string, return a crate. pub fn string_to_crate (source_str : String) -> ast::Crate { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_crate_mod() }) @@ -46,7 +47,7 @@ pub fn string_to_crate (source_str : String) -> ast::Crate { /// Parse a string, return an expr pub fn string_to_expr (source_str : String) -> P<ast::Expr> { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_expr() }) @@ -54,7 +55,7 @@ pub fn string_to_expr (source_str : String) -> P<ast::Expr> { /// Parse a string, return an item pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_item() }) @@ -62,7 +63,7 @@ pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> { /// Parse a string, return a stmt pub fn string_to_stmt(source_str : String) -> Option<ast::Stmt> { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_stmt() }) @@ -71,7 +72,7 @@ pub fn string_to_stmt(source_str : String) -> Option<ast::Stmt> { /// Parse a string, return a pat. Uses "irrefutable"... which doesn't /// (currently) affect parsing. pub fn string_to_pat(source_str: String) -> P<ast::Pat> { - let ps = ParseSess::new(); + let ps = ParseSess::new(FilePathMapping::empty()); with_error_checking_parse(source_str, &ps, |p| { p.parse_pat() }) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bae1c56db00..0fa0753b22c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -27,6 +27,7 @@ use abi::Abi; use ast::*; use syntax_pos::Span; use codemap::Spanned; +use tokenstream::ThinTokenStream; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { @@ -56,7 +57,9 @@ pub trait Visitor<'ast>: Sized { fn visit_ident(&mut self, span: Span, ident: Ident) { walk_ident(self, span, ident); } - fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _n: NodeId) { walk_mod(self, m) } + fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _attrs: &[Attribute], _n: NodeId) { + walk_mod(self, m); + } fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { walk_foreign_item(self, i) } fn visit_global_asm(&mut self, ga: &'ast GlobalAsm) { walk_global_asm(self, ga) } fn visit_item(&mut self, i: &'ast Item) { walk_item(self, i) } @@ -110,6 +113,9 @@ pub trait Visitor<'ast>: Sized { // definition in your trait impl: // visit::walk_mac(self, _mac) } + fn visit_mac_def(&mut self, _mac: &'ast ThinTokenStream, _id: NodeId) { + // Nothing to do + } fn visit_path(&mut self, path: &'ast Path, _id: NodeId) { walk_path(self, path) } @@ -172,7 +178,7 @@ pub fn walk_ident<'a, V: Visitor<'a>>(visitor: &mut V, span: Span, ident: Ident) } pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) { - visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID); + visitor.visit_mod(&krate.module, krate.span, &krate.attrs, CRATE_NODE_ID); walk_list!(visitor, visit_attribute, &krate.attrs); } @@ -249,7 +255,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { item.id) } ItemKind::Mod(ref module) => { - visitor.visit_mod(module, item.span, item.id) + visitor.visit_mod(module, item.span, &item.attrs, item.id) } ItemKind::ForeignMod(ref foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); @@ -266,7 +272,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { ItemKind::DefaultImpl(_, ref trait_ref) => { visitor.visit_trait_ref(trait_ref) } - ItemKind::Impl(_, _, + ItemKind::Impl(_, _, _, ref type_parameters, ref opt_trait_reference, ref typ, @@ -288,7 +294,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { walk_list!(visitor, visit_trait_item, methods); } ItemKind::Mac(ref mac) => visitor.visit_mac(mac), - ItemKind::MacroDef(..) => {}, + ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), } walk_list!(visitor, visit_attribute, &item.attrs); } @@ -343,9 +349,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { visitor.visit_ty(ty); visitor.visit_expr(expression) } - TyKind::TraitObject(ref bounds) => { - walk_list!(visitor, visit_ty_param_bound, bounds); - } + TyKind::TraitObject(ref bounds) | TyKind::ImplTrait(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); } @@ -540,7 +544,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl walk_fn_decl(visitor, declaration); visitor.visit_block(body); } - FnKind::Method(_, ref sig, _, body) => { + FnKind::Method(_, sig, _, body) => { visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, declaration); visitor.visit_block(body); @@ -776,7 +780,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { } ExprKind::InlineAsm(ref ia) => { for &(_, ref input) in &ia.inputs { - visitor.visit_expr(&input) + visitor.visit_expr(input) } for output in &ia.outputs { visitor.visit_expr(&output.expr) |
