From f3ba950a34885b366b79750237aca6ca3901cbc2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 3 Jul 2015 12:50:18 +1200 Subject: Refactor how the parser looks for sub-modules This makes the functionality usable from outside the parser --- src/libsyntax/parse/parser.rs | 176 ++++++++++++++++++++++++++---------------- 1 file changed, 108 insertions(+), 68 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 03c788aee58..d19364f5f44 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -60,7 +60,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; use ast; use ast_util::{self, AS_PREC, ident_to_path, operator_prec}; -use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp}; +use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; use diagnostic; use ext::tt::macro_parser; use parse; @@ -297,6 +297,24 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool { t.is_plain_ident() || *t == token::Underscore } +/// Information about the path to a module. +pub struct ModulePath { + pub name: String, + pub path_exists: bool, + pub result: Result, +} + +pub struct ModulePathSuccess { + pub path: ::std::path::PathBuf, + pub owns_directory: bool, +} + +pub struct ModulePathError { + pub err_msg: String, + pub help_msg: String, +} + + impl<'a> Parser<'a> { pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig, @@ -4861,82 +4879,104 @@ impl<'a> Parser<'a> { self.mod_path_stack.pop().unwrap(); } - /// Read a module from a source file. - fn eval_src_mod(&mut self, - id: ast::Ident, - outer_attrs: &[ast::Attribute], - id_sp: Span) - -> PResult<(ast::Item_, Vec )> { + pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option { + ::attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d)) + } + + /// Returns either a path to a module, or . + pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -> ModulePath + { + let mod_string = token::get_ident(id); + let mod_name = mod_string.to_string(); + let default_path_str = format!("{}.rs", mod_name); + let secondary_path_str = format!("{}/mod.rs", mod_name); + let default_path = dir_path.join(&default_path_str); + let secondary_path = dir_path.join(&secondary_path_str); + let default_exists = codemap.file_exists(&default_path); + let secondary_exists = codemap.file_exists(&secondary_path); + + let result = match (default_exists, secondary_exists) { + (true, false) => Ok(ModulePathSuccess { path: default_path, owns_directory: false }), + (false, true) => Ok(ModulePathSuccess { path: secondary_path, owns_directory: true }), + (false, false) => Err(ModulePathError { + err_msg: format!("file not found for module `{}`", mod_name), + help_msg: format!("name the file either {} or {} inside the directory {:?}", + default_path_str, + secondary_path_str, + dir_path.display()), + }), + (true, true) => Err(ModulePathError { + err_msg: format!("file for module `{}` found at both {} and {}", + mod_name, + default_path_str, + secondary_path_str), + help_msg: "delete or rename one of them to remove the ambiguity".to_owned(), + }), + }; + + ModulePath { + name: mod_name, + path_exists: default_exists || secondary_exists, + result: result, + } + } + + fn submod_path(&mut self, + id: ast::Ident, + outer_attrs: &[ast::Attribute], + id_sp: Span) -> PResult { let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span)); prefix.pop(); let mut dir_path = prefix; for part in &self.mod_path_stack { dir_path.push(&**part); } - let mod_string = token::get_ident(id); - let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name( - outer_attrs, "path") { - Some(d) => (dir_path.join(&*d), true), - None => { - let mod_name = mod_string.to_string(); - let default_path_str = format!("{}.rs", mod_name); - let secondary_path_str = format!("{}/mod.rs", mod_name); - let default_path = dir_path.join(&default_path_str[..]); - let secondary_path = dir_path.join(&secondary_path_str[..]); - let default_exists = self.sess.codemap().file_exists(&default_path); - let secondary_exists = self.sess.codemap().file_exists(&secondary_path); - - if !self.owns_directory { - self.span_err(id_sp, - "cannot declare a new module at this location"); - let this_module = match self.mod_path_stack.last() { - Some(name) => name.to_string(), - None => self.root_module_name.as_ref().unwrap().clone(), - }; - self.span_note(id_sp, - &format!("maybe move this module `{0}` \ - to its own directory via \ - `{0}/mod.rs`", - this_module)); - if default_exists || secondary_exists { - self.span_note(id_sp, - &format!("... or maybe `use` the module \ - `{}` instead of possibly \ - redeclaring it", - mod_name)); - } - self.abort_if_errors(); - } - match (default_exists, secondary_exists) { - (true, false) => (default_path, false), - (false, true) => (secondary_path, true), - (false, false) => { - return Err(self.span_fatal_help(id_sp, - &format!("file not found for module `{}`", - mod_name), - &format!("name the file either {} or {} inside \ - the directory {:?}", - default_path_str, - secondary_path_str, - dir_path.display()))); - } - (true, true) => { - return Err(self.span_fatal_help( - id_sp, - &format!("file for module `{}` found at both {} \ - and {}", - mod_name, - default_path_str, - secondary_path_str), - "delete or rename one of them to remove the ambiguity")); - } - } + if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &dir_path) { + return Ok(ModulePathSuccess { path: p, owns_directory: true }); + } + + let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap()); + + if !self.owns_directory { + self.span_err(id_sp, "cannot declare a new module at this location"); + let this_module = match self.mod_path_stack.last() { + Some(name) => name.to_string(), + None => self.root_module_name.as_ref().unwrap().clone(), + }; + self.span_note(id_sp, + &format!("maybe move this module `{0}` to its own directory \ + via `{0}/mod.rs`", + this_module)); + if paths.path_exists { + self.span_note(id_sp, + &format!("... or maybe `use` the module `{}` instead \ + of possibly redeclaring it", + paths.name)); } - }; + self.abort_if_errors(); + } + + match paths.result { + Ok(succ) => Ok(succ), + Err(err) => Err(self.span_fatal_help(id_sp, &err.err_msg, &err.help_msg)), + } + } - self.eval_src_mod_from_path(file_path, owns_directory, - mod_string.to_string(), id_sp) + /// Read a module from a source file. + fn eval_src_mod(&mut self, + id: ast::Ident, + outer_attrs: &[ast::Attribute], + id_sp: Span) + -> PResult<(ast::Item_, Vec )> { + let ModulePathSuccess { path, owns_directory } = try!(self.submod_path(id, + outer_attrs, + id_sp)); + + self.eval_src_mod_from_path(path, + owns_directory, + token::get_ident(id).to_string(), + id_sp) } fn eval_src_mod_from_path(&mut self, -- cgit 1.4.1-3-g733a5 From f28f79b79615fc77e65ec42c4e2a3960659150c9 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 8 Jul 2015 17:47:27 +1200 Subject: Fix a span bug for qualified paths --- src/libsyntax/parse/parser.rs | 6 ++---- src/test/run-make/save-analysis/foo.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 03c788aee58..81ae607fea2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1566,12 +1566,13 @@ impl<'a> Parser<'a> { // Assumes that the leading `<` has been parsed already. pub fn parse_qualified_path(&mut self, mode: PathParsingMode) -> PResult<(QSelf, ast::Path)> { + let span = self.last_span; let self_type = try!(self.parse_ty_sum()); let mut path = if try!(self.eat_keyword(keywords::As)) { try!(self.parse_path(LifetimeAndTypesWithoutColons)) } else { ast::Path { - span: self.span, + span: span, global: false, segments: vec![] } @@ -1598,9 +1599,6 @@ impl<'a> Parser<'a> { }; path.segments.extend(segments); - if path.segments.len() == 1 { - path.span.lo = self.last_span.lo; - } path.span.hi = self.last_span.hi; Ok((qself, path)) diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index 07b99dff4e0..4981ea475d3 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -364,3 +364,18 @@ impl<'a> Pattern<'a> for CharEqPattern { } struct CharSearcher<'a>(>::Searcher); + +pub trait Error { +} + +impl Error + 'static { + pub fn is(&self) -> bool { + panic!() + } +} + +impl Error + 'static + Send { + pub fn is(&self) -> bool { + ::is::(self) + } +} -- cgit 1.4.1-3-g733a5 From 93ddee6cee6816843035575ddf0bf0309021ebc5 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 10 Jul 2015 08:19:21 -0400 Subject: Change some instances of .connect() to .join() --- src/compiletest/runtest.rs | 8 +++---- src/libcollectionstest/slice.rs | 20 ++++++++--------- src/libcollectionstest/str.rs | 30 +++++++++++++------------- src/libgetopts/lib.rs | 6 +++--- src/librustc/metadata/encoder.rs | 2 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 2 +- src/librustc_driver/pretty.rs | 2 +- src/librustc_driver/test.rs | 2 +- src/librustc_lint/builtin.rs | 2 +- src/librustc_trans/trans/_match.rs | 4 ++-- src/librustc_trans/trans/asm.rs | 2 +- src/librustc_trans/trans/build.rs | 2 +- src/librustc_trans/trans/builder.rs | 4 ++-- src/librustc_trans/trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/llrepr.rs | 2 +- src/librustc_trans/trans/type_.rs | 2 +- src/librustc_trans/trans/type_of.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 6 +++--- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 2 +- src/librustdoc/clean/mod.rs | 6 +++--- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/markdown.rs | 10 ++++----- src/librustdoc/html/render.rs | 22 +++++++++---------- src/librustdoc/passes.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libstd/net/ip.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/source_util.rs | 2 +- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/libsyntax/parse/lexer/comments.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libtest/lib.rs | 2 +- src/test/auxiliary/plugin_args.rs | 2 +- src/test/run-pass/issue-3563-3.rs | 2 +- src/test/run-pass/trait-to-str.rs | 2 +- 39 files changed, 87 insertions(+), 87 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 93054f39790..5b62f29b824 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -344,7 +344,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { check_lines, breakpoint_lines } = parse_debugger_commands(testfile, "gdb"); - let mut cmds = commands.connect("\n"); + let mut cmds = commands.join("\n"); // compile test file (it should have 'compile-flags:-g' in the header) let compiler_run_result = compile_test(config, props, testfile); @@ -799,7 +799,7 @@ fn cleanup_debug_info_options(options: &Option) -> Option { split_maybe_args(options).into_iter() .filter(|x| !options_to_remove.contains(x)) .collect::>() - .connect(" "); + .join(" "); Some(new_options) } @@ -1412,7 +1412,7 @@ fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String { // Linux and mac don't require adjusting the library search path if cfg!(unix) { - format!("{} {}", prog, args.connect(" ")) + format!("{} {}", prog, args.join(" ")) } else { // Build the LD_LIBRARY_PATH variable as it would be seen on the command line // for diagnostic purposes @@ -1420,7 +1420,7 @@ fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String { format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) } - format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" ")) + format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.join(" ")) } } diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index d88d8b8e4a0..436e71fd4a0 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -606,22 +606,22 @@ fn test_concat() { assert_eq!(d, [1, 2, 3]); let v: &[&[_]] = &[&[1], &[2, 3]]; - assert_eq!(v.connect(&0), [1, 0, 2, 3]); + assert_eq!(v.join(&0), [1, 0, 2, 3]); let v: &[&[_]] = &[&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); + assert_eq!(v.join(&0), [1, 0, 2, 0, 3]); } #[test] -fn test_connect() { +fn test_join() { let v: [Vec; 0] = []; - assert_eq!(v.connect(&0), []); - assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]); - assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]); + assert_eq!(v.join(&0), []); + assert_eq!([vec![1], vec![2, 3]].join(&0), [1, 0, 2, 3]); + assert_eq!([vec![1], vec![2], vec![3]].join(&0), [1, 0, 2, 0, 3]); let v: [&[_]; 2] = [&[1], &[2, 3]]; - assert_eq!(v.connect(&0), [1, 0, 2, 3]); + assert_eq!(v.join(&0), [1, 0, 2, 3]); let v: [&[_]; 3] = [&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); + assert_eq!(v.join(&0), [1, 0, 2, 0, 3]); } #[test] @@ -1339,11 +1339,11 @@ mod bench { } #[bench] - fn connect(b: &mut Bencher) { + fn join(b: &mut Bencher) { let xss: Vec> = (0..100).map(|i| (0..i).collect()).collect(); b.iter(|| { - xss.connect(&0) + xss.join(&0) }); } diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index 87a018ced19..e92af585c15 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -158,32 +158,32 @@ fn test_concat_for_different_lengths() { test_concat!("abc", ["", "a", "bc"]); } -macro_rules! test_connect { +macro_rules! test_join { ($expected: expr, $string: expr, $delim: expr) => { { - let s = $string.connect($delim); + let s = $string.join($delim); assert_eq!($expected, s); } } } #[test] -fn test_connect_for_different_types() { - test_connect!("a-b", ["a", "b"], "-"); +fn test_join_for_different_types() { + test_join!("a-b", ["a", "b"], "-"); let hyphen = "-".to_string(); - test_connect!("a-b", [s("a"), s("b")], &*hyphen); - test_connect!("a-b", vec!["a", "b"], &*hyphen); - test_connect!("a-b", &*vec!["a", "b"], "-"); - test_connect!("a-b", vec![s("a"), s("b")], "-"); + test_join!("a-b", [s("a"), s("b")], &*hyphen); + test_join!("a-b", vec!["a", "b"], &*hyphen); + test_join!("a-b", &*vec!["a", "b"], "-"); + test_join!("a-b", vec![s("a"), s("b")], "-"); } #[test] -fn test_connect_for_different_lengths() { +fn test_join_for_different_lengths() { let empty: &[&str] = &[]; - test_connect!("", empty, "-"); - test_connect!("a", ["a"], "-"); - test_connect!("a-b", ["a", "b"], "-"); - test_connect!("-a-bc", ["", "a", "bc"], "-"); + test_join!("", empty, "-"); + test_join!("a", ["a"], "-"); + test_join!("a-b", ["a", "b"], "-"); + test_join!("-a-bc", ["", "a", "bc"], "-"); } #[test] @@ -2081,12 +2081,12 @@ mod bench { } #[bench] - fn bench_connect(b: &mut Bencher) { + fn bench_join(b: &mut Bencher) { let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; let sep = "→"; let v = vec![s, s, s, s, s, s, s, s, s, s]; b.iter(|| { - assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9); + assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9); }) } diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 0d15f584d64..65e85b92e0b 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -784,13 +784,13 @@ pub fn usage(brief: &str, opts: &[OptGroup]) -> String { // FIXME: #5516 should be graphemes not codepoints // wrapped description - row.push_str(&desc_rows.connect(&desc_sep[..])); + row.push_str(&desc_rows.join(&desc_sep[..])); row }); format!("{}\n\nOptions:\n{}\n", brief, - rows.collect::>().connect("\n")) + rows.collect::>().join("\n")) } fn format_option(opt: &OptGroup) -> String { @@ -836,7 +836,7 @@ pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> String { line.push_str(&opts.iter() .map(format_option) .collect::>() - .connect(" ")[..]); + .join(" ")[..]); line } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index a9e9f17bdce..f38369e3f4c 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -2028,7 +2028,7 @@ fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) { cstore::RequireStatic => "s", })).to_string()) }).collect::>(); - rbml_w.wr_tagged_str(tag, &s.connect(",")); + rbml_w.wr_tagged_str(tag, &s.join(",")); } None => { rbml_w.wr_tagged_str(tag, ""); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 63f31921ec2..e24fadba6a5 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1098,7 +1098,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String { let tstrs: Vec = ts.iter().map(|t| self.ty_to_string(*t)).collect(); - format!("({})", tstrs.connect(", ")) + format!("({})", tstrs.join(", ")) } pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9541076df82..67301a09e52 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -843,7 +843,7 @@ fn write_out_deps(sess: &Session, let mut file = try!(fs::File::create(&deps_filename)); for path in &out_filenames { try!(write!(&mut file, - "{}: {}\n\n", path.display(), files.connect(" "))); + "{}: {}\n\n", path.display(), files.join(" "))); } Ok(()) })(); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 7ccada1079f..2906fd35a0a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -606,7 +606,7 @@ Available lint options: for (name, to) in lints { let name = name.to_lowercase().replace("_", "-"); let desc = to.into_iter().map(|x| x.as_str().replace("_", "-")) - .collect::>().connect(", "); + .collect::>().join(", "); println!(" {} {}", padded(&name[..]), desc); } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 610f3f3a75e..0e735cbb7ff 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -378,7 +378,7 @@ impl UserIdentifiedItem { fn reconstructed_input(&self) -> String { match *self { ItemViaNode(node_id) => node_id.to_string(), - ItemViaPath(ref parts) => parts.connect("::"), + ItemViaPath(ref parts) => parts.join("::"), } } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 128b0b7baab..a9efd13a998 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { return match search_mod(self, &self.infcx.tcx.map.krate().module, 0, names) { Some(id) => id, None => { - panic!("no item found: `{}`", names.connect("::")); + panic!("no item found: `{}`", names.join("::")); } }; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 186361626ff..1574080b313 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -923,7 +923,7 @@ impl NonSnakeCase { } words.push(buf); } - words.connect("_") + words.join("_") } fn check_snake_case(&self, cx: &Context, sort: &str, name: &str, span: Option) { diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 936b0070dfc..3aa98ab031d 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -936,7 +936,7 @@ fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx.to_str(), guard_expr, m, - vals.iter().map(|v| bcx.val_to_string(*v)).collect::>().connect(", ")); + vals.iter().map(|v| bcx.val_to_string(*v)).collect::>().join(", ")); let _indenter = indenter(); let mut bcx = insert_lllocals(bcx, &data.bindings_map, None); @@ -981,7 +981,7 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, debug!("compile_submatch(bcx={}, m={:?}, vals=[{}])", bcx.to_str(), m, - vals.iter().map(|v| bcx.val_to_string(*v)).collect::>().connect(", ")); + vals.iter().map(|v| bcx.val_to_string(*v)).collect::>().join(", ")); let _indenter = indenter(); let _icx = push_ctxt("match::compile_submatch"); let mut bcx = bcx; diff --git a/src/librustc_trans/trans/asm.rs b/src/librustc_trans/trans/asm.rs index b25d6f2daac..67e7aa5baf6 100644 --- a/src/librustc_trans/trans/asm.rs +++ b/src/librustc_trans/trans/asm.rs @@ -92,7 +92,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) .chain(arch_clobbers.iter() .map(|s| s.to_string())) .collect::>() - .connect(","); + .join(","); debug!("Asm Constraints: {}", &all_constraints[..]); diff --git a/src/librustc_trans/trans/build.rs b/src/librustc_trans/trans/build.rs index 05d0a967e64..7d682504044 100644 --- a/src/librustc_trans/trans/build.rs +++ b/src/librustc_trans/trans/build.rs @@ -148,7 +148,7 @@ pub fn Invoke(cx: Block, terminate(cx, "Invoke"); debug!("Invoke({} with arguments ({}))", cx.val_to_string(fn_), - args.iter().map(|a| cx.val_to_string(*a)).collect::>().connect(", ")); + args.iter().map(|a| cx.val_to_string(*a)).collect::>().join(", ")); debug_loc.apply(cx.fcx); B(cx).invoke(fn_, args, then, catch, attributes) } diff --git a/src/librustc_trans/trans/builder.rs b/src/librustc_trans/trans/builder.rs index e100defc248..32d9ee7a508 100644 --- a/src/librustc_trans/trans/builder.rs +++ b/src/librustc_trans/trans/builder.rs @@ -167,7 +167,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args.iter() .map(|&v| self.ccx.tn().val_to_string(v)) .collect::>() - .connect(", ")); + .join(", ")); unsafe { let v = llvm::LLVMBuildInvoke(self.llbuilder, @@ -809,7 +809,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { args.iter() .map(|&v| self.ccx.tn().val_to_string(v)) .collect::>() - .connect(", ")); + .join(", ")); unsafe { let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(), diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 45349969a0b..45d8fa67db6 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -1443,7 +1443,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { let discrfield = discrfield.iter() .skip(1) .map(|x| x.to_string()) - .collect::>().connect("$"); + .collect::>().join("$"); let union_member_name = format!("RUST$ENCODED$ENUM${}${}", discrfield, null_variant_name); diff --git a/src/librustc_trans/trans/llrepr.rs b/src/librustc_trans/trans/llrepr.rs index 6dd56679797..6b785e7edfd 100644 --- a/src/librustc_trans/trans/llrepr.rs +++ b/src/librustc_trans/trans/llrepr.rs @@ -19,7 +19,7 @@ pub trait LlvmRepr { impl LlvmRepr for [T] { fn llrepr(&self, ccx: &CrateContext) -> String { let reprs: Vec = self.iter().map(|t| t.llrepr(ccx)).collect(); - format!("[{}]", reprs.connect(",")) + format!("[{}]", reprs.join(",")) } } diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index ac39d10a23d..c88509dac4c 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -322,7 +322,7 @@ impl TypeNames { pub fn types_to_str(&self, tys: &[Type]) -> String { let strs: Vec = tys.iter().map(|t| self.type_to_string(*t)).collect(); - format!("[{}]", strs.connect(",")) + format!("[{}]", strs.join(",")) } pub fn val_to_string(&self, val: ValueRef) -> String { diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 4359a8d270d..36905ffe93b 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -457,7 +457,7 @@ fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let tstr = if strings.is_empty() { base } else { - format!("{}<{}>", base, strings.connect(", ")) + format!("{}<{}>", base, strings.join(", ")) }; if did.krate == 0 { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 4d86a4f7c70..f14886606c2 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -134,7 +134,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, p.self_ty(), p)) .collect::>() - .connect(", "); + .join(", "); cx.sess.fileline_note( span, &format!("the method `{}` exists but the \ diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 638cc868527..0f9ebf3713c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1002,7 +1002,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, "not all trait items implemented, missing: `{}`", missing_items.iter() .map(::as_str) - .collect::>().connect("`, `")) + .collect::>().join("`, `")) } if !invalidated_items.is_empty() { @@ -1013,7 +1013,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, invalidator.ident.as_str(), invalidated_items.iter() .map(::as_str) - .collect::>().connect("`, `")) + .collect::>().join("`, `")) } } @@ -2868,7 +2868,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, span_err!(tcx.sess, span, E0063, "missing field{}: {}", if missing_fields.len() == 1 {""} else {"s"}, - missing_fields.connect(", ")); + missing_fields.join(", ")); } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 20407e927f7..cd904425d63 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -514,7 +514,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } else { name.to_string() }, a, b) - }).collect::>().connect(", ")); + }).collect::>().join(", ")); return; } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e170808ad07..5d2e3533efc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1536,7 +1536,7 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, d => format!("{:?}", d), }) .collect::>() - .connect(","); + .join(","); tcx.sess.span_err(it.span, &object_lifetime_default_reprs); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c25267520cc..daa4e1af338 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2536,12 +2536,12 @@ fn name_from_pat(p: &ast::Pat) -> String { format!("{} {{ {}{} }}", path_to_string(name), fields.iter().map(|&Spanned { node: ref fp, .. }| format!("{}: {}", fp.ident.as_str(), name_from_pat(&*fp.pat))) - .collect::>().connect(", "), + .collect::>().join(", "), if etc { ", ..." } else { "" } ) }, PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p)) - .collect::>().connect(", ")), + .collect::>().join(", ")), PatBox(ref p) => name_from_pat(&**p), PatRegion(ref p, _) => name_from_pat(&**p), PatLit(..) => { @@ -2555,7 +2555,7 @@ fn name_from_pat(p: &ast::Pat) -> String { let begin = begin.iter().map(|p| name_from_pat(&**p)); let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter(); let end = end.iter().map(|p| name_from_pat(&**p)); - format!("[{}]", begin.chain(mid).chain(end).collect::>().connect(", ")) + format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) }, PatMac(..) => { warn!("can't document the name of a function argument \ diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 9439fc3c5f4..fc06dc347b5 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -360,7 +360,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, path: &clean::Path, match href(did) { Some((url, shortty, fqp)) => { try!(write!(w, "{}", - shortty, url, fqp.connect("::"), last.name)); + shortty, url, fqp.join("::"), last.name)); } _ => try!(write!(w, "{}", last.name)), } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 4982215d02f..4ec4ffb0c31 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -199,7 +199,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> { fn collapse_whitespace(s: &str) -> String { s.split(|c: char| c.is_whitespace()).filter(|s| { !s.is_empty() - }).collect::>().connect(" ") + }).collect::>().join(" ") } thread_local!(static USED_HEADER_MAP: RefCell> = { @@ -238,14 +238,14 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { let lines = origtext.lines().filter(|l| { stripped_filtered_line(*l).is_none() }); - let text = lines.collect::>().connect("\n"); + let text = lines.collect::>().join("\n"); if rendered { return } PLAYGROUND_KRATE.with(|krate| { let mut s = String::new(); krate.borrow().as_ref().map(|krate| { let test = origtext.lines().map(|l| { stripped_filtered_line(l).unwrap_or(l) - }).collect::>().connect("\n"); + }).collect::>().join("\n"); let krate = krate.as_ref().map(|s| &**s); let test = test::maketest(&test, krate, false, &Default::default()); @@ -275,7 +275,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { // Transform the contents of the header into a hyphenated string let id = s.split_whitespace().map(|s| s.to_ascii_lowercase()) - .collect::>().connect("-"); + .collect::>().join("-"); // This is a terrible hack working around how hoedown gives us rendered // html for text rather than the raw text. @@ -387,7 +387,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { let lines = text.lines().map(|l| { stripped_filtered_line(l).unwrap_or(l) }); - let text = lines.collect::>().connect("\n"); + let text = lines.collect::>().join("\n"); tests.add_test(text.to_string(), block_info.should_panic, block_info.no_run, block_info.ignore, block_info.test_harness); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5ecf0fe8ecf..07e3ae975d6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -285,7 +285,7 @@ impl fmt::Display for IndexItemFunctionType { let inputs: Vec = self.inputs.iter().map(|ref t| { format!("{}", t) }).collect(); - try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.connect(","))); + try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.join(","))); match self.output { Some(ref t) => try!(write!(f, "{}", t)), @@ -461,7 +461,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result { search_index.push(IndexItem { ty: shortty(item), name: item.name.clone().unwrap(), - path: fqp[..fqp.len() - 1].connect("::"), + path: fqp[..fqp.len() - 1].join("::"), desc: shorter(item.doc_value()), parent: Some(did), search_type: get_index_search_type(&item, parent_basename), @@ -957,7 +957,7 @@ impl DocFolder for Cache { self.search_index.push(IndexItem { ty: shortty(&item), name: s.to_string(), - path: path.connect("::").to_string(), + path: path.join("::").to_string(), desc: shorter(item.doc_value()), parent: parent, search_type: get_index_search_type(&item, parent_basename), @@ -1187,7 +1187,7 @@ impl Context { *slot.borrow_mut() = cx.current.clone(); }); - let mut title = cx.current.connect("::"); + let mut title = cx.current.join("::"); if pushname { if !title.is_empty() { title.push_str("::"); @@ -1393,7 +1393,7 @@ impl<'a> Item<'a> { Some(format!("{root}src/{krate}/{path}.html#{href}", root = self.cx.root_path, krate = self.cx.layout.krate, - path = path.connect("/"), + path = path.join("/"), href = href)) // If this item is not part of the local crate, then things get a little @@ -1417,7 +1417,7 @@ impl<'a> Item<'a> { }; Some(format!("{root}{path}/{file}?gotosrc={goto}", root = root, - path = path[..path.len() - 1].connect("/"), + path = path[..path.len() - 1].join("/"), file = item_path(self.item), goto = self.item.def_id.node)) } @@ -1523,7 +1523,7 @@ fn item_path(item: &clean::Item) -> String { } fn full_path(cx: &Context, item: &clean::Item) -> String { - let mut s = cx.current.connect("::"); + let mut s = cx.current.join("::"); s.push_str("::"); s.push_str(item.name.as_ref().unwrap()); return s @@ -1535,7 +1535,7 @@ fn shorter<'a>(s: Option<&'a str>) -> String { (*line).chars().any(|chr|{ !chr.is_whitespace() }) - }).collect::>().connect("\n"), + }).collect::>().join("\n"), None => "".to_string() } } @@ -1920,12 +1920,12 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, r#""#, - root_path = vec![".."; cx.current.len()].connect("/"), + root_path = vec![".."; cx.current.len()].join("/"), path = if ast_util::is_local(it.def_id) { - cx.current.connect("/") + cx.current.join("/") } else { let path = &cache.external_paths[&it.def_id]; - path[..path.len() - 1].connect("/") + path[..path.len() - 1].join("/") }, ty = shortty(it).to_static_str(), name = *it.name.as_ref().unwrap())); diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 74c16127f41..6e1c8beb3ad 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -361,7 +361,7 @@ pub fn unindent(s: &str) -> String { line[min_indent..].to_string() } }).collect::>()); - unindented.connect("\n") + unindented.join("\n") } else { s.to_string() } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 1ac95177860..3ce2922c4c9 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -360,7 +360,7 @@ impl Collector { let s = self.current_header.as_ref().map(|s| &**s).unwrap_or(""); format!("{}_{}", s, self.cnt) } else { - format!("{}_{}", self.names.connect("::"), self.cnt) + format!("{}_{}", self.names.join("::"), self.cnt) }; self.cnt += 1; let libs = self.libs.clone(); diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index bc13d966a10..3fe44d4809e 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -442,7 +442,7 @@ impl fmt::Display for Ipv6Addr { .iter() .map(|&seg| format!("{:x}", seg)) .collect::>() - .connect(":") + .join(":") } write!(fmt, "{}::{}", diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 7d7ea371ba5..6b38762316c 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -27,7 +27,7 @@ pub fn path_name_i(idents: &[Ident]) -> String { // FIXME: Bad copies (#2543 -- same for everything else that says "bad") idents.iter().map(|i| { token::get_ident(*i).to_string() - }).collect::>().connect("::") + }).collect::>().join("::") } pub fn local_def(id: NodeId) -> DefId { diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 3866f5534c2..5418b1f43e4 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -78,7 +78,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) .iter() .map(|x| token::get_ident(*x).to_string()) .collect::>() - .connect("::"); + .join("::"); base::MacEager::expr(cx.expr_str( sp, token::intern_and_get_ident(&string[..]))) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 5521c68e75c..5b3887e76b4 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -465,7 +465,7 @@ pub fn parse(sess: &ParseSess, token::get_ident(bind))).to_string() } _ => panic!() - } }).collect::>().connect(" or "); + } }).collect::>().join(" or "); return Error(sp, format!( "local ambiguity: multiple parsing options: \ built-in NTs {} or {} other options.", diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 1577b50ad76..467345624c2 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -139,7 +139,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { let lines = vertical_trim(lines); let lines = horizontal_trim(lines); - return lines.connect("\n"); + return lines.join("\n"); } panic!("not a doc-comment: {}", comment); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 81ae607fea2..d77b529a3bf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5215,7 +5215,7 @@ impl<'a> Parser<'a> { last_span, &format!("illegal ABI: expected one of [{}], \ found `{}`", - abi::all_names().connect(", "), + abi::all_names().join(", "), the_string)); Ok(None) } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 724c0b2a892..629e3920e10 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1080,7 +1080,7 @@ impl MetricMap { .map(|(k,v)| format!("{}: {} (+/- {})", *k, v.value, v.noise)) .collect(); - v.connect(", ") + v.join(", ") } } diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs index 5a615502a95..1920185d4e5 100644 --- a/src/test/auxiliary/plugin_args.rs +++ b/src/test/auxiliary/plugin_args.rs @@ -36,7 +36,7 @@ impl TTMacroExpander for Expander { sp: Span, _: &[ast::TokenTree]) -> Box { let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i)) - .collect::>().connect(", "); + .collect::>().join(", "); let interned = token::intern_and_get_ident(&args[..]); MacEager::expr(ecx.expr_str(sp, interned)) } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 5cd58c0ecfb..ecee2fd0faa 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -108,7 +108,7 @@ impl fmt::Display for AsciiArt { .collect::>(); // Concatenate the lines together using a new-line. - write!(f, "{}", lines.connect("\n")) + write!(f, "{}", lines.join("\n")) } } diff --git a/src/test/run-pass/trait-to-str.rs b/src/test/run-pass/trait-to-str.rs index 8fa628def79..f5af05d872b 100644 --- a/src/test/run-pass/trait-to-str.rs +++ b/src/test/run-pass/trait-to-str.rs @@ -24,7 +24,7 @@ impl to_str for Vec { self.iter() .map(|e| e.to_string_()) .collect::>() - .connect(", ")) + .join(", ")) } } -- cgit 1.4.1-3-g733a5 From 12963606d015c5f68c6e8bc51267cd2b9c8d0cfe Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Thu, 16 Jul 2015 09:22:57 +0200 Subject: Include label in the span of loops --- src/libsyntax/parse/parser.rs | 42 ++++++++++++++++++++---------------- src/test/compile-fail/issue-27042.rs | 26 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/issue-27042.rs (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6e6d3c8105d..28802d323c6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2099,28 +2099,32 @@ impl<'a> Parser<'a> { return self.parse_if_expr(); } if try!(self.eat_keyword(keywords::For) ){ - return self.parse_for_expr(None); + let lo = self.last_span.lo; + return self.parse_for_expr(None, lo); } if try!(self.eat_keyword(keywords::While) ){ - return self.parse_while_expr(None); + let lo = self.last_span.lo; + return self.parse_while_expr(None, lo); } if self.token.is_lifetime() { let lifetime = self.get_lifetime(); + let lo = self.span.lo; try!(self.bump()); try!(self.expect(&token::Colon)); if try!(self.eat_keyword(keywords::While) ){ - return self.parse_while_expr(Some(lifetime)) + return self.parse_while_expr(Some(lifetime), lo) } if try!(self.eat_keyword(keywords::For) ){ - return self.parse_for_expr(Some(lifetime)) + return self.parse_for_expr(Some(lifetime), lo) } if try!(self.eat_keyword(keywords::Loop) ){ - return self.parse_loop_expr(Some(lifetime)) + return self.parse_loop_expr(Some(lifetime), lo) } return Err(self.fatal("expected `while`, `for`, or `loop` after a label")) } if try!(self.eat_keyword(keywords::Loop) ){ - return self.parse_loop_expr(None); + let lo = self.last_span.lo; + return self.parse_loop_expr(None, lo); } if try!(self.eat_keyword(keywords::Continue) ){ let lo = self.span.lo; @@ -2892,48 +2896,48 @@ impl<'a> Parser<'a> { } /// Parse a 'for' .. 'in' expression ('for' token already eaten) - pub fn parse_for_expr(&mut self, opt_ident: Option) -> PResult> { + pub fn parse_for_expr(&mut self, opt_ident: Option, + span_lo: BytePos) -> PResult> { // Parse: `for in ` - let lo = self.last_span.lo; let pat = try!(self.parse_pat_nopanic()); try!(self.expect_keyword(keywords::In)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let loop_block = try!(self.parse_block()); let hi = self.last_span.hi; - Ok(self.mk_expr(lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))) + Ok(self.mk_expr(span_lo, hi, ExprForLoop(pat, expr, loop_block, opt_ident))) } /// Parse a 'while' or 'while let' expression ('while' token already eaten) - pub fn parse_while_expr(&mut self, opt_ident: Option) -> PResult> { + pub fn parse_while_expr(&mut self, opt_ident: Option, + span_lo: BytePos) -> PResult> { if self.token.is_keyword(keywords::Let) { - return self.parse_while_let_expr(opt_ident); + return self.parse_while_let_expr(opt_ident, span_lo); } - let lo = self.last_span.lo; let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let body = try!(self.parse_block()); let hi = body.span.hi; - return Ok(self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident))); + return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident))); } /// Parse a 'while let' expression ('while' token already eaten) - pub fn parse_while_let_expr(&mut self, opt_ident: Option) -> PResult> { - let lo = self.last_span.lo; + pub fn parse_while_let_expr(&mut self, opt_ident: Option, + span_lo: BytePos) -> PResult> { try!(self.expect_keyword(keywords::Let)); let pat = try!(self.parse_pat_nopanic()); try!(self.expect(&token::Eq)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); let body = try!(self.parse_block()); let hi = body.span.hi; - return Ok(self.mk_expr(lo, hi, ExprWhileLet(pat, expr, body, opt_ident))); + return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident))); } - pub fn parse_loop_expr(&mut self, opt_ident: Option) -> PResult> { - let lo = self.last_span.lo; + pub fn parse_loop_expr(&mut self, opt_ident: Option, + span_lo: BytePos) -> PResult> { let body = try!(self.parse_block()); let hi = body.span.hi; - Ok(self.mk_expr(lo, hi, ExprLoop(body, opt_ident))) + Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident))) } fn parse_match_expr(&mut self) -> PResult> { diff --git a/src/test/compile-fail/issue-27042.rs b/src/test/compile-fail/issue-27042.rs new file mode 100644 index 00000000000..f31389f1337 --- /dev/null +++ b/src/test/compile-fail/issue-27042.rs @@ -0,0 +1,26 @@ +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #27042. Test that a loop's label is included in its span. + +fn main() { + let _: i32 = + 'a: //~ ERROR mismatched types + loop { break }; + let _: i32 = + 'b: //~ ERROR mismatched types + while true { break }; + let _: i32 = + 'c: //~ ERROR mismatched types + for _ in None { break }; + let _: i32 = + 'd: //~ ERROR mismatched types + while let Some(_) = None { break }; +} -- cgit 1.4.1-3-g733a5 From f47d20aecdcd7db34d41ad1666fd3eee095cc943 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 6 Jul 2015 14:13:19 +1200 Subject: Use a span from the correct file for the inner span of a module This basically only affects modules which are empty (or only contain comments). Closes #26755 --- src/librustdoc/clean/mod.rs | 4 ++++ src/libsyntax/codemap.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 1 + src/libsyntax/parse/mod.rs | 11 +++++++++-- src/libsyntax/parse/parser.rs | 24 ++++++++++++++---------- 5 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3cc24550297..d4eeaa1de10 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1947,6 +1947,10 @@ impl Span { impl Clean for syntax::codemap::Span { fn clean(&self, cx: &DocContext) -> Span { + if *self == DUMMY_SP { + return Span::empty(); + } + let cm = cx.sess().codemap(); let filename = cm.span_to_filename(*self); let lo = cm.lookup_char_pos(self.lo); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3e5c10702b6..e6bc3218897 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -894,7 +894,7 @@ impl CodeMap { FileMapAndBytePos {fm: fm, pos: offset} } - /// Converts an absolute BytePos to a CharPos relative to the filemap and above. + /// Converts an absolute BytePos to a CharPos relative to the filemap. pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { let idx = self.lookup_filemap_idx(bpos); let files = self.files.borrow(); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b6a3788dacc..621335ecd97 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -231,6 +231,7 @@ impl<'a> StringReader<'a> { None => { if self.is_eof() { self.peek_tok = token::Eof; + self.peek_span = codemap::mk_sp(self.filemap.end_pos, self.filemap.end_pos); } else { let start_bytepos = self.last_pos; self.peek_tok = self.next_token_inner(); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index d6c28d41447..34a63fc92fe 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -11,7 +11,7 @@ //! The main parser interface use ast; -use codemap::{Span, CodeMap, FileMap}; +use codemap::{self, Span, CodeMap, FileMap}; use diagnostic::{SpanHandler, Handler, Auto, FatalError}; use parse::attr::ParserAttr; use parse::parser::Parser; @@ -203,7 +203,14 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc, cfg: ast::CrateConfig) -> Parser<'a> { - tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg) + let end_pos = filemap.end_pos; + let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg); + + if parser.token == token::Eof && parser.span == codemap::DUMMY_SP { + parser.span = codemap::mk_sp(end_pos, end_pos); + } + + parser } // must preserve old name for now, because quote! from the *existing* diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 28802d323c6..db1b2489f1d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4824,8 +4824,14 @@ impl<'a> Parser<'a> { return Err(self.fatal(&format!("expected item, found `{}`", token_str))); } + let hi = if self.span == codemap::DUMMY_SP { + inner_lo + } else { + self.span.lo + }; + Ok(ast::Mod { - inner: mk_sp(inner_lo, self.span.lo), + inner: mk_sp(inner_lo, hi), items: items }) } @@ -4869,8 +4875,7 @@ impl<'a> Parser<'a> { fn push_mod_path(&mut self, id: Ident, attrs: &[Attribute]) { let default_path = self.id_to_interned_str(id); - let file_path = match ::attr::first_attr_value_str_by_name(attrs, - "path") { + let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") { Some(d) => d, None => default_path, }; @@ -5003,13 +5008,12 @@ impl<'a> Parser<'a> { included_mod_stack.push(path.clone()); drop(included_mod_stack); - let mut p0 = - new_sub_parser_from_file(self.sess, - self.cfg.clone(), - &path, - owns_directory, - Some(name), - id_sp); + let mut p0 = new_sub_parser_from_file(self.sess, + self.cfg.clone(), + &path, + owns_directory, + Some(name), + id_sp); let mod_inner_lo = p0.span.lo; let mod_attrs = p0.parse_inner_attributes(); let m0 = try!(p0.parse_mod_items(&token::Eof, mod_inner_lo)); -- cgit 1.4.1-3-g733a5 From b36d107b83388606ed4ce2b58941f0d905983958 Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Tue, 21 Jul 2015 23:04:23 +0200 Subject: Assign proper span to range expression --- src/libsyntax/parse/parser.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 28802d323c6..be13f9a130e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2738,14 +2738,15 @@ impl<'a> Parser<'a> { // (much lower than other prefix expressions) to be consistent // with the postfix-form 'expr..' let lo = self.span.lo; + let mut hi = self.span.hi; try!(self.bump()); let opt_end = if self.is_at_start_of_range_notation_rhs() { let end = try!(self.parse_binops()); + hi = end.span.hi; Some(end) } else { None }; - let hi = self.span.hi; let ex = self.mk_range(None, opt_end); Ok(self.mk_expr(lo, hi, ex)) } @@ -2787,17 +2788,17 @@ impl<'a> Parser<'a> { } // A range expression, either `expr..expr` or `expr..`. token::DotDot => { + let lo = lhs.span.lo; + let mut hi = self.span.hi; try!(self.bump()); let opt_end = if self.is_at_start_of_range_notation_rhs() { let end = try!(self.parse_binops()); + hi = end.span.hi; Some(end) } else { None }; - - let lo = lhs.span.lo; - let hi = self.span.hi; let range = self.mk_range(Some(lhs), opt_end); return Ok(self.mk_expr(lo, hi, range)); } -- cgit 1.4.1-3-g733a5 From 9f6f35bef4986e02f811a1fb7c3da212241784a8 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 21 Jul 2015 18:31:37 +0200 Subject: Added support for parsing `in PLACE { BLOCK_CONTENT }`. --- src/libsyntax/parse/parser.rs | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index db1b2489f1d..6c10d6efa50 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2612,18 +2612,43 @@ impl<'a> Parser<'a> { ex = ExprAddrOf(m, e); } token::Ident(_, _) => { - if !self.check_keyword(keywords::Box) { + if !self.check_keyword(keywords::Box) && !self.check_keyword(keywords::In) { return self.parse_dot_or_call_expr(); } let lo = self.span.lo; - let box_hi = self.span.hi; + let keyword_hi = self.span.hi; + let is_in = self.token.is_keyword(keywords::In); try!(self.bump()); - // Check for a place: `box(PLACE) EXPR`. + if is_in { + let place = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL)); + let blk = try!(self.parse_block()); + hi = blk.span.hi; + let blk_expr = self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk)); + ex = ExprBox(Some(place), blk_expr); + return Ok(self.mk_expr(lo, hi, ex)); + } + + // FIXME (#22181) Remove `box (PLACE) EXPR` support + // entirely after next release (enabling `(box (EXPR))`), + // since it will be replaced by `in PLACE { EXPR }`, ... + // + // ... but for now: check for a place: `box(PLACE) EXPR`. + if try!(self.eat(&token::OpenDelim(token::Paren)) ){ - // Support `box() EXPR` as the default. + // SNAP ba0e1cd + // Enable this warning after snapshot ... + // + // let box_span = mk_sp(lo, self.last_span.hi); + // self.span_warn( + // box_span, + // "deprecated syntax; use the `in` keyword now \ + // (e.g. change `box () ` to \ + // `in { }`)"); + + // Continue supporting `box () EXPR` (temporarily) if !try!(self.eat(&token::CloseDelim(token::Paren)) ){ let place = try!(self.parse_expr_nopanic()); try!(self.expect(&token::CloseDelim(token::Paren))); @@ -2634,10 +2659,9 @@ impl<'a> Parser<'a> { self.span_err(span, &format!("expected expression, found `{}`", this_token_to_string)); - let box_span = mk_sp(lo, box_hi); - self.span_suggestion(box_span, - "try using `box()` instead:", - "box()".to_string()); + let box_span = mk_sp(lo, keyword_hi); + let new_expr = format!("box () {}", pprust::expr_to_string(&place)); + self.span_suggestion(box_span, "try using `box ()` instead:", new_expr); self.abort_if_errors(); } let subexpression = try!(self.parse_prefix_expr()); @@ -2650,6 +2674,7 @@ impl<'a> Parser<'a> { // Otherwise, we use the unique pointer default. let subexpression = try!(self.parse_prefix_expr()); hi = subexpression.span.hi; + // FIXME (pnkfelix): After working out kinks with box // desugaring, should be `ExprBox(None, subexpression)` // instead. -- cgit 1.4.1-3-g733a5 From abad7d6bba9d3fa9d5f1126c8ef6f1b413db1152 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 22 Jul 2015 23:23:36 +0200 Subject: placate `make tidy`. --- src/libcore/intrinsics.rs | 2 +- src/libsyntax/parse/parser.rs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index a1d7867431b..1d466895f2c 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -190,7 +190,7 @@ extern "rust-intrinsic" { /// Drop glue is not run on the destination. pub fn move_val_init(dst: *mut T, src: T); - // SNAP ba0e1cd + // SNAP d4432b3 #[cfg(stage0)] /// Moves a value to an uninitialized memory location. /// diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6c10d6efa50..c229ac31fc0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2638,7 +2638,7 @@ impl<'a> Parser<'a> { // ... but for now: check for a place: `box(PLACE) EXPR`. if try!(self.eat(&token::OpenDelim(token::Paren)) ){ - // SNAP ba0e1cd + // SNAP d4432b3 // Enable this warning after snapshot ... // // let box_span = mk_sp(lo, self.last_span.hi); @@ -2659,9 +2659,15 @@ impl<'a> Parser<'a> { self.span_err(span, &format!("expected expression, found `{}`", this_token_to_string)); + + // Spanning just keyword avoids constructing + // printout of arg expression (which starts + // with parenthesis, as established above). + let box_span = mk_sp(lo, keyword_hi); - let new_expr = format!("box () {}", pprust::expr_to_string(&place)); - self.span_suggestion(box_span, "try using `box ()` instead:", new_expr); + self.span_suggestion(box_span, + "try using `box ()` instead:", + format!("box ()")); self.abort_if_errors(); } let subexpression = try!(self.parse_prefix_expr()); -- cgit 1.4.1-3-g733a5 From adfdbc4bd75f2581e9ad0151b26fb786b64475f8 Mon Sep 17 00:00:00 2001 From: mitaa Date: Sat, 25 Jul 2015 22:43:35 +0200 Subject: Remove `ast::LocalSource` with only one used variant `LocalSource` indicated wether a let binding originated from for-loop desugaring to enable specialized error messages, but for-loop expansion has changed and this is now achieved through `MatchSource::ForLoopDesugar`. --- src/librustc/middle/check_match.rs | 8 +------- src/libsyntax/ast.rs | 10 ---------- src/libsyntax/ext/build.rs | 2 -- src/libsyntax/ext/expand.rs | 3 +-- src/libsyntax/fold.rs | 3 +-- src/libsyntax/parse/parser.rs | 3 +-- 6 files changed, 4 insertions(+), 25 deletions(-) (limited to 'src/libsyntax/parse/parser.rs') diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index ea86fa318b4..d1467b67310 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -1016,16 +1016,10 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) { visit::walk_local(cx, loc); - let name = match loc.source { - ast::LocalLet => "local", - ast::LocalFor => "`for` loop" - }; - let mut static_inliner = StaticInliner::new(cx.tcx, None); is_refutable(cx, &*static_inliner.fold_pat(loc.pat.clone()), |pat| { span_err!(cx.tcx.sess, loc.pat.span, E0005, - "refutable pattern in {} binding: `{}` not covered", - name, pat_to_string(pat) + "refutable pattern in local binding: `{}` not covered", pat_to_string(pat) ); }); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fba9db401db..72711f2ed18 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -29,7 +29,6 @@ pub use self::Item_::*; pub use self::KleeneOp::*; pub use self::Lit_::*; pub use self::LitIntType::*; -pub use self::LocalSource::*; pub use self::Mac_::*; pub use self::MacStmtStyle::*; pub use self::MetaItem_::*; @@ -756,14 +755,6 @@ pub enum MacStmtStyle { MacStmtWithoutBraces, } -/// Where a local declaration came from: either a true `let ... = -/// ...;`, or one desugared from the pattern of a for loop. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum LocalSource { - LocalLet, - LocalFor, -} - // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. /// Local represents a `let` statement, e.g., `let : = ;` @@ -775,7 +766,6 @@ pub struct Local { pub init: Option>, pub id: NodeId, pub span: Span, - pub source: LocalSource, } pub type Decl = Spanned; diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 8a80e291a53..79210cb3260 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -538,7 +538,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { init: Some(ex), id: ast::DUMMY_NODE_ID, span: sp, - source: ast::LocalLet, }); let decl = respan(sp, ast::DeclLocal(local)); P(respan(sp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))) @@ -562,7 +561,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { init: Some(ex), id: ast::DUMMY_NODE_ID, span: sp, - source: ast::LocalLet, }); let decl = respan(sp, ast::DeclLocal(local)); P(respan(sp, ast::StmtDecl(P(decl), ast::DUMMY_NODE_ID))) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index faa1e5b2f51..286dc91299f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -911,7 +911,7 @@ fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroE StmtDecl(decl, node_id) => decl.and_then(|Spanned {node: decl, span}| match decl { DeclLocal(local) => { // take it apart: - let rewritten_local = local.map(|Local {id, pat, ty, init, source, span}| { + let rewritten_local = local.map(|Local {id, pat, ty, init, span}| { // expand the ty since TyFixedLengthVec contains an Expr // and thus may have a macro use let expanded_ty = ty.map(|t| fld.fold_ty(t)); @@ -941,7 +941,6 @@ fn expand_non_macro_stmt(Spanned {node, span: stmt_span}: Stmt, fld: &mut MacroE pat: rewritten_pat, // also, don't forget to expand the init: init: init.map(|e| fld.fold_expr(e)), - source: source, span: span } }); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 14742d2e74c..dab6d41df30 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -515,12 +515,11 @@ pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedPara } pub fn noop_fold_local(l: P, fld: &mut T) -> P { - l.map(|Local {id, pat, ty, init, source, span}| Local { + l.map(|Local {id, pat, ty, init, span}| Local { id: fld.new_id(id), ty: ty.map(|t| fld.fold_ty(t)), pat: fld.fold_pat(pat), init: init.map(|e| fld.fold_expr(e)), - source: source, span: fld.new_span(span) }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c2a2259a80a..04665140e2f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -35,7 +35,7 @@ use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl}; use ast::{ItemExternCrate, ItemUse}; use ast::{LifetimeDef, Lit, Lit_}; use ast::{LitBool, LitChar, LitByte, LitBinary}; -use ast::{LitStr, LitInt, Local, LocalLet}; +use ast::{LitStr, LitInt, Local}; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource}; use ast::{MutTy, BiMul, Mutability}; @@ -3432,7 +3432,6 @@ impl<'a> Parser<'a> { init: init, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, self.last_span.hi), - source: LocalLet, })) } -- cgit 1.4.1-3-g733a5