]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #45322 - infinity0:master, r=alexcrichton
authorbors <bors@rust-lang.org>
Mon, 6 Nov 2017 18:04:13 +0000 (18:04 +0000)
committerbors <bors@rust-lang.org>
Mon, 6 Nov 2017 18:04:13 +0000 (18:04 +0000)
When cross-compiling, also build target-arch tarballs for libstd. (Closes: #42320)

Half of the logic is actually in there already in install.rs:install_std but it fails with an error like:

sh: 0: Can't open /<<BUILDDIR>>/rustc-1.21.0+dfsg1/build/tmp/dist/rust-std-1.21.0-powerpc64le-unknown-linux-gnu/install.sh

because the target-arch dist tarball wasn't built as well. This commit fixes that so the overall install works.

There is one minor bug in the existing code which this commit doesn't fix - the install.log from multiple runs of the installer gets clobbered, which seems like it might interfere with the uninstall process (I didn't look very deeply into this, because it doesn't affect what I need to do.) The actual installed files under DESTDIR seem fine though - either they are installed under an arch-specific path, or the multiple runs will clobber the same path with the same arch-independent file.

12 files changed:
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/span_utils.rs
src/libstd/io/buffered.rs
src/libsyntax/json.rs
src/test/ui/lint/unused_parens_json_suggestion.rs
src/test/ui/lint/unused_parens_json_suggestion.stderr
src/test/ui/lint/use_suggestion_json.rs
src/test/ui/lint/use_suggestion_json.stderr
src/tools/compiletest/src/runtest.rs

index 8401d493b9dbf575eabf6a72c0fdba8c54cd4a2d..c4fc30429e0aabe965516f3fcd8c68d186c57a5f 100644 (file)
@@ -155,7 +155,7 @@ pub fn extension(&self) -> &'static str {
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum ErrorOutputType {
     HumanReadable(ColorConfig),
-    Json,
+    Json(bool),
     Short(ColorConfig),
 }
 
@@ -1433,7 +1433,8 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
     let error_format = if matches.opts_present(&["error-format".to_owned()]) {
         match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
             Some("human") => ErrorOutputType::HumanReadable(color),
-            Some("json")  => ErrorOutputType::Json,
+            Some("json")  => ErrorOutputType::Json(false),
+            Some("pretty-json") => ErrorOutputType::Json(true),
             Some("short") => ErrorOutputType::Short(color),
 
             None => ErrorOutputType::HumanReadable(color),
@@ -1474,6 +1475,11 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
 
     let debugging_opts = build_debugging_options(matches, error_format);
 
+    if !debugging_opts.unstable_options && error_format == ErrorOutputType::Json(true) {
+        early_error(ErrorOutputType::Json(false),
+                    "--error-format=pretty-json is unstable");
+    }
+
     let mut output_types = BTreeMap::new();
     if !debugging_opts.parse_only {
         for list in matches.opt_strs("emit") {
@@ -2254,46 +2260,46 @@ fn test_search_paths_tracking_hash_different_values() {
         let mut v5 = super::basic_options();
 
         // Reference
-        v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
+        v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
 
         // Native changed
-        v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
+        v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
 
         // Crate changed
-        v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
+        v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
 
         // Dependency changed
-        v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
+        v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
 
         // Framework changed
-        v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
+        v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
 
         // All changed
-        v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json);
+        v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json(false));
 
         assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
         assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
@@ -2316,29 +2322,29 @@ fn test_search_paths_tracking_hash_different_order() {
         let mut v4 = super::basic_options();
 
         // Reference
-        v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
-
-        v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
-
-        v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
-
-        v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json);
-        v4.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json);
+        v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
+
+        v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
+
+        v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
+
+        v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+        v4.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
 
         assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
         assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
index a15a9a84580b307ea6adde1b4ef9107a094fc800..39cf50787effedeb7353e5fbf462ac03551bf1b0 100644 (file)
@@ -372,7 +372,7 @@ fn diag_once<'a, 'b>(&'a self,
         match self.opts.error_format {
             // when outputting JSON for tool consumption, the tool might want
             // the duplicates
-            config::ErrorOutputType::Json => {
+            config::ErrorOutputType::Json(_) => {
                 do_method()
             },
             _ => {
@@ -736,11 +736,11 @@ pub fn build_session_with_codemap(sopts: config::Options,
         (config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
             Box::new(EmitterWriter::new(dst, Some(codemap.clone()), false))
         }
-        (config::ErrorOutputType::Json, None) => {
-            Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
+        (config::ErrorOutputType::Json(pretty), None) => {
+            Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(), pretty))
         }
-        (config::ErrorOutputType::Json, Some(dst)) => {
-            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone()))
+        (config::ErrorOutputType::Json(pretty), Some(dst)) => {
+            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(), pretty))
         }
         (config::ErrorOutputType::Short(color_config), None) => {
             Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true))
@@ -918,7 +918,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
         config::ErrorOutputType::HumanReadable(color_config) => {
             Box::new(EmitterWriter::stderr(color_config, None, false))
         }
-        config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
+        config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
         config::ErrorOutputType::Short(color_config) => {
             Box::new(EmitterWriter::stderr(color_config, None, true))
         }
@@ -933,7 +933,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
         config::ErrorOutputType::HumanReadable(color_config) => {
             Box::new(EmitterWriter::stderr(color_config, None, false))
         }
-        config::ErrorOutputType::Json => Box::new(JsonEmitter::basic()),
+        config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
         config::ErrorOutputType::Short(color_config) => {
             Box::new(EmitterWriter::stderr(color_config, None, true))
         }
index 23f6e6b46bad5a883785a7907996f59ee092453c..d190ae1431fd80db73e78f9d15c27645a924f7d2 100644 (file)
@@ -521,39 +521,41 @@ fn process_struct(&mut self,
                       item: &'l ast::Item,
                       def: &'l ast::VariantData,
                       ty_params: &'l ast::Generics) {
+        debug!("process_struct {:?} {:?}", item, item.span);
         let name = item.ident.to_string();
         let qualname = format!("::{}", self.tcx.node_path_str(item.id));
 
-        let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct);
-        let (value, fields) =
-            if let ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) = item.node
-        {
-            let include_priv_fields = !self.save_ctxt.config.pub_only;
-            let fields_str = fields
-                .iter()
-                .enumerate()
-                .filter_map(|(i, f)| {
-                     if include_priv_fields || f.vis == ast::Visibility::Public {
-                         f.ident.map(|i| i.to_string()).or_else(|| Some(i.to_string()))
-                     } else {
-                         None
-                     }
-                })
-                .collect::<Vec<_>>()
-                .join(", ");
-            let value = format!("{} {{ {} }}", name, fields_str);
-            (value, fields.iter().map(|f| ::id_from_node_id(f.id, &self.save_ctxt)).collect())
-        } else {
-            (String::new(), vec![])
+        let (kind, keyword) = match item.node {
+            ast::ItemKind::Struct(_, _) => (DefKind::Struct, keywords::Struct),
+            ast::ItemKind::Union(_, _) => (DefKind::Union, keywords::Union),
+            _ => unreachable!(),
+        };
+
+        let sub_span = self.span.sub_span_after_keyword(item.span, keyword);
+        let (value, fields) = match item.node {
+            ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) |
+            ast::ItemKind::Union(ast::VariantData::Struct(ref fields, _), _) => {
+                let include_priv_fields = !self.save_ctxt.config.pub_only;
+                let fields_str = fields
+                    .iter()
+                    .enumerate()
+                    .filter_map(|(i, f)| {
+                         if include_priv_fields || f.vis == ast::Visibility::Public {
+                             f.ident.map(|i| i.to_string()).or_else(|| Some(i.to_string()))
+                         } else {
+                             None
+                         }
+                    })
+                    .collect::<Vec<_>>()
+                    .join(", ");
+                let value = format!("{} {{ {} }}", name, fields_str);
+                (value, fields.iter().map(|f| ::id_from_node_id(f.id, &self.save_ctxt)).collect())
+            }
+            _ => (String::new(), vec![])
         };
 
         if !self.span.filter_generated(sub_span, item.span) {
             let span = self.span_from_span(sub_span.expect("No span found for struct"));
-            let kind = match item.node {
-                ast::ItemKind::Struct(_, _) => DefKind::Struct,
-                ast::ItemKind::Union(_, _) => DefKind::Union,
-                _ => unreachable!(),
-            };
             self.dumper.dump_def(item.vis == ast::Visibility::Public, Def {
                 kind,
                 id: ::id_from_node_id(item.id, &self.save_ctxt),
@@ -876,6 +878,7 @@ fn process_method_call(&mut self,
                            ex: &'l ast::Expr,
                            seg: &'l ast::PathSegment,
                            args: &'l [P<ast::Expr>]) {
+        debug!("process_method_call {:?} {:?}", ex, ex.span);
         if let Some(mcd) = self.save_ctxt.get_expr_data(ex) {
             down_cast_data!(mcd, RefData, ex.span);
             if !generated_code(ex.span) {
index 5ae1ba92262f5cc0e8202e024943de961076e7c5..edb51ae59e1b56c8b431893212f0e0fd87aa9693 100644 (file)
@@ -546,16 +546,16 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
                     }
                 }
             }
-            ast::ExprKind::MethodCall(..) => {
+            ast::ExprKind::MethodCall(ref seg, ..) => {
                 let expr_hir_id = self.tcx.hir.definitions().node_to_hir_id(expr.id);
                 let method_id = self.tables.type_dependent_defs()[expr_hir_id].def_id();
                 let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
                     ty::ImplContainer(_) => (Some(method_id), None),
                     ty::TraitContainer(_) => (None, Some(method_id)),
                 };
-                let sub_span = self.span_utils.sub_span_for_meth_name(expr.span);
-                filter!(self.span_utils, sub_span, expr.span, None);
-                let span = self.span_from_span(sub_span.unwrap());
+                let sub_span = seg.span;
+                filter!(self.span_utils, Some(sub_span), expr.span, None);
+                let span = self.span_from_span(sub_span);
                 Some(Data::RefData(Ref {
                     kind: RefKind::Function,
                     span,
@@ -627,13 +627,18 @@ fn fn_type(path: &ast::Path) -> bool {
             false
         }
 
+        if path.segments.is_empty() {
+            return None;
+        }
+
         let def = self.get_path_def(id);
-        let sub_span = self.span_utils.span_for_last_ident(path.span);
-        filter!(self.span_utils, sub_span, path.span, None);
+        let last_seg = &path.segments[path.segments.len() - 1];
+        let sub_span = last_seg.span;
+        filter!(self.span_utils, Some(sub_span), path.span, None);
         match def {
             HirDef::Upvar(id, ..) |
             HirDef::Local(id) => {
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Variable,
                     span,
@@ -644,7 +649,7 @@ fn fn_type(path: &ast::Path) -> bool {
             HirDef::Const(..) |
             HirDef::AssociatedConst(..) |
             HirDef::VariantCtor(..) => {
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Variable,
                     span,
@@ -670,7 +675,7 @@ fn fn_type(path: &ast::Path) -> bool {
             HirDef::AssociatedTy(def_id) |
             HirDef::Trait(def_id) |
             HirDef::TyParam(def_id) => {
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Type,
                     span,
@@ -681,7 +686,7 @@ fn fn_type(path: &ast::Path) -> bool {
                 // This is a reference to a tuple struct where the def_id points
                 // to an invisible constructor function. That is not a very useful
                 // def, so adjust to point to the tuple struct itself.
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
                 Some(Ref {
                     kind: RefKind::Type,
@@ -690,8 +695,6 @@ fn fn_type(path: &ast::Path) -> bool {
                 })
             }
             HirDef::Method(decl_id) => {
-                let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
-                filter!(self.span_utils, sub_span, path.span, None);
                 let def_id = if decl_id.is_local() {
                     let ti = self.tcx.associated_item(decl_id);
                     self.tcx.associated_items(ti.container.id())
@@ -700,7 +703,7 @@ fn fn_type(path: &ast::Path) -> bool {
                 } else {
                     None
                 };
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Function,
                     span,
@@ -708,7 +711,7 @@ fn fn_type(path: &ast::Path) -> bool {
                 })
             }
             HirDef::Fn(def_id) => {
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Function,
                     span,
@@ -716,7 +719,7 @@ fn fn_type(path: &ast::Path) -> bool {
                 })
             }
             HirDef::Mod(def_id) => {
-                let span = self.span_from_span(sub_span.unwrap());
+                let span = self.span_from_span(sub_span);
                 Some(Ref {
                     kind: RefKind::Mod,
                     span,
index b9d82b8e2512a1c21bb64a871c7b879c6274222f..5bfb4d1b3b20389546be7f1fba6538b64fe5165f 100644 (file)
@@ -103,47 +103,6 @@ pub fn span_for_first_ident(&self, span: Span) -> Option<Span> {
         }
     }
 
-    // Return the span for the last ident before a `(` or `<` or '::<' and outside any
-    // any brackets, or the last span.
-    pub fn sub_span_for_meth_name(&self, span: Span) -> Option<Span> {
-        let mut toks = self.retokenise_span(span);
-        let mut prev = toks.real_token();
-        let mut result = None;
-        let mut bracket_count = 0;
-        let mut prev_span = None;
-        while prev.tok != token::Eof {
-            prev_span = None;
-            let mut next = toks.real_token();
-
-            if (next.tok == token::OpenDelim(token::Paren) || next.tok == token::Lt) &&
-               bracket_count == 0 && prev.tok.is_ident() {
-                result = Some(prev.sp);
-            }
-
-            if bracket_count == 0 && next.tok == token::ModSep {
-                let old = prev;
-                prev = next;
-                next = toks.real_token();
-                if next.tok == token::Lt && old.tok.is_ident() {
-                    result = Some(old.sp);
-                }
-            }
-
-            bracket_count += match prev.tok {
-                token::OpenDelim(token::Paren) | token::Lt => 1,
-                token::CloseDelim(token::Paren) | token::Gt => -1,
-                token::BinOp(token::Shr) => -2,
-                _ => 0,
-            };
-
-            if prev.tok.is_ident() && bracket_count == 0 {
-                prev_span = Some(prev.sp);
-            }
-            prev = next;
-        }
-        result.or(prev_span)
-    }
-
     // Return the span for the last ident before a `<` and outside any
     // angle brackets, or the last span.
     pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
@@ -330,7 +289,7 @@ pub fn filter_generated(&self, sub_span: Option<Span>, parent: Span) -> bool {
 }
 
 macro_rules! filter {
-    ($util: expr, $span: ident, $parent: expr, None) => {
+    ($util: expr, $span: expr, $parent: expr, None) => {
         if $util.filter_generated($span, $parent) {
             return None;
         }
index 4ebd3554fd1428fc60f2854d7e1bc709fac70382..6d3fbc9d268222d3407b3e4cc8c3bbf43478da01 100644 (file)
@@ -147,6 +147,31 @@ pub fn get_ref(&self) -> &R { &self.inner }
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
 
+    /// Returns `true` if there are no bytes in the internal buffer.
+    ///
+    /// # Examples
+    /// ```
+    /// # #![feature(bufreader_is_empty)]
+    /// use std::io::BufReader;
+    /// use std::io::BufRead;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let f1 = File::open("log.txt")?;
+    /// let mut reader = BufReader::new(f1);
+    /// assert!(reader.is_empty());
+    ///
+    /// if reader.fill_buf()?.len() > 0 {
+    ///     assert!(!reader.is_empty());
+    /// }
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")]
+    pub fn is_empty(&self) -> bool {
+        self.pos == self.cap
+    }
+
     /// Unwraps this `BufReader`, returning the underlying reader.
     ///
     /// Note that any leftover data in the internal buffer is lost.
index 31fe0c234e8d3c45957be7ff1f40c040246f6c1a..74a762f2f622cdf702840e9377fc3d46a39fb312 100644 (file)
 use std::io::{self, Write};
 use std::vec;
 
-use rustc_serialize::json::as_json;
+use rustc_serialize::json::{as_json, as_pretty_json};
 
 pub struct JsonEmitter {
     dst: Box<Write + Send>,
     registry: Option<Registry>,
     cm: Rc<CodeMapper + 'static>,
+    pretty: bool,
 }
 
 impl JsonEmitter {
     pub fn stderr(registry: Option<Registry>,
-                  code_map: Rc<CodeMap>) -> JsonEmitter {
+                  code_map: Rc<CodeMap>,
+                  pretty: bool) -> JsonEmitter {
         JsonEmitter {
             dst: Box::new(io::stderr()),
             registry,
             cm: code_map,
+            pretty,
         }
     }
 
-    pub fn basic() -> JsonEmitter {
+    pub fn basic(pretty: bool) -> JsonEmitter {
         let file_path_mapping = FilePathMapping::empty();
-        JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)))
+        JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)), pretty)
     }
 
     pub fn new(dst: Box<Write + Send>,
                registry: Option<Registry>,
-               code_map: Rc<CodeMap>) -> JsonEmitter {
+               code_map: Rc<CodeMap>,
+               pretty: bool) -> JsonEmitter {
         JsonEmitter {
             dst,
             registry,
             cm: code_map,
+            pretty,
         }
     }
 }
@@ -67,7 +72,12 @@ pub fn new(dst: Box<Write + Send>,
 impl Emitter for JsonEmitter {
     fn emit(&mut self, db: &DiagnosticBuilder) {
         let data = Diagnostic::from_diagnostic_builder(db, self);
-        if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
+        let result = if self.pretty {
+            writeln!(&mut self.dst, "{}", as_pretty_json(&data))
+        } else {
+            writeln!(&mut self.dst, "{}", as_json(&data))
+        };
+        if let Err(e) = result {
             panic!("failed to print diagnostics: {:?}", e);
         }
     }
@@ -85,9 +95,7 @@ struct Diagnostic {
     spans: Vec<DiagnosticSpan>,
     /// Associated diagnostic messages.
     children: Vec<Diagnostic>,
-    /// The message as rustc would render it. Currently this is only
-    /// `Some` for "suggestions", but eventually it will include all
-    /// snippets.
+    /// The message as rustc would render it. Currently this is always `None`
     rendered: Option<String>,
 }
 
@@ -110,9 +118,7 @@ struct DiagnosticSpan {
     /// Label that should be placed at this location (if any)
     label: Option<String>,
     /// If we are suggesting a replacement, this will contain text
-    /// that should be sliced in atop this span. You may prefer to
-    /// load the fully rendered version from the parent `Diagnostic`,
-    /// however.
+    /// that should be sliced in atop this span.
     suggested_replacement: Option<String>,
     /// Macro invocations that created the code at this span, if any.
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
index 15251795d5e082a5078b1dfee673aa62e85d1ee2..ad501e668095ae86cade1f29b49da5929e08a7ca 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: --error-format json
+// compile-flags: --error-format pretty-json -Zunstable-options
 
 // The output for humans should just highlight the whole span without showing
 // the suggested replacement, but we also want to test that suggested
index 02bb76722e6fad7c6a0338de61dcc3af951d2c03..e166f7011b58ac42a2b63205b136046e30dee436 100644 (file)
@@ -1 +1,91 @@
-{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":1001,"byte_end":1014,"line_start":24,"line_end":24,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":27}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"lint level defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":847,"byte_end":860,"line_start":19,"line_end":19,"column_start":9,"column_end":22,"is_primary":true,"text":[{"text":"#![warn(unused_parens)]","highlight_start":9,"highlight_end":22}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":1001,"byte_end":1014,"line_start":24,"line_end":24,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":"    let _a = (1 / (2 + 3));","highlight_start":14,"highlight_end":27}],"label":null,"suggested_replacement":"1 / (2 + 3)","expansion":null}],"children":[],"rendered":null}],"rendered":null}
+{
+  "message": "unnecessary parentheses around assigned value",
+  "code": {
+    "code": "unused_parens",
+    "explanation": null
+  },
+  "level": "warning",
+  "spans": [
+    {
+      "file_name": "$DIR/unused_parens_json_suggestion.rs",
+      "byte_start": 1027,
+      "byte_end": 1040,
+      "line_start": 24,
+      "line_end": 24,
+      "column_start": 14,
+      "column_end": 27,
+      "is_primary": true,
+      "text": [
+        {
+          "text": "    let _a = (1 / (2 + 3));",
+          "highlight_start": 14,
+          "highlight_end": 27
+        }
+      ],
+      "label": null,
+      "suggested_replacement": null,
+      "expansion": null
+    }
+  ],
+  "children": [
+    {
+      "message": "lint level defined here",
+      "code": null,
+      "level": "note",
+      "spans": [
+        {
+          "file_name": "$DIR/unused_parens_json_suggestion.rs",
+          "byte_start": 873,
+          "byte_end": 886,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 9,
+          "column_end": 22,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "#![warn(unused_parens)]",
+              "highlight_start": 9,
+              "highlight_end": 22
+            }
+          ],
+          "label": null,
+          "suggested_replacement": null,
+          "expansion": null
+        }
+      ],
+      "children": [],
+      "rendered": null
+    },
+    {
+      "message": "remove these parentheses",
+      "code": null,
+      "level": "help",
+      "spans": [
+        {
+          "file_name": "$DIR/unused_parens_json_suggestion.rs",
+          "byte_start": 1027,
+          "byte_end": 1040,
+          "line_start": 24,
+          "line_end": 24,
+          "column_start": 14,
+          "column_end": 27,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "    let _a = (1 / (2 + 3));",
+              "highlight_start": 14,
+              "highlight_end": 27
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "1 / (2 + 3)",
+          "expansion": null
+        }
+      ],
+      "children": [],
+      "rendered": null
+    }
+  ],
+  "rendered": null
+}
index 20c24d6405042e15cb128b08d3ef2efd2c080af0..27232c4fec4ad89590c882df463e1bef7faaae28 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: --error-format json
+// compile-flags: --error-format pretty-json -Zunstable-options
 
 // The output for humans should just highlight the whole span without showing
 // the suggested replacement, but we also want to test that suggested
index 2ebe212b93ddb7f0a9db59e5c5103587af86d9a2..fd3b5fe1adadf0be0a26e802ecbf8400a02aac2a 100644 (file)
@@ -1,2 +1,290 @@
-{"message":"cannot find type `Iter` in this scope","code":{"code":"E0412","explanation":"/nThe type name used is not in scope./n/nErroneous code examples:/n/n```compile_fail,E0412/nimpl Something {} // error: type name `Something` is not in scope/n/n// or:/n/ntrait Foo {/n    fn bar(N); // error: type name `N` is not in scope/n}/n/n// or:/n/nfn foo(x: T) {} // type name `T` is not in scope/n```/n/nTo fix this error, please verify you didn't misspell the type name, you did/ndeclare it or imported it into the scope. Examples:/n/n```/nstruct Something;/n/nimpl Something {} // ok!/n/n// or:/n/ntrait Foo {/n    type N;/n/n    fn bar(_: Self::N); // ok!/n}/n/n// or:/n/nfn foo<T>(x: T) {} // ok!/n```/n/nAnother case that causes this error is when a type is imported into a parent/nmodule. To fix this, you can follow the suggestion and use File directly or/n`use super::File;` which will import the types from the parent namespace. An/nexample that causes this error is below:/n/n```compile_fail,E0412/nuse std::fs::File;/n/nmod foo {/n    fn some_function(f: File) {}/n}/n```/n/n```/nuse std::fs::File;/n/nmod foo {/n    // either/n    use super::File;/n    // or/n    // use std::fs::File;/n    fn foo(f: File) {}/n}/n# fn main() {} // don't insert it for us; that'll break imports/n```/n"},"level":"error","spans":[{"file_name":"$DIR/use_suggestion_json.rs","byte_start":862,"byte_end":866,"line_start":20,"line_end":20,"column_start":12,"column_end":16,"is_primary":true,"text":[{"text":"    let x: Iter;","highlight_start":12,"highlight_end":16}],"label":"not found in this scope","suggested_replacement":null,"expansion":null}],"children":[{"message":"possible candidates are found in other modules, you can import them into scope","code":null,"level":"help","spans":[{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::binary_heap::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::btree_map::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::btree_set::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::hash_map::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::hash_set::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::linked_list::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::collections::vec_deque::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::option::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::path::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::result::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::slice::Iter;/n/n","expansion":null},{"file_name":"$DIR/use_suggestion_json.rs","byte_start":839,"byte_end":839,"line_start":19,"line_end":19,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"fn main() {","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":"use std::sync::mpsc::Iter;/n/n","expansion":null}],"children":[],"rendered":null}],"rendered":null}
-{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":null}
+{
+  "message": "cannot find type `Iter` in this scope",
+  "code": {
+    "code": "E0412",
+    "explanation": "/nThe type name used is not in scope./n/nErroneous code examples:/n/n```compile_fail,E0412/nimpl Something {} // error: type name `Something` is not in scope/n/n// or:/n/ntrait Foo {/n    fn bar(N); // error: type name `N` is not in scope/n}/n/n// or:/n/nfn foo(x: T) {} // type name `T` is not in scope/n```/n/nTo fix this error, please verify you didn't misspell the type name, you did/ndeclare it or imported it into the scope. Examples:/n/n```/nstruct Something;/n/nimpl Something {} // ok!/n/n// or:/n/ntrait Foo {/n    type N;/n/n    fn bar(_: Self::N); // ok!/n}/n/n// or:/n/nfn foo<T>(x: T) {} // ok!/n```/n/nAnother case that causes this error is when a type is imported into a parent/nmodule. To fix this, you can follow the suggestion and use File directly or/n`use super::File;` which will import the types from the parent namespace. An/nexample that causes this error is below:/n/n```compile_fail,E0412/nuse std::fs::File;/n/nmod foo {/n    fn some_function(f: File) {}/n}/n```/n/n```/nuse std::fs::File;/n/nmod foo {/n    // either/n    use super::File;/n    // or/n    // use std::fs::File;/n    fn foo(f: File) {}/n}/n# fn main() {} // don't insert it for us; that'll break imports/n```/n"
+  },
+  "level": "error",
+  "spans": [
+    {
+      "file_name": "$DIR/use_suggestion_json.rs",
+      "byte_start": 888,
+      "byte_end": 892,
+      "line_start": 20,
+      "line_end": 20,
+      "column_start": 12,
+      "column_end": 16,
+      "is_primary": true,
+      "text": [
+        {
+          "text": "    let x: Iter;",
+          "highlight_start": 12,
+          "highlight_end": 16
+        }
+      ],
+      "label": "not found in this scope",
+      "suggested_replacement": null,
+      "expansion": null
+    }
+  ],
+  "children": [
+    {
+      "message": "possible candidates are found in other modules, you can import them into scope",
+      "code": null,
+      "level": "help",
+      "spans": [
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::binary_heap::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::btree_map::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::btree_set::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::hash_map::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::hash_set::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::linked_list::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::collections::vec_deque::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::option::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::path::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::result::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::slice::Iter;/n/n",
+          "expansion": null
+        },
+        {
+          "file_name": "$DIR/use_suggestion_json.rs",
+          "byte_start": 865,
+          "byte_end": 865,
+          "line_start": 19,
+          "line_end": 19,
+          "column_start": 1,
+          "column_end": 1,
+          "is_primary": true,
+          "text": [
+            {
+              "text": "fn main() {",
+              "highlight_start": 1,
+              "highlight_end": 1
+            }
+          ],
+          "label": null,
+          "suggested_replacement": "use std::sync::mpsc::Iter;/n/n",
+          "expansion": null
+        }
+      ],
+      "children": [],
+      "rendered": null
+    }
+  ],
+  "rendered": null
+}
+{
+  "message": "aborting due to previous error",
+  "code": null,
+  "level": "error",
+  "spans": [],
+  "children": [],
+  "rendered": null
+}
index de96aa9cdeb7f7902788b9fb9a0a4d79a6e43a28..16c48ccfdd1cd440b36cc1ea639bf41fe10447e1 100644 (file)
@@ -2391,7 +2391,8 @@ fn get_mir_dump_dir(&self) -> PathBuf {
     fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
         let parent_dir = self.testpaths.file.parent().unwrap();
         let cflags = self.props.compile_flags.join(" ");
-        let parent_dir_str = if cflags.contains("--error-format json") {
+        let parent_dir_str = if cflags.contains("--error-format json")
+                             || cflags.contains("--error-format pretty-json") {
             parent_dir.display().to_string().replace("\\", "\\\\")
         } else {
             parent_dir.display().to_string()