From 06fe27866920b3eaf6502f321ccb239cc617db10 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 26 Oct 2020 15:01:39 +0100 Subject: [PATCH 01/27] Fix unindent behavior between different doc comments --- src/librustdoc/passes/unindent_comments.rs | 131 ++++++++++++--------- 1 file changed, 75 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index a9cf5a87f5493..1c856b1da53f1 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -1,7 +1,6 @@ use std::cmp; -use std::string::String; -use crate::clean::{self, DocFragment, Item}; +use crate::clean::{self, DocFragment, DocFragmentKind, Item}; use crate::core::DocContext; use crate::fold::{self, DocFolder}; use crate::passes::Pass; @@ -35,65 +34,85 @@ impl clean::Attributes { } fn unindent_fragments(docs: &mut Vec) { - for fragment in docs { - fragment.doc = unindent(&fragment.doc); - } -} - -fn unindent(s: &str) -> String { - let lines = s.lines().collect::>(); let mut saw_first_line = false; let mut saw_second_line = false; - let min_indent = lines.iter().fold(usize::MAX, |min_indent, line| { - // After we see the first non-whitespace line, look at - // the line we have. If it is not whitespace, and therefore - // part of the first paragraph, then ignore the indentation - // level of the first line - let ignore_previous_indents = - saw_first_line && !saw_second_line && !line.chars().all(|c| c.is_whitespace()); - - let min_indent = if ignore_previous_indents { usize::MAX } else { min_indent }; - - if saw_first_line { - saw_second_line = true; - } - if line.chars().all(|c| c.is_whitespace()) { - min_indent - } else { - saw_first_line = true; - let mut whitespace = 0; - line.chars().all(|char| { - // Compare against either space or tab, ignoring whether they - // are mixed or not - if char == ' ' || char == '\t' { - whitespace += 1; - true + let add = if !docs.windows(2).all(|arr| arr[0].kind == arr[1].kind) + && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) + { + // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to + // "decide" how much the minimum indent will be. + 1 + } else { + 0 + }; + + let min_indent = match docs + .iter() + .map(|fragment| { + fragment.doc.lines().fold(usize::MAX, |min_indent, line| { + // After we see the first non-whitespace line, look at + // the line we have. If it is not whitespace, and therefore + // part of the first paragraph, then ignore the indentation + // level of the first line + let ignore_previous_indents = + saw_first_line && !saw_second_line && !line.chars().all(|c| c.is_whitespace()); + + let min_indent = if ignore_previous_indents { usize::MAX } else { min_indent }; + + if saw_first_line { + saw_second_line = true; + } + + if line.chars().all(|c| c.is_whitespace()) { + min_indent } else { - false + saw_first_line = true; + // Compare against either space or tab, ignoring whether they are + // mixed or not. + let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); + cmp::min(min_indent, whitespace) + + if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add } } - }); - cmp::min(min_indent, whitespace) + }) + }) + .min() + { + Some(x) => x, + None => return, + }; + + let mut first_ignored = false; + for fragment in docs { + let lines: Vec<_> = fragment.doc.lines().collect(); + + if !lines.is_empty() { + let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { + min_indent - add + } else { + min_indent + }; + + let mut iter = lines.iter(); + let mut result = if !first_ignored { + first_ignored = true; + vec![iter.next().unwrap().trim_start().to_string()] + } else { + Vec::new() + }; + result.extend_from_slice( + &iter + .map(|&line| { + if line.chars().all(|c| c.is_whitespace()) { + line.to_string() + } else { + assert!(line.len() >= min_indent); + line[min_indent..].to_string() + } + }) + .collect::>(), + ); + fragment.doc = result.join("\n"); } - }); - - if !lines.is_empty() { - let mut unindented = vec![lines[0].trim_start().to_string()]; - unindented.extend_from_slice( - &lines[1..] - .iter() - .map(|&line| { - if line.chars().all(|c| c.is_whitespace()) { - line.to_string() - } else { - assert!(line.len() >= min_indent); - line[min_indent..].to_string() - } - }) - .collect::>(), - ); - unindented.join("\n") - } else { - s.to_string() } } From b4c35368f41c36484cfa7679acb53d40ffbcce35 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 26 Oct 2020 15:01:57 +0100 Subject: [PATCH 02/27] Add test for doc comments unindent fix --- .../passes/unindent_comments/tests.rs | 60 +++++++++---------- src/test/rustdoc/unindent.rs | 23 +++++++ 2 files changed, 51 insertions(+), 32 deletions(-) create mode 100644 src/test/rustdoc/unindent.rs diff --git a/src/librustdoc/passes/unindent_comments/tests.rs b/src/librustdoc/passes/unindent_comments/tests.rs index c39c03e1249c6..5c1307b6628e3 100644 --- a/src/librustdoc/passes/unindent_comments/tests.rs +++ b/src/librustdoc/passes/unindent_comments/tests.rs @@ -1,26 +1,38 @@ use super::*; +use rustc_span::source_map::DUMMY_SP; + +fn create_doc_fragment(s: &str) -> Vec { + vec![DocFragment { + line: 0, + span: DUMMY_SP, + parent_module: None, + doc: s.to_string(), + kind: DocFragmentKind::SugaredDoc, + }] +} + +#[track_caller] +fn run_test(input: &str, expected: &str) { + let mut s = create_doc_fragment(input); + unindent_fragments(&mut s); + assert_eq!(s[0].doc, expected); +} #[test] fn should_unindent() { - let s = " line1\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); + run_test(" line1\n line2", "line1\nline2"); } #[test] fn should_unindent_multiple_paragraphs() { - let s = " line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\nline2"); + run_test(" line1\n\n line2", "line1\n\nline2"); } #[test] fn should_leave_multiple_indent_levels() { // Line 2 is indented another level beyond the // base indentation and should be preserved - let s = " line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\n line2"); + run_test(" line1\n\n line2", "line1\n\n line2"); } #[test] @@ -30,43 +42,27 @@ fn should_ignore_first_line_indent() { // // #[doc = "Start way over here // and continue here"] - let s = "line1\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); + run_test("line1\n line2", "line1\nline2"); } #[test] fn should_not_ignore_first_line_indent_in_a_single_line_para() { - let s = "line1\n\n line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\n\n line2"); + run_test("line1\n\n line2", "line1\n\n line2"); } #[test] fn should_unindent_tabs() { - let s = "\tline1\n\tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); + run_test("\tline1\n\tline2", "line1\nline2"); } #[test] fn should_trim_mixed_indentation() { - let s = "\t line1\n\t line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); - - let s = " \tline1\n \tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1\nline2"); + run_test("\t line1\n\t line2", "line1\nline2"); + run_test(" \tline1\n \tline2", "line1\nline2"); } #[test] fn should_not_trim() { - let s = "\t line1 \n\t line2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1 \nline2"); - - let s = " \tline1 \n \tline2".to_string(); - let r = unindent(&s); - assert_eq!(r, "line1 \nline2"); + run_test("\t line1 \n\t line2", "line1 \nline2"); + run_test(" \tline1 \n \tline2", "line1 \nline2"); } diff --git a/src/test/rustdoc/unindent.rs b/src/test/rustdoc/unindent.rs new file mode 100644 index 0000000000000..5e3d71ae7d04e --- /dev/null +++ b/src/test/rustdoc/unindent.rs @@ -0,0 +1,23 @@ +#![crate_name = "foo"] + +// @has foo/struct.Example.html +// @matches - '//pre[@class="rust rust-example-rendered"]' \ +// '(?m)let example = Example::new\(\)\n \.first\(\)\n \.second\(\)\n \.build\(\);\Z' +/// ```rust +/// let example = Example::new() +/// .first() +#[cfg_attr(not(feature = "one"), doc = " .second()")] +/// .build(); +/// ``` +pub struct Example; + +// @has foo/struct.F.html +// @matches - '//pre[@class="rust rust-example-rendered"]' \ +// '(?m)let example = Example::new\(\)\n \.first\(\)\n \.another\(\)\n \.build\(\);\Z' +///```rust +///let example = Example::new() +/// .first() +#[cfg_attr(not(feature = "one"), doc = " .another()")] +/// .build(); +/// ``` +pub struct F; From f3e6d882fec61ef290b9097f896cfbcf39f5b4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 16:42:28 +0100 Subject: [PATCH 03/27] Fix typos and replace static vector with slice --- .../rustc_incremental/src/persist/dirty_clean.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index f0a1088555035..d55813f4cc5ad 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -160,7 +160,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { let mut all_attrs = FindAllAttrs { tcx, - attr_names: vec![sym::rustc_dirty, sym::rustc_clean], + attr_names: &[sym::rustc_dirty, sym::rustc_clean], found_attrs: vec![], }; intravisit::walk_crate(&mut all_attrs, krate); @@ -299,7 +299,7 @@ impl DirtyCleanVisitor<'tcx> { // Represents a Trait Declaration // FIXME(michaelwoerister): trait declaration is buggy because sometimes some of - // the depnodes don't exist (because they legitametely didn't need to be + // the depnodes don't exist (because they legitimately didn't need to be // calculated) // // michaelwoerister and vitiral came up with a possible solution, @@ -512,17 +512,17 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol { } // A visitor that collects all #[rustc_dirty]/#[rustc_clean] attributes from -// the HIR. It is used to verfiy that we really ran checks for all annotated +// the HIR. It is used to verify that we really ran checks for all annotated // nodes. -pub struct FindAllAttrs<'tcx> { +pub struct FindAllAttrs<'a, 'tcx> { tcx: TyCtxt<'tcx>, - attr_names: Vec, + attr_names: &'a [Symbol], found_attrs: Vec<&'tcx Attribute>, } -impl FindAllAttrs<'tcx> { +impl FindAllAttrs<'_, 'tcx> { fn is_active_attr(&mut self, attr: &Attribute) -> bool { - for attr_name in &self.attr_names { + for attr_name in self.attr_names { if self.tcx.sess.check_name(attr, *attr_name) && check_config(self.tcx, attr) { return true; } @@ -543,7 +543,7 @@ impl FindAllAttrs<'tcx> { } } -impl intravisit::Visitor<'tcx> for FindAllAttrs<'tcx> { +impl intravisit::Visitor<'tcx> for FindAllAttrs<'_, 'tcx> { type Map = Map<'tcx>; fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { From a21f3a76a9f5c1f7087e9aec6102889cb24a0b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 16:51:41 +0100 Subject: [PATCH 04/27] Clean up encode_dep_graph --- compiler/rustc_incremental/src/persist/save.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index c43d4ad4049c9..45cef479a4f43 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -153,7 +153,8 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { let total_node_count = serialized_graph.nodes.len(); let total_edge_count = serialized_graph.edge_list_data.len(); - let mut counts: FxHashMap<_, Stat> = FxHashMap::default(); + let mut counts: FxHashMap<_, Stat> = + FxHashMap::with_capacity_and_hasher(total_node_count, Default::default()); for (i, &node) in serialized_graph.nodes.iter_enumerated() { let stat = counts.entry(node.kind).or_insert(Stat { @@ -170,14 +171,6 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { let mut counts: Vec<_> = counts.values().cloned().collect(); counts.sort_by_key(|s| -(s.node_counter as i64)); - let percentage_of_all_nodes: Vec = counts - .iter() - .map(|s| (100.0 * (s.node_counter as f64)) / (total_node_count as f64)) - .collect(); - - let average_edges_per_kind: Vec = - counts.iter().map(|s| (s.edge_counter as f64) / (s.node_counter as f64)).collect(); - println!("[incremental]"); println!("[incremental] DepGraph Statistics"); @@ -207,13 +200,13 @@ fn encode_dep_graph(tcx: TyCtxt<'_>, encoder: &mut Encoder) { |------------------|" ); - for (i, stat) in counts.iter().enumerate() { + for stat in counts.iter() { println!( "[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |", format!("{:?}", stat.kind), - percentage_of_all_nodes[i], + (100.0 * (stat.node_counter as f64)) / (total_node_count as f64), // percentage of all nodes stat.node_counter, - average_edges_per_kind[i] + (stat.edge_counter as f64) / (stat.node_counter as f64), // average edges per kind ); } From 5248b20d9ae02a39cb20448896fc663636f591fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 17:04:44 +0100 Subject: [PATCH 05/27] Reuse memory --- compiler/rustc_graphviz/src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 76e33bed97f27..d332466160ce5 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -653,13 +653,13 @@ where writeln!(w, r#" edge[{}];"#, content_attrs_str)?; } + let mut text = Vec::new(); for n in g.nodes().iter() { write!(w, " ")?; let id = g.node_id(n); let escaped = &g.node_label(n).to_dot_string(); - let mut text = Vec::new(); write!(text, "{}", id.as_slice()).unwrap(); if !options.contains(&RenderOption::NoNodeLabels) { @@ -677,6 +677,8 @@ where writeln!(text, ";").unwrap(); w.write_all(&text[..])?; + + text.clear(); } for e in g.edges().iter() { @@ -687,7 +689,6 @@ where let source_id = g.node_id(&source); let target_id = g.node_id(&target); - let mut text = Vec::new(); write!(text, "{} -> {}", source_id.as_slice(), target_id.as_slice()).unwrap(); if !options.contains(&RenderOption::NoEdgeLabels) { @@ -701,6 +702,8 @@ where writeln!(text, ";").unwrap(); w.write_all(&text[..])?; + + text.clear(); } writeln!(w, "}}") From 2fa359814aab054f4b0c9c764a6d6a36ecf6cde8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 17:05:49 +0100 Subject: [PATCH 06/27] Avoid reallocating cgu_path_components --- compiler/rustc_incremental/src/assert_module_sources.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs index 80448c01a262d..17d8ac9c88297 100644 --- a/compiler/rustc_incremental/src/assert_module_sources.rs +++ b/compiler/rustc_incremental/src/assert_module_sources.rs @@ -111,10 +111,12 @@ impl AssertModuleSource<'tcx> { (&user_path[..], None) }; - let mut cgu_path_components = user_path.split('-').collect::>(); + let mut iter = user_path.split('-'); // Remove the crate name - assert_eq!(cgu_path_components.remove(0), crate_name); + assert_eq!(iter.next().unwrap(), crate_name); + + let cgu_path_components = iter.collect::>(); let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); let cgu_name = From a8803d3c04b25928b5ec42b3147c8002de7ac64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 28 Oct 2020 17:21:02 +0100 Subject: [PATCH 07/27] Delete files immediately, instead of collecting into vector --- compiler/rustc_incremental/src/persist/fs.rs | 37 +++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 4926f726f3593..9fdf0a56d9de1 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -765,7 +765,6 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { // Now garbage collect the valid session directories. let mut deletion_candidates = vec![]; - let mut definitely_delete = vec![]; for (lock_file_name, directory_name) in &lock_file_to_session_dir { debug!("garbage_collect_session_directories() - inspecting: {}", directory_name); @@ -842,8 +841,11 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { successfully acquired lock" ); - // Note that we are holding on to the lock - definitely_delete.push((crate_directory.join(directory_name), Some(lock))); + delete_old(sess, &crate_directory.join(directory_name)); + + // Let's make it explicit that the file lock is released at this point, + // or rather, that we held on to it until here + mem::drop(lock); } Err(_) => { debug!( @@ -880,26 +882,21 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { mem::drop(lock); } - for (path, lock) in definitely_delete { - debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); + Ok(()) +} - if let Err(err) = safe_remove_dir_all(&path) { - sess.warn(&format!( - "Failed to garbage collect incremental \ - compilation session directory `{}`: {}", - path.display(), - err - )); - } else { - delete_session_dir_lock_file(sess, &lock_file_path(&path)); - } +fn delete_old(sess: &Session, path: &Path) { + debug!("garbage_collect_session_directories() - deleting `{}`", path.display()); - // Let's make it explicit that the file lock is released at this point, - // or rather, that we held on to it until here - mem::drop(lock); + if let Err(err) = safe_remove_dir_all(&path) { + sess.warn(&format!( + "Failed to garbage collect incremental compilation session directory `{}`: {}", + path.display(), + err + )); + } else { + delete_session_dir_lock_file(sess, &lock_file_path(&path)); } - - Ok(()) } fn all_except_most_recent( From 6bbb7fd26532682051f8d74db954ac1a8650b22c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 29 Oct 2020 11:42:30 +0100 Subject: [PATCH 08/27] Change a bit how the first doc comment lines are handled --- src/librustdoc/passes/unindent_comments.rs | 71 ++++++++++------------ 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 1c856b1da53f1..4f7297c90c5c9 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -34,9 +34,18 @@ impl clean::Attributes { } fn unindent_fragments(docs: &mut Vec) { - let mut saw_first_line = false; - let mut saw_second_line = false; - + // `add` is used in case the most common sugared doc syntax is used ("/// "). The other + // fragments kind's lines are never starting with a whitespace unless they are using some + // markdown formatting requiring it. Therefore, if the doc block have a mix between the two, + // we need to take into account the fact that the minimum indent minus one (to take this + // whitespace into account). + // + // For example: + // + // /// hello! + // #[doc = "another"] + // + // In this case, you want "hello! another" and not "hello! another". let add = if !docs.windows(2).all(|arr| arr[0].kind == arr[1].kind) && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) { @@ -47,27 +56,22 @@ fn unindent_fragments(docs: &mut Vec) { 0 }; + // `min_indent` is used to know how much whitespaces from the start of each lines must be + // removed. Example: + // + // /// hello! + // #[doc = "another"] + // + // In here, the `min_indent` is 1 (because non-sugared fragment are always counted with minimum + // 1 whitespace), meaning that "hello!" will be considered a codeblock because it starts with 4 + // (5 - 1) whitespaces. let min_indent = match docs .iter() .map(|fragment| { fragment.doc.lines().fold(usize::MAX, |min_indent, line| { - // After we see the first non-whitespace line, look at - // the line we have. If it is not whitespace, and therefore - // part of the first paragraph, then ignore the indentation - // level of the first line - let ignore_previous_indents = - saw_first_line && !saw_second_line && !line.chars().all(|c| c.is_whitespace()); - - let min_indent = if ignore_previous_indents { usize::MAX } else { min_indent }; - - if saw_first_line { - saw_second_line = true; - } - if line.chars().all(|c| c.is_whitespace()) { min_indent } else { - saw_first_line = true; // Compare against either space or tab, ignoring whether they are // mixed or not. let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); @@ -82,7 +86,6 @@ fn unindent_fragments(docs: &mut Vec) { None => return, }; - let mut first_ignored = false; for fragment in docs { let lines: Vec<_> = fragment.doc.lines().collect(); @@ -93,26 +96,18 @@ fn unindent_fragments(docs: &mut Vec) { min_indent }; - let mut iter = lines.iter(); - let mut result = if !first_ignored { - first_ignored = true; - vec![iter.next().unwrap().trim_start().to_string()] - } else { - Vec::new() - }; - result.extend_from_slice( - &iter - .map(|&line| { - if line.chars().all(|c| c.is_whitespace()) { - line.to_string() - } else { - assert!(line.len() >= min_indent); - line[min_indent..].to_string() - } - }) - .collect::>(), - ); - fragment.doc = result.join("\n"); + fragment.doc = lines + .iter() + .map(|&line| { + if line.chars().all(|c| c.is_whitespace()) { + line.to_string() + } else { + assert!(line.len() >= min_indent); + line[min_indent..].to_string() + } + }) + .collect::>() + .join("\n"); } } } From fcee70f643d8a40fe82b784e50880d5f8af062c0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 29 Oct 2020 11:43:07 +0100 Subject: [PATCH 09/27] Update tests --- .../passes/unindent_comments/tests.rs | 7 +--- src/test/rustdoc/unindent.md | 1 + src/test/rustdoc/unindent.rs | 41 +++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 src/test/rustdoc/unindent.md diff --git a/src/librustdoc/passes/unindent_comments/tests.rs b/src/librustdoc/passes/unindent_comments/tests.rs index 5c1307b6628e3..9dec71f7683aa 100644 --- a/src/librustdoc/passes/unindent_comments/tests.rs +++ b/src/librustdoc/passes/unindent_comments/tests.rs @@ -37,12 +37,7 @@ fn should_leave_multiple_indent_levels() { #[test] fn should_ignore_first_line_indent() { - // The first line of the first paragraph may not be indented as - // far due to the way the doc string was written: - // - // #[doc = "Start way over here - // and continue here"] - run_test("line1\n line2", "line1\nline2"); + run_test("line1\n line2", "line1\n line2"); } #[test] diff --git a/src/test/rustdoc/unindent.md b/src/test/rustdoc/unindent.md new file mode 100644 index 0000000000000..8e4e7a25af8d7 --- /dev/null +++ b/src/test/rustdoc/unindent.md @@ -0,0 +1 @@ +Just some text. diff --git a/src/test/rustdoc/unindent.rs b/src/test/rustdoc/unindent.rs index 5e3d71ae7d04e..d10e1ec89c59e 100644 --- a/src/test/rustdoc/unindent.rs +++ b/src/test/rustdoc/unindent.rs @@ -1,3 +1,5 @@ +#![feature(external_doc)] + #![crate_name = "foo"] // @has foo/struct.Example.html @@ -21,3 +23,42 @@ pub struct Example; /// .build(); /// ``` pub struct F; + +// @has foo/struct.G.html +// @matches - '//pre[@class="rust rust-example-rendered"]' \ +// '(?m)let example = Example::new\(\)\n\.first\(\)\n \.another\(\)\n\.build\(\);\Z' +///```rust +///let example = Example::new() +///.first() +#[cfg_attr(not(feature = "one"), doc = " .another()")] +///.build(); +///``` +pub struct G; + +// @has foo/struct.H.html +// @has - '//div[@class="docblock"]/p' 'no whitespace lol' +///no whitespace +#[doc = " lol"] +pub struct H; + +// @has foo/struct.I.html +// @matches - '//pre[@class="rust rust-example-rendered"]' '(?m)4 whitespaces!\Z' +/// 4 whitespaces! +#[doc = "something"] +pub struct I; + +// @has foo/struct.J.html +// @matches - '//div[@class="docblock"]/p' '(?m)a\nno whitespace\nJust some text.\Z' +///a +///no whitespace +#[doc(include = "unindent.md")] +pub struct J; + +// @has foo/struct.K.html +// @matches - '//pre[@class="rust rust-example-rendered"]' '(?m)4 whitespaces!\Z' +///a +/// +/// 4 whitespaces! +/// +#[doc(include = "unindent.md")] +pub struct K; From ad278943ada85b8c283423e7ef21a7e28a6a1ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 30 Oct 2020 00:00:00 +0000 Subject: [PATCH 10/27] Move compiletest meta tests to a separate directory --- .../expected-error-correct-rev.a.stderr} | 2 +- .../expected-error-correct-rev.rs} | 2 +- src/test/ui/{meta-revision-bad.rs => meta/revision-bad.rs} | 0 src/test/ui/{meta-revision-ok.rs => meta/revision-ok.rs} | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/test/ui/{meta-expected-error-correct-rev.a.stderr => meta/expected-error-correct-rev.a.stderr} (89%) rename src/test/ui/{meta-expected-error-correct-rev.rs => meta/expected-error-correct-rev.rs} (68%) rename src/test/ui/{meta-revision-bad.rs => meta/revision-bad.rs} (100%) rename src/test/ui/{meta-revision-ok.rs => meta/revision-ok.rs} (83%) diff --git a/src/test/ui/meta-expected-error-correct-rev.a.stderr b/src/test/ui/meta/expected-error-correct-rev.a.stderr similarity index 89% rename from src/test/ui/meta-expected-error-correct-rev.a.stderr rename to src/test/ui/meta/expected-error-correct-rev.a.stderr index 5e6980a9dd1f7..df4dbdbc8e62d 100644 --- a/src/test/ui/meta-expected-error-correct-rev.a.stderr +++ b/src/test/ui/meta/expected-error-correct-rev.a.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/meta-expected-error-correct-rev.rs:7:18 + --> $DIR/expected-error-correct-rev.rs:7:18 | LL | let x: u32 = 22_usize; | --- ^^^^^^^^ expected `u32`, found `usize` diff --git a/src/test/ui/meta-expected-error-correct-rev.rs b/src/test/ui/meta/expected-error-correct-rev.rs similarity index 68% rename from src/test/ui/meta-expected-error-correct-rev.rs rename to src/test/ui/meta/expected-error-correct-rev.rs index b06a64b15c87c..26798c3dfc29f 100644 --- a/src/test/ui/meta-expected-error-correct-rev.rs +++ b/src/test/ui/meta/expected-error-correct-rev.rs @@ -1,6 +1,6 @@ // revisions: a -// Counterpart to `meta-expected-error-wrong-rev.rs` +// Counterpart to `expected-error-wrong-rev.rs` #[cfg(a)] fn foo() { diff --git a/src/test/ui/meta-revision-bad.rs b/src/test/ui/meta/revision-bad.rs similarity index 100% rename from src/test/ui/meta-revision-bad.rs rename to src/test/ui/meta/revision-bad.rs diff --git a/src/test/ui/meta-revision-ok.rs b/src/test/ui/meta/revision-ok.rs similarity index 83% rename from src/test/ui/meta-revision-ok.rs rename to src/test/ui/meta/revision-ok.rs index 7df9a6ea48fae..bbeae41b8bb95 100644 --- a/src/test/ui/meta-revision-ok.rs +++ b/src/test/ui/meta/revision-ok.rs @@ -1,5 +1,5 @@ // Meta test for compiletest: check that when we give the right error -// patterns, the test passes. See all `meta-revision-bad.rs`. +// patterns, the test passes. See all `revision-bad.rs`. // run-fail // revisions: foo bar From affb47fa5750bae1adfbbcf8032bb252369620cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 30 Oct 2020 00:00:00 +0000 Subject: [PATCH 11/27] Add a test for compiletest rustc-env & unset-rustc-env directives --- src/test/ui/meta/auxiliary/env.rs | 9 +++++++++ src/test/ui/meta/rustc-env.rs | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/ui/meta/auxiliary/env.rs create mode 100644 src/test/ui/meta/rustc-env.rs diff --git a/src/test/ui/meta/auxiliary/env.rs b/src/test/ui/meta/auxiliary/env.rs new file mode 100644 index 0000000000000..b3644d8d5943f --- /dev/null +++ b/src/test/ui/meta/auxiliary/env.rs @@ -0,0 +1,9 @@ +// Check that aux builds can also use rustc-env, but environment is configured +// separately from the main test case. +// +// rustc-env:COMPILETEST_BAR=bar + +pub fn test() { + assert_eq!(option_env!("COMPILETEST_FOO"), None); + assert_eq!(env!("COMPILETEST_BAR"), "bar"); +} diff --git a/src/test/ui/meta/rustc-env.rs b/src/test/ui/meta/rustc-env.rs new file mode 100644 index 0000000000000..7d4e005be10cf --- /dev/null +++ b/src/test/ui/meta/rustc-env.rs @@ -0,0 +1,18 @@ +// Compiletest meta test checking that rustc-env and unset-rustc-env directives +// can be used to configure environment for rustc. +// +// run-pass +// aux-build:env.rs +// rustc-env:COMPILETEST_FOO=foo +// +// An environment variable that is likely to be set, but should be safe to unset. +// unset-rustc-env:PWD + +extern crate env; + +fn main() { + assert_eq!(env!("COMPILETEST_FOO"), "foo"); + assert_eq!(option_env!("COMPILETEST_BAR"), None); + assert_eq!(option_env!("PWD"), None); + env::test(); +} From 289c0d8489d02c1bc5cb0b091455fe03cd9384bd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 31 Oct 2020 13:57:56 +0100 Subject: [PATCH 12/27] Retagging: do not retag 'raw reborrows' --- compiler/rustc_mir/src/transform/add_retag.rs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir/src/transform/add_retag.rs b/compiler/rustc_mir/src/transform/add_retag.rs index eec704e6cb775..6fe9f64be32e8 100644 --- a/compiler/rustc_mir/src/transform/add_retag.rs +++ b/compiler/rustc_mir/src/transform/add_retag.rs @@ -73,6 +73,19 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // a temporary and retag on that. is_stable(place.as_ref()) && may_be_reference(place.ty(&*local_decls, tcx).ty) }; + let place_base_raw = |place: &Place<'tcx>| { + // If this is a `Deref`, get the type of what we are deref'ing. + let deref_base = + place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref)); + if let Some(deref_base) = deref_base { + let base_proj = &place.projection[..deref_base]; + let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty; + ty.is_unsafe_ptr() + } else { + // Not a deref, and thus not raw. + false + } + }; // PART 1 // Retag arguments at the beginning of the start block. @@ -136,13 +149,14 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // iterate backwards using indices. for i in (0..block_data.statements.len()).rev() { let (retag_kind, place) = match block_data.statements[i].kind { - // Retag-as-raw after escaping to a raw pointer. - StatementKind::Assign(box (place, Rvalue::AddressOf(..))) => { - (RetagKind::Raw, place) + // Retag-as-raw after escaping to a raw pointer, if the referent + // is not already a raw pointer. + StatementKind::Assign(box (lplace, Rvalue::AddressOf(_, ref rplace))) + if !place_base_raw(rplace) => + { + (RetagKind::Raw, lplace) } - // Assignments of reference or ptr type are the ones where we may have - // to update tags. This includes `x = &[mut] ...` and hence - // we also retag after taking a reference! + // Retag after assignments of reference type. StatementKind::Assign(box (ref place, ref rvalue)) if needs_retag(place) => { let kind = match rvalue { Rvalue::Ref(_, borrow_kind, _) From fef9c63051248209b3e799f733db97ec46d397cc Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 5 Oct 2020 16:36:10 -0700 Subject: [PATCH 13/27] Rust coverage before splitting instrument_coverage.rs --- .../src/coverageinfo/mapgen.rs | 2 +- .../src/coverageinfo/mod.rs | 64 +- .../rustc_codegen_ssa/src/coverageinfo/ffi.rs | 12 +- .../rustc_codegen_ssa/src/coverageinfo/map.rs | 111 ++- .../rustc_codegen_ssa/src/mir/coverageinfo.rs | 19 +- .../src/traits/coverageinfo.rs | 16 +- compiler/rustc_graphviz/src/lib.rs | 1 + compiler/rustc_middle/src/mir/coverage.rs | 88 +- compiler/rustc_middle/src/mir/mod.rs | 21 +- .../rustc_middle/src/ty/structural_impls.rs | 1 + .../src/transform/instrument_coverage.rs | 845 +++++++++++------- compiler/rustc_mir/src/util/graphviz.rs | 4 +- ...ment_coverage.main.InstrumentCoverage.diff | 4 +- src/test/mir-opt/instrument_coverage.rs | 8 +- .../filecheck.testprog.txt | 2 +- .../coverage-reports-base/Makefile | 18 +- .../expected_export_coverage.closure.json | 24 +- .../expected_export_coverage.drop_trait.json | 8 +- .../expected_export_coverage.generics.json | 8 +- .../expected_export_coverage.if.json | 12 +- .../expected_export_coverage.if_else.json | 24 +- .../expected_export_coverage.inner_items.json | 12 +- ...expected_export_coverage.lazy_boolean.json | 28 +- ...ed_export_coverage.loops_and_branches.json | 59 ++ ...expected_export_coverage.nested_loops.json | 59 ++ ...age.partial_eq_counter_without_region.json | 59 ++ .../expected_export_coverage.simple_loop.json | 24 +- ...expected_export_coverage.simple_match.json | 24 +- ...d_export_coverage.tight_infinite_loop.json | 59 ++ ...cted_export_coverage.try_error_result.json | 28 +- ...ed_export_coverage.various_conditions.json | 12 +- .../expected_export_coverage.while.json | 59 ++ ...ed_export_coverage.while_early_return.json | 24 +- .../expected_show_coverage.closure.txt | 4 +- .../expected_show_coverage.drop_trait.txt | 2 +- .../expected_show_coverage.generics.txt | 2 +- .../expected_show_coverage.if.txt | 1 + .../expected_show_coverage.if_else.txt | 4 +- .../expected_show_coverage.inner_items.txt | 2 + .../expected_show_coverage.lazy_boolean.txt | 53 +- ...ected_show_coverage.loops_and_branches.txt | 38 + .../expected_show_coverage.nested_loops.txt | 26 + ...rage.partial_eq_counter_without_region.txt | 101 +++ .../expected_show_coverage.simple_loop.txt | 3 +- .../expected_show_coverage.simple_match.txt | 16 +- ...cted_show_coverage.tight_infinite_loop.txt | 6 + ...xpected_show_coverage.try_error_result.txt | 17 +- ...ected_show_coverage.various_conditions.txt | 2 +- .../expected_show_coverage.while.txt | 6 + ...ected_show_coverage.while_early_return.txt | 6 +- ...xpected_show_coverage_counters.closure.txt | 95 ++ ...cted_show_coverage_counters.drop_trait.txt | 24 + ...pected_show_coverage_counters.generics.txt | 50 ++ .../expected_show_coverage_counters.if.txt | 22 + ...xpected_show_coverage_counters.if_else.txt | 38 + ...ted_show_coverage_counters.inner_items.txt | 61 ++ ...ed_show_coverage_counters.lazy_boolean.txt | 138 +++ ...how_coverage_counters.loop_break_value.txt | 7 + ...w_coverage_counters.loops_and_branches.txt | 39 + ...ed_show_coverage_counters.nested_loops.txt | 76 ++ ...ters.partial_eq_counter_without_region.txt | 28 + ...ted_show_coverage_counters.simple_loop.txt | 38 + ...ed_show_coverage_counters.simple_match.txt | 58 ++ ..._coverage_counters.tight_infinite_loop.txt | 11 + ...how_coverage_counters.try_error_result.txt | 72 ++ ...w_coverage_counters.various_conditions.txt | 240 +++++ .../expected_show_coverage_counters.while.txt | 22 + ...w_coverage_counters.while_early_return.txt | 44 + .../expected_export_coverage.closure.json | 24 +- .../expected_export_coverage.drop_trait.json | 8 +- .../expected_export_coverage.generics.json | 8 +- .../expected_export_coverage.if.json | 12 +- .../expected_export_coverage.if_else.json | 24 +- .../expected_export_coverage.inner_items.json | 12 +- ...expected_export_coverage.lazy_boolean.json | 28 +- ...ed_export_coverage.loops_and_branches.json | 59 ++ ...expected_export_coverage.nested_loops.json | 59 ++ ...age.partial_eq_counter_without_region.json | 59 ++ .../expected_export_coverage.simple_loop.json | 24 +- ...expected_export_coverage.simple_match.json | 24 +- ...d_export_coverage.tight_infinite_loop.json | 59 ++ ...cted_export_coverage.try_error_result.json | 28 +- ...ed_export_coverage.various_conditions.json | 12 +- .../expected_export_coverage.while.json | 59 ++ ...ed_export_coverage.while_early_return.json | 24 +- .../expected_show_coverage.closure.txt | 4 +- .../expected_show_coverage.drop_trait.txt | 2 +- .../expected_show_coverage.generics.txt | 2 +- .../expected_show_coverage.if.txt | 1 + .../expected_show_coverage.if_else.txt | 4 +- .../expected_show_coverage.inner_items.txt | 2 + .../expected_show_coverage.lazy_boolean.txt | 53 +- ...ected_show_coverage.loops_and_branches.txt | 38 + .../expected_show_coverage.nested_loops.txt | 26 + ...rage.partial_eq_counter_without_region.txt | 111 +++ .../expected_show_coverage.simple_loop.txt | 3 +- .../expected_show_coverage.simple_match.txt | 16 +- ...cted_show_coverage.tight_infinite_loop.txt | 6 + ...xpected_show_coverage.try_error_result.txt | 17 +- ...ected_show_coverage.various_conditions.txt | 2 +- .../expected_show_coverage.while.txt | 6 + ...ected_show_coverage.while_early_return.txt | 6 +- ...xpected_show_coverage_counters.closure.txt | 95 ++ ...cted_show_coverage_counters.drop_trait.txt | 24 + ...pected_show_coverage_counters.generics.txt | 50 ++ .../expected_show_coverage_counters.if.txt | 22 + ...xpected_show_coverage_counters.if_else.txt | 38 + ...ted_show_coverage_counters.inner_items.txt | 61 ++ ...ed_show_coverage_counters.lazy_boolean.txt | 138 +++ ...how_coverage_counters.loop_break_value.txt | 7 + ...w_coverage_counters.loops_and_branches.txt | 39 + ...ed_show_coverage_counters.nested_loops.txt | 76 ++ ...ters.partial_eq_counter_without_region.txt | 68 ++ ...ted_show_coverage_counters.simple_loop.txt | 38 + ...ed_show_coverage_counters.simple_match.txt | 58 ++ ..._coverage_counters.tight_infinite_loop.txt | 11 + ...how_coverage_counters.try_error_result.txt | 72 ++ ...w_coverage_counters.various_conditions.txt | 240 +++++ .../expected_show_coverage_counters.while.txt | 22 + ...w_coverage_counters.while_early_return.txt | 44 + ...osure#0}.-------.InstrumentCoverage.0.html | 13 +- ...osure#1}.-------.InstrumentCoverage.0.html | 13 +- ...osure#2}.-------.InstrumentCoverage.0.html | 13 +- ...osure#3}.-------.InstrumentCoverage.0.html | 13 +- ...ait.main.-------.InstrumentCoverage.0.html | 2 +- ...ics.main.-------.InstrumentCoverage.0.html | 2 +- .../if.main.-------.InstrumentCoverage.0.html | 20 +- ...lse.main.-------.InstrumentCoverage.0.html | 30 +- ...-in_func.-------.InstrumentCoverage.0.html | 3 +- ...ait_func.-------.InstrumentCoverage.0.html | 3 +- ...ems.main.-------.InstrumentCoverage.0.html | 26 +- ...ean.main.-------.InstrumentCoverage.0.html | 143 ++- ...hes.main.-------.InstrumentCoverage.0.html | 151 ++++ ...l#0}-fmt.-------.InstrumentCoverage.0.html | 94 ++ ...ops.main.-------.InstrumentCoverage.0.html | 125 +++ ...ion.main.-------.InstrumentCoverage.0.html | 285 ++++++ ...l#0}-new.-------.InstrumentCoverage.0.html | 94 ++ ...l#1}-cmp.-------.InstrumentCoverage.0.html | 70 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-ge.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-gt.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-le.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-lt.-------.InstrumentCoverage.0.html | 82 ++ ...tial_cmp.-------.InstrumentCoverage.0.html | 72 ++ ...total_eq.-------.InstrumentCoverage.0.html | 65 ++ ...pl#6}-eq.-------.InstrumentCoverage.0.html | 67 ++ ...pl#6}-ne.-------.InstrumentCoverage.0.html | 71 ++ ...l#7}-fmt.-------.InstrumentCoverage.0.html | 99 ++ ...8}-clone.-------.InstrumentCoverage.0.html | 78 ++ ...oop.main.-------.InstrumentCoverage.0.html | 34 +- ...tch.main.-------.InstrumentCoverage.0.html | 62 +- ...oop.main.-------.InstrumentCoverage.0.html | 70 ++ ...ult.call.-------.InstrumentCoverage.0.html | 4 +- ...ult.main.-------.InstrumentCoverage.0.html | 62 +- ...ons.main.-------.InstrumentCoverage.0.html | 133 +-- ...ile.main.-------.InstrumentCoverage.0.html | 71 ++ ...urn.main.-------.InstrumentCoverage.0.html | 20 +- ...osure#0}.-------.InstrumentCoverage.0.html | 13 +- ...osure#1}.-------.InstrumentCoverage.0.html | 13 +- ...osure#2}.-------.InstrumentCoverage.0.html | 13 +- ...osure#3}.-------.InstrumentCoverage.0.html | 13 +- ...ait.main.-------.InstrumentCoverage.0.html | 2 +- ...ics.main.-------.InstrumentCoverage.0.html | 2 +- .../if.main.-------.InstrumentCoverage.0.html | 20 +- ...lse.main.-------.InstrumentCoverage.0.html | 30 +- ...-in_func.-------.InstrumentCoverage.0.html | 3 +- ...ait_func.-------.InstrumentCoverage.0.html | 3 +- ...ems.main.-------.InstrumentCoverage.0.html | 26 +- ...ean.main.-------.InstrumentCoverage.0.html | 143 ++- ...hes.main.-------.InstrumentCoverage.0.html | 151 ++++ ...l#0}-fmt.-------.InstrumentCoverage.0.html | 94 ++ ...ops.main.-------.InstrumentCoverage.0.html | 125 +++ ...ion.main.-------.InstrumentCoverage.0.html | 285 ++++++ ...l#0}-new.-------.InstrumentCoverage.0.html | 94 ++ ...l#1}-cmp.-------.InstrumentCoverage.0.html | 70 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-ge.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-gt.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-le.-------.InstrumentCoverage.0.html | 82 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 72 ++ ...osure#0}.-------.InstrumentCoverage.0.html | 73 ++ ...pl#2}-lt.-------.InstrumentCoverage.0.html | 82 ++ ...tial_cmp.-------.InstrumentCoverage.0.html | 72 ++ ...total_eq.-------.InstrumentCoverage.0.html | 65 ++ ...pl#6}-eq.-------.InstrumentCoverage.0.html | 67 ++ ...pl#6}-ne.-------.InstrumentCoverage.0.html | 71 ++ ...l#7}-fmt.-------.InstrumentCoverage.0.html | 99 ++ ...8}-clone.-------.InstrumentCoverage.0.html | 78 ++ ...oop.main.-------.InstrumentCoverage.0.html | 34 +- ...tch.main.-------.InstrumentCoverage.0.html | 62 +- ...oop.main.-------.InstrumentCoverage.0.html | 70 ++ ...ult.call.-------.InstrumentCoverage.0.html | 4 +- ...ult.main.-------.InstrumentCoverage.0.html | 62 +- ...ons.main.-------.InstrumentCoverage.0.html | 133 +-- ...ile.main.-------.InstrumentCoverage.0.html | 71 ++ ...urn.main.-------.InstrumentCoverage.0.html | 20 +- .../coverage/lazy_boolean.rs | 46 +- .../coverage/loops_and_branches.rs | 36 + .../coverage/nested_loops.rs | 25 + .../partial_eq_counter_without_region.rs | 99 ++ .../coverage/tight_infinite_loop.rs | 5 + src/test/run-make-fulldeps/coverage/while.rs | 5 + 214 files changed, 9821 insertions(+), 1243 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.partial_eq_counter_without_region.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.tight_infinite_loop.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.loops_and_branches.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.partial_eq_counter_without_region.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.tight_infinite_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.partial_eq_counter_without_region.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.tight_infinite_loop.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.loops_and_branches.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.partial_eq_counter_without_region.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.tight_infinite_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt create mode 100644 src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html create mode 100644 src/test/run-make-fulldeps/coverage/loops_and_branches.rs create mode 100644 src/test/run-make-fulldeps/coverage/nested_loops.rs create mode 100644 src/test/run-make-fulldeps/coverage/partial_eq_counter_without_region.rs create mode 100644 src/test/run-make-fulldeps/coverage/tight_infinite_loop.rs create mode 100644 src/test/run-make-fulldeps/coverage/while.rs diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index c1163a871cf1f..41827a91ba4be 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -129,7 +129,7 @@ impl CoverageMapGenerator { let (filenames_index, _) = self.filenames.insert_full(c_filename); virtual_file_mapping.push(filenames_index as u32); } - debug!("Adding counter {:?} to map for {:?}", counter, region,); + debug!("Adding counter {:?} to map for {:?}", counter, region); mapping_regions.push(CounterMappingRegion::code_region( counter, current_file_id, diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 7fdbe1a55128a..c4b4032fd478c 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -12,7 +12,7 @@ use rustc_codegen_ssa::traits::{ use rustc_data_structures::fx::FxHashMap; use rustc_llvm::RustString; use rustc_middle::mir::coverage::{ - CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionIndex, Op, + CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op, }; use rustc_middle::ty::Instance; @@ -27,8 +27,8 @@ const COVMAP_VAR_ALIGN_BYTES: usize = 8; /// A context object for maintaining all state needed by the coverageinfo module. pub struct CrateCoverageContext<'tcx> { - // Coverage region data for each instrumented function identified by DefId. - pub(crate) function_coverage_map: RefCell, FunctionCoverage>>, + // Coverage data for each instrumented function identified by DefId. + pub(crate) function_coverage_map: RefCell, FunctionCoverage<'tcx>>>, } impl<'tcx> CrateCoverageContext<'tcx> { @@ -36,7 +36,7 @@ impl<'tcx> CrateCoverageContext<'tcx> { Self { function_coverage_map: Default::default() } } - pub fn take_function_coverage_map(&self) -> FxHashMap, FunctionCoverage> { + pub fn take_function_coverage_map(&self) -> FxHashMap, FunctionCoverage<'tcx>> { self.function_coverage_map.replace(FxHashMap::default()) } } @@ -58,7 +58,23 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) } } - fn add_counter_region( + fn set_function_source_hash(&mut self, instance: Instance<'tcx>, function_source_hash: u64) -> bool { + if let Some(coverage_context) = self.coverage_context() { + debug!( + "ensuring function source hash is set for instance={:?}; function_source_hash={}", + instance, function_source_hash, + ); + let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); + coverage_map + .entry(instance) + .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) + .set_function_source_hash(function_source_hash); + } else { + false + } + } + + fn add_coverage_counter( &mut self, instance: Instance<'tcx>, function_source_hash: u64, @@ -67,59 +83,53 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { ) -> bool { if let Some(coverage_context) = self.coverage_context() { debug!( - "adding counter to coverage_regions: instance={:?}, function_source_hash={}, id={:?}, \ + "adding counter to coverage_map: instance={:?}, function_source_hash={}, id={:?}, \ at {:?}", instance, function_source_hash, id, region, ); - let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut(); - coverage_regions + let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); + coverage_map .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_counter(function_source_hash, id, region); - true } else { false } } - fn add_counter_expression_region( + fn add_coverage_counter_expression( &mut self, instance: Instance<'tcx>, - id: InjectedExpressionIndex, + id: InjectedExpressionId, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, - region: CodeRegion, - ) -> bool { - if let Some(coverage_context) = self.coverage_context() { + region: Option, + ) { + if let Some(coverage_context) = self.coverage_context() -> bool { debug!( - "adding counter expression to coverage_regions: instance={:?}, id={:?}, {:?} {:?} {:?}, \ - at {:?}", + "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; \ + region: {:?}", instance, id, lhs, op, rhs, region, ); - let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut(); - coverage_regions + let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); + coverage_map .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_counter_expression(id, lhs, op, rhs, region); - true } else { false } } - fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool { + fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool { if let Some(coverage_context) = self.coverage_context() { - debug!( - "adding unreachable code to coverage_regions: instance={:?}, at {:?}", - instance, region, - ); - let mut coverage_regions = coverage_context.function_coverage_map.borrow_mut(); - coverage_regions + debug!("adding unreachable code to coverage_map: instance={:?}, at {:?}", instance, region,); + let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); + coverage_map .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_unreachable_region(region); - true } else { false } diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs index a266d179a421b..bcac2c90fdc20 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/ffi.rs @@ -3,7 +3,7 @@ use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex}; /// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-05-05/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L91) #[derive(Copy, Clone, Debug)] #[repr(C)] -enum CounterKind { +pub enum CounterKind { Zero = 0, CounterValueReference = 1, Expression = 2, @@ -23,8 +23,8 @@ enum CounterKind { #[repr(C)] pub struct Counter { // Important: The layout (order and types of fields) must match its C++ counterpart. - kind: CounterKind, - id: u32, + pub kind: CounterKind, + pub id: u32, } impl Counter { @@ -55,9 +55,9 @@ pub enum ExprKind { #[derive(Copy, Clone, Debug)] #[repr(C)] pub struct CounterExpression { - kind: ExprKind, - lhs: Counter, - rhs: Counter, + pub kind: ExprKind, + pub lhs: Counter, + pub rhs: Counter, } impl CounterExpression { diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index d8bde8ee70533..006d6662196a0 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -2,18 +2,18 @@ pub use super::ffi::*; use rustc_index::vec::IndexVec; use rustc_middle::mir::coverage::{ - CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionIndex, - MappedExpressionIndex, Op, + CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, + InjectedExpressionIndex, MappedExpressionIndex, Op, }; use rustc_middle::ty::Instance; use rustc_middle::ty::TyCtxt; #[derive(Clone, Debug)] -pub struct ExpressionRegion { +pub struct Expression { lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, - region: CodeRegion, + region: Option, } /// Collects all of the coverage regions associated with (a) injected counters, (b) counter @@ -28,17 +28,23 @@ pub struct ExpressionRegion { /// only whitespace or comments). According to LLVM Code Coverage Mapping documentation, "A count /// for a gap area is only used as the line execution count if there are no other regions on a /// line." -pub struct FunctionCoverage { +pub struct FunctionCoverage<'tcx> { + instance: Instance<'tcx>, source_hash: u64, counters: IndexVec>, - expressions: IndexVec>, + expressions: IndexVec>, unreachable_regions: Vec, } -impl FunctionCoverage { - pub fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { +impl<'tcx> FunctionCoverage<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { let coverageinfo = tcx.coverageinfo(instance.def_id()); + debug!( + "FunctionCoverage::new(instance={:?}) has coverageinfo={:?}", + instance, coverageinfo + ); Self { + instance, source_hash: 0, // will be set with the first `add_counter()` counters: IndexVec::from_elem_n(None, coverageinfo.num_counters as usize), expressions: IndexVec::from_elem_n(None, coverageinfo.num_expressions as usize), @@ -46,6 +52,19 @@ impl FunctionCoverage { } } + /// Although every function should have at least one `Counter`, the `Counter` isn't required to + /// have a `CodeRegion`. (The `CodeRegion` may be associated only with `Expressions`.) This + /// method supports the ability to ensure the `function_source_hash` is set from `Counters` that + /// do not trigger the call to `add_counter()` because they don't have an associated + /// `CodeRegion` to add. + pub fn set_function_source_hash(&mut self, source_hash: u64) { + if self.source_hash == 0 { + self.source_hash = source_hash; + } else { + debug_assert_eq!(source_hash, self.source_hash); + } + } + /// Adds a code region to be counted by an injected counter intrinsic. /// The source_hash (computed during coverage instrumentation) should also be provided, and /// should be the same for all counters in a given function. @@ -74,15 +93,19 @@ impl FunctionCoverage { /// counters and expressions have been added. pub fn add_counter_expression( &mut self, - expression_id: InjectedExpressionIndex, + expression_id: InjectedExpressionId, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, - region: CodeRegion, + region: Option, ) { + debug!( + "add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}", + expression_id, lhs, op, rhs, region + ); let expression_index = self.expression_index(u32::from(expression_id)); self.expressions[expression_index] - .replace(ExpressionRegion { lhs, op, rhs, region }) + .replace(Expression { lhs, op, rhs, region }) .expect_none("add_counter_expression called with duplicate `id_descending_from_max`"); } @@ -103,7 +126,11 @@ impl FunctionCoverage { pub fn get_expressions_and_counter_regions<'a>( &'a self, ) -> (Vec, impl Iterator) { - assert!(self.source_hash != 0); + assert!( + self.source_hash != 0, + "No counters provided the source_hash for function: {:?}", + self.instance + ); let counter_regions = self.counter_regions(); let (counter_expressions, expression_regions) = self.expressions_with_regions(); @@ -129,54 +156,60 @@ impl FunctionCoverage { ) -> (Vec, impl Iterator) { let mut counter_expressions = Vec::with_capacity(self.expressions.len()); let mut expression_regions = Vec::with_capacity(self.expressions.len()); - let mut new_indexes = - IndexVec::from_elem_n(MappedExpressionIndex::from(u32::MAX), self.expressions.len()); - // Note, the initial value shouldn't matter since every index in use in `self.expressions` - // will be set, and after that, `new_indexes` will only be accessed using those same - // indexes. - - // Note that an `ExpressionRegion`s at any given index can include other expressions as + let mut new_indexes = IndexVec::from_elem_n(None, self.expressions.len()); + // Note that an `Expression`s at any given index can include other expressions as // operands, but expression operands can only come from the subset of expressions having - // `expression_index`s lower than the referencing `ExpressionRegion`. Therefore, it is + // `expression_index`s lower than the referencing `Expression`. Therefore, it is // reasonable to look up the new index of an expression operand while the `new_indexes` // vector is only complete up to the current `ExpressionIndex`. let id_to_counter = - |new_indexes: &IndexVec, + |new_indexes: &IndexVec>, id: ExpressionOperandId| { if id == ExpressionOperandId::ZERO { Some(Counter::zero()) } else if id.index() < self.counters.len() { + // Note: Some codegen-injected Counters may be only referenced by `Expression`s, + // and may not have their own `CodeRegion`s, let index = CounterValueReference::from(id.index()); - self.counters - .get(index) - .unwrap() // pre-validated - .as_ref() - .map(|_| Counter::counter_value_reference(index)) + Some(Counter::counter_value_reference(index)) } else { let index = self.expression_index(u32::from(id)); self.expressions .get(index) .expect("expression id is out of range") .as_ref() - .map(|_| Counter::expression(new_indexes[index])) + // If an expression was optimized out, assume it would have produced a count + // of zero. This ensures that expressions dependent on optimized-out + // expressions are still valid. + .map_or(Some(Counter::zero()), |_| { + new_indexes[index].map(|new_index| Counter::expression(new_index)) + }) } }; - for (original_index, expression_region) in + for (original_index, expression) in self.expressions.iter_enumerated().filter_map(|(original_index, entry)| { // Option::map() will return None to filter out missing expressions. This may happen // if, for example, a MIR-instrumented expression is removed during an optimization. - entry.as_ref().map(|region| (original_index, region)) + entry.as_ref().map(|expression| (original_index, expression)) }) { - let region = &expression_region.region; - let ExpressionRegion { lhs, op, rhs, .. } = *expression_region; + let optional_region = &expression.region; + let Expression { lhs, op, rhs, .. } = *expression; if let Some(Some((lhs_counter, rhs_counter))) = id_to_counter(&new_indexes, lhs).map(|lhs_counter| { id_to_counter(&new_indexes, rhs).map(|rhs_counter| (lhs_counter, rhs_counter)) }) { + debug_assert!( + (lhs_counter.id as usize) + < usize::max(self.counters.len(), self.expressions.len()) + ); + debug_assert!( + (rhs_counter.id as usize) + < usize::max(self.counters.len(), self.expressions.len()) + ); // Both operands exist. `Expression` operands exist in `self.expressions` and have // been assigned a `new_index`. let mapped_expression_index = @@ -190,12 +223,20 @@ impl FunctionCoverage { rhs_counter, ); debug!( - "Adding expression {:?} = {:?} at {:?}", - mapped_expression_index, expression, region + "Adding expression {:?} = {:?}, region: {:?}", + mapped_expression_index, expression, optional_region ); counter_expressions.push(expression); - new_indexes[original_index] = mapped_expression_index; - expression_regions.push((Counter::expression(mapped_expression_index), region)); + new_indexes[original_index] = Some(mapped_expression_index); + if let Some(region) = optional_region { + expression_regions.push((Counter::expression(mapped_expression_index), region)); + } + } else { + debug!( + "Ignoring expression with one or more missing operands: \ + original_index={:?}, lhs={:?}, op={:?}, rhs={:?}, region={:?}", + original_index, lhs, op, rhs, optional_region, + ) } } (counter_expressions, expression_regions.into_iter()) diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index 4811adea9ec06..e52f952e93278 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -10,7 +10,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Coverage { kind, code_region } = coverage; match kind { CoverageKind::Counter { function_source_hash, id } => { - if bx.add_counter_region(self.instance, function_source_hash, id, code_region) { + let covmap_updated = if let Some(code_region) = code_region { + // Note: Some counters do not have code regions, but may still be referenced from + // expressions. + bx.add_coverage_counter(self.instance, function_source_hash, id, code_region) + } else { + bx.set_function_source_hash(self.instance, function_source_hash) + }; + + if covmap_updated { let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id()); let fn_name = bx.create_pgo_func_name_var(self.instance); @@ -21,14 +29,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})", fn_name, hash, num_counters, id, ); - bx.instrprof_increment(fn_name, hash, num_counters, id); + bx.instrprof_increment(fn_name, hash, num_counters, index); } } CoverageKind::Expression { id, lhs, op, rhs } => { - bx.add_counter_expression_region(self.instance, id, lhs, op, rhs, code_region); + bx.add_coverage_counter_expression(self.instance, id, lhs, op, rhs, code_region); } CoverageKind::Unreachable => { - bx.add_unreachable_region(self.instance, code_region); + bx.add_coverage_unreachable( + self.instance, + code_region.expect("unreachable regions always have code regions"), + ); } } } diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index 3b1654f3ad4fc..5aa0950b399e3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -9,9 +9,13 @@ pub trait CoverageInfoMethods: BackendTypes { pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value; + /// Returns true if the function source hash was added to the coverage map; false if + /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). + fn set_function_source_hash(&mut self, instance: Instance<'tcx>, function_source_hash: u64) -> bool; + /// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage` /// is not enabled (a coverage map is not being generated). - fn add_counter_region( + fn add_coverage_counter( &mut self, instance: Instance<'tcx>, function_source_hash: u64, @@ -21,17 +25,17 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { /// Returns true if the expression was added to the coverage map; false if /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). - fn add_counter_expression_region( + fn add_coverage_counter_expression( &mut self, instance: Instance<'tcx>, - id: InjectedExpressionIndex, + id: InjectedExpressionId, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, - region: CodeRegion, - ) -> bool; + region: Option, + ); /// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage` /// is not enabled (a coverage map is not being generated). - fn add_unreachable_region(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool; + fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool; } diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 76e33bed97f27..e9ec11ba99714 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -643,6 +643,7 @@ where } if options.contains(&RenderOption::DarkTheme) { graph_attrs.push(r#"bgcolor="black""#); + graph_attrs.push(r#"fontcolor="white""#); content_attrs.push(r#"color="white""#); content_attrs.push(r#"fontcolor="white""#); } diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 0421eabc2dc05..ad0ba292d0241 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -7,6 +7,10 @@ use std::cmp::Ord; use std::fmt::{self, Debug, Formatter}; rustc_index::newtype_index! { + /// An ExpressionOperandId value is assigned directly from either a + /// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32() + /// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a + /// constant value of `0`. pub struct ExpressionOperandId { derive [HashStable] DEBUG_FORMAT = "ExpressionOperandId({})", @@ -42,6 +46,20 @@ impl CounterValueReference { } rustc_index::newtype_index! { + /// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32() + /// + /// Values descend from u32::MAX. + pub struct InjectedExpressionId { + derive [HashStable] + DEBUG_FORMAT = "InjectedExpressionId({})", + MAX = 0xFFFF_FFFF, + } +} + +rustc_index::newtype_index! { + /// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32() + /// + /// Values ascend from 0. pub struct InjectedExpressionIndex { derive [HashStable] DEBUG_FORMAT = "InjectedExpressionIndex({})", @@ -50,6 +68,9 @@ rustc_index::newtype_index! { } rustc_index::newtype_index! { + /// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their + /// array position in the LLVM coverage map "Expressions" array, which is assembled during the + /// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s. pub struct MappedExpressionIndex { derive [HashStable] DEBUG_FORMAT = "MappedExpressionIndex({})", @@ -64,21 +85,35 @@ impl From for ExpressionOperandId { } } -impl From for ExpressionOperandId { +impl From<&mut CounterValueReference> for ExpressionOperandId { #[inline] - fn from(v: InjectedExpressionIndex) -> ExpressionOperandId { + fn from(v: &mut CounterValueReference) -> ExpressionOperandId { ExpressionOperandId::from(v.as_u32()) } } -#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)] +impl From for ExpressionOperandId { + #[inline] + fn from(v: InjectedExpressionId) -> ExpressionOperandId { + ExpressionOperandId::from(v.as_u32()) + } +} + +impl From<&mut InjectedExpressionId> for ExpressionOperandId { + #[inline] + fn from(v: &mut InjectedExpressionId) -> ExpressionOperandId { + ExpressionOperandId::from(v.as_u32()) + } +} + +#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)] pub enum CoverageKind { Counter { function_source_hash: u64, id: CounterValueReference, }, Expression { - id: InjectedExpressionIndex, + id: InjectedExpressionId, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, @@ -88,12 +123,47 @@ pub enum CoverageKind { impl CoverageKind { pub fn as_operand_id(&self) -> ExpressionOperandId { + use CoverageKind::*; match *self { - CoverageKind::Counter { id, .. } => ExpressionOperandId::from(id), - CoverageKind::Expression { id, .. } => ExpressionOperandId::from(id), - CoverageKind::Unreachable => { - bug!("Unreachable coverage cannot be part of an expression") - } + Counter { id, .. } => ExpressionOperandId::from(id), + Expression { id, .. } => ExpressionOperandId::from(id), + Unreachable => bug!("Unreachable coverage cannot be part of an expression"), + } + } + + pub fn is_counter(&self) -> bool { + match self { + Self::Counter { .. } => true, + _ => false, + } + } + + pub fn is_expression(&self) -> bool { + match self { + Self::Expression { .. } => true, + _ => false, + } + } + + pub fn is_unreachable(&self) -> bool { + *self == Self::Unreachable + } +} + +impl Debug for CoverageKind { + fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { + use CoverageKind::*; + match self { + Counter { id, .. } => write!(fmt, "Counter({:?})", id.index()), + Expression { id, lhs, op, rhs } => write!( + fmt, + "Expression({:?}) = {} {} {}", + id.index(), + lhs.index(), + if *op == Op::Add { "+" } else { "-" }, + rhs.index(), + ), + Unreachable => write!(fmt, "Unreachable"), } } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b6b6c968501a3..6d59a669ea7e0 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1586,21 +1586,10 @@ impl Debug for Statement<'_> { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } Coverage(box ref coverage) => { - let rgn = &coverage.code_region; - match coverage.kind { - CoverageKind::Counter { id, .. } => { - write!(fmt, "Coverage::Counter({:?}) for {:?}", id.index(), rgn) - } - CoverageKind::Expression { id, lhs, op, rhs } => write!( - fmt, - "Coverage::Expression({:?}) = {} {} {} for {:?}", - id.index(), - lhs.index(), - if op == coverage::Op::Add { "+" } else { "-" }, - rhs.index(), - rgn - ), - CoverageKind::Unreachable => write!(fmt, "Coverage::Unreachable for {:?}", rgn), + if let Some(rgn) = &coverage.code_region { + write!(fmt, "Coverage::{:?} for {:?}", coverage.kind, rgn) + } else { + write!(fmt, "Coverage::{:?}", coverage.kind) } } Nop => write!(fmt, "nop"), @@ -1611,7 +1600,7 @@ impl Debug for Statement<'_> { #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)] pub struct Coverage { pub kind: CoverageKind, - pub code_region: CodeRegion, + pub code_region: Option, } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 431225e276751..89fd803fe5140 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -300,6 +300,7 @@ CloneTypeFoldableAndLiftImpls! { ::rustc_target::spec::abi::Abi, crate::mir::coverage::ExpressionOperandId, crate::mir::coverage::CounterValueReference, + crate::mir::coverage::InjectedExpressionId, crate::mir::coverage::InjectedExpressionIndex, crate::mir::coverage::MappedExpressionIndex, crate::mir::Local, diff --git a/compiler/rustc_mir/src/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/instrument_coverage.rs index 6824c73ab60a0..cb6798f2ee75e 100644 --- a/compiler/rustc_mir/src/transform/instrument_coverage.rs +++ b/compiler/rustc_mir/src/transform/instrument_coverage.rs @@ -1,9 +1,10 @@ use crate::transform::MirPass; use crate::util::pretty; -use crate::util::spanview::{self, SpanViewable}; +use crate::util::spanview::{self, source_range_no_file, SpanViewable}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::graph::dominators::Dominators; +use rustc_data_structures::graph::WithNumNodes; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::BitSet; @@ -16,7 +17,7 @@ use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{ AggregateKind, BasicBlock, BasicBlockData, Coverage, CoverageInfo, FakeReadCause, Location, - Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, + Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; @@ -28,11 +29,6 @@ use std::cmp::Ordering; const ID_SEPARATOR: &str = ","; -/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected -/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen -/// to construct the coverage map. -pub struct InstrumentCoverage; - /// The `query` provider for `CoverageInfo`, requested by `codegen_coverage()` (to inject each /// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR). pub(crate) fn provide(providers: &mut Providers) { @@ -54,23 +50,72 @@ pub(crate) fn provide(providers: &mut Providers) { /// are still included in the total `num_counters` or `num_expressions`.) Simply counting the /// calls may not work; but computing the number of counters or expressions by adding `1` to the /// highest ID (for a given instrumented function) is valid. +/// +/// This visitor runs twice, first with `add_missing_operands` set to `false`, to find the maximum +/// counter ID and maximum expression ID based on their enum variant `id` fields; then, as a +/// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression +/// IDs referenced by expression operands, if not already seen. +/// +/// Ideally, every expression operand in the MIR will have a corresponding Counter or Expression, +/// but since current or future MIR optimizations can theoretically optimize out segments of a +/// MIR, it may not be possible to guarantee this, so the second pass ensures the `CoverageInfo` +/// counts include all referenced IDs. struct CoverageVisitor { info: CoverageInfo, + add_missing_operands: bool, +} + +impl CoverageVisitor { + // If an expression operand is encountered with an ID outside the range of known counters and + // expressions, the only way to determine if the ID is a counter ID or an expression ID is to + // assume a maximum possible counter ID value. + const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; + + #[inline(always)] + fn update_num_counters(&mut self, counter_id: u32) { + self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); + } + + #[inline(always)] + fn update_num_expressions(&mut self, expression_id: u32) { + let expression_index = u32::MAX - expression_id; + self.info.num_expressions = std::cmp::max(self.info.num_expressions, expression_index + 1); + } + + fn update_from_expression_operand(&mut self, operand_id: u32) { + if operand_id >= self.info.num_counters { + let operand_as_expression_index = u32::MAX - operand_id; + if operand_as_expression_index >= self.info.num_expressions { + if operand_id <= Self::MAX_COUNTER_GUARD { + self.update_num_counters(operand_id) + } else { + self.update_num_expressions(operand_id) + } + } + } + } } impl Visitor<'_> for CoverageVisitor { fn visit_coverage(&mut self, coverage: &Coverage, _location: Location) { - match coverage.kind { - CoverageKind::Counter { id, .. } => { - let counter_id = u32::from(id); - self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); + if self.add_missing_operands { + match coverage.kind { + CoverageKind::Expression { lhs, rhs, .. } => { + self.update_from_expression_operand(u32::from(lhs)); + self.update_from_expression_operand(u32::from(rhs)); + } + _ => {} } - CoverageKind::Expression { id, .. } => { - let expression_index = u32::MAX - u32::from(id); - self.info.num_expressions = - std::cmp::max(self.info.num_expressions, expression_index + 1); + } else { + match coverage.kind { + CoverageKind::Counter { id, .. } => { + self.update_num_counters(u32::from(id)); + } + CoverageKind::Expression { id, .. } => { + self.update_num_expressions(u32::from(id)); + } + _ => {} } - _ => {} } } } @@ -78,45 +123,58 @@ impl Visitor<'_> for CoverageVisitor { fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo { let mir_body = tcx.optimized_mir(def_id); - let mut coverage_visitor = - CoverageVisitor { info: CoverageInfo { num_counters: 0, num_expressions: 0 } }; + let mut coverage_visitor = CoverageVisitor { + info: CoverageInfo { num_counters: 0, num_expressions: 0 }, + add_missing_operands: false, + }; coverage_visitor.visit_body(mir_body); + + coverage_visitor.add_missing_operands = true; + coverage_visitor.visit_body(mir_body); + coverage_visitor.info } +/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected +/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen +/// to construct the coverage map. +pub struct InstrumentCoverage; impl<'tcx> MirPass<'tcx> for InstrumentCoverage { fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) { + let mir_source = mir_body.source; + // If the InstrumentCoverage pass is called on promoted MIRs, skip them. // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 - if mir_body.source.promoted.is_some() { + if mir_source.promoted.is_some() { trace!( "InstrumentCoverage skipped for {:?} (already promoted for Miri evaluation)", - mir_body.source.def_id() + mir_source.def_id() ); return; } - let hir_id = tcx.hir().local_def_id_to_hir_id(mir_body.source.def_id().expect_local()); + let hir_id = tcx.hir().local_def_id_to_hir_id(mir_source.def_id().expect_local()); let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some(); // Only instrument functions, methods, and closures (not constants since they are evaluated // at compile time by Miri). - // FIXME(#73156): Handle source code coverage in const eval + // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const + // expressions get coverage spans, we will probably have to "carve out" space for const + // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might + // be tricky if const expressions have no corresponding statements in the enclosing MIR. + // Closures are carved out by their initial `Assign` statement.) if !is_fn_like { - trace!( - "InstrumentCoverage skipped for {:?} (not an FnLikeNode)", - mir_body.source.def_id(), - ); + trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id()); return; } // FIXME(richkadel): By comparison, the MIR pass `ConstProp` includes associated constants, // with functions, methods, and closures. I assume Miri is used for associated constants as // well. If not, we may need to include them here too. - trace!("InstrumentCoverage starting for {:?}", mir_body.source.def_id()); + trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); Instrumentor::new(&self.name(), tcx, mir_body).inject_counters(); - trace!("InstrumentCoverage starting for {:?}", mir_body.source.def_id()); + trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); } } @@ -184,12 +242,16 @@ impl BasicCoverageBlocks { } pub fn iter(&self) -> impl Iterator { - self.vec.iter().filter_map(|option| option.as_ref()) + self.vec.iter().filter_map(|bcb| bcb.as_ref()) + } + + pub fn num_nodes(&self) -> usize { + self.vec.len() } - fn extract_from_mir(&mut self, mir_body: &mir::Body<'tcx>) { + pub fn extract_from_mir(&mut self, mir_body: &mir::Body<'tcx>) { // Traverse the CFG but ignore anything following an `unwind` - let cfg_without_unwind = ShortCircuitPreorder::new(mir_body, |term_kind| { + let cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, |term_kind| { let mut successors = term_kind.successors(); match &term_kind { // SwitchInt successors are never unwind, and all of them should be traversed. @@ -337,20 +399,20 @@ impl CoverageStatement { pub fn format(&self, tcx: TyCtxt<'tcx>, mir_body: &'a mir::Body<'tcx>) -> String { match *self { Self::Statement(bb, span, stmt_index) => { - let stmt = &mir_body.basic_blocks()[bb].statements[stmt_index]; + let stmt = &mir_body[bb].statements[stmt_index]; format!( "{}: @{}[{}]: {:?}", - spanview::source_range_no_file(tcx, &span), + source_range_no_file(tcx, &span), bb.index(), stmt_index, stmt ) } Self::Terminator(bb, span) => { - let term = mir_body.basic_blocks()[bb].terminator(); + let term = mir_body[bb].terminator(); format!( "{}: @{}.{}: {:?}", - spanview::source_range_no_file(tcx, &span), + source_range_no_file(tcx, &span), bb.index(), term_type(&term.kind), term.kind @@ -366,6 +428,8 @@ impl CoverageStatement { } } +/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any +/// values it might hold. fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { match kind { TerminatorKind::Goto { .. } => "Goto", @@ -398,10 +462,10 @@ fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { /// `is_dominated_by()` the `BasicBlock`s in this `CoverageSpan`. #[derive(Debug, Clone)] struct CoverageSpan { - span: Span, - bcb_leader_bb: BasicBlock, - coverage_statements: Vec, - is_closure: bool, + pub span: Span, + pub bcb_leader_bb: BasicBlock, + pub coverage_statements: Vec, + pub is_closure: bool, } impl CoverageSpan { @@ -428,7 +492,7 @@ impl CoverageSpan { } } - pub fn for_terminator(span: Span, bcb: &'a BasicCoverageBlock, bb: BasicBlock) -> Self { + pub fn for_terminator(span: Span, bcb: &BasicCoverageBlock, bb: BasicBlock) -> Self { Self { span, bcb_leader_bb: bcb.leader_bb(), @@ -455,132 +519,119 @@ impl CoverageSpan { } } - pub fn is_dominated_by( - &self, - other: &CoverageSpan, - dominators: &Dominators, - ) -> bool { - debug_assert!(!self.is_in_same_bcb(other)); - dominators.is_dominated_by(self.bcb_leader_bb, other.bcb_leader_bb) - } - + #[inline] pub fn is_mergeable(&self, other: &Self) -> bool { self.is_in_same_bcb(other) && !(self.is_closure || other.is_closure) } + #[inline] pub fn is_in_same_bcb(&self, other: &Self) -> bool { self.bcb_leader_bb == other.bcb_leader_bb } + + pub fn format_coverage_statements( + &self, + tcx: TyCtxt<'tcx>, + mir_body: &'a mir::Body<'tcx>, + ) -> String { + let mut sorted_coverage_statements = self.coverage_statements.clone(); + sorted_coverage_statements.sort_unstable_by_key(|covstmt| match *covstmt { + CoverageStatement::Statement(bb, _, index) => (bb, index), + CoverageStatement::Terminator(bb, _) => (bb, usize::MAX), + }); + sorted_coverage_statements + .iter() + .map(|covstmt| covstmt.format(tcx, mir_body)) + .collect::>() + .join("\n") + } } struct Instrumentor<'a, 'tcx> { pass_name: &'a str, tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>, - hir_body: &'tcx rustc_hir::Body<'tcx>, - dominators: Option>, - basic_coverage_blocks: Option, - function_source_hash: Option, - next_counter_id: u32, - num_expressions: u32, + body_span: Span, + basic_coverage_blocks: BasicCoverageBlocks, + coverage_counters: CoverageCounters, } impl<'a, 'tcx> Instrumentor<'a, 'tcx> { fn new(pass_name: &'a str, tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self { let hir_body = hir_body(tcx, mir_body.source.def_id()); + let body_span = hir_body.value.span; + let function_source_hash = hash_mir_source(tcx, hir_body); + let basic_coverage_blocks = BasicCoverageBlocks::from_mir(mir_body); Self { pass_name, tcx, mir_body, - hir_body, - dominators: None, - basic_coverage_blocks: None, - function_source_hash: None, - next_counter_id: CounterValueReference::START.as_u32(), - num_expressions: 0, + body_span, + basic_coverage_blocks, + coverage_counters: CoverageCounters::new(function_source_hash), } } - /// Counter IDs start from one and go up. - fn next_counter(&mut self) -> CounterValueReference { - assert!(self.next_counter_id < u32::MAX - self.num_expressions); - let next = self.next_counter_id; - self.next_counter_id += 1; - CounterValueReference::from(next) - } - - /// Expression IDs start from u32::MAX and go down because a CounterExpression can reference - /// (add or subtract counts) of both Counter regions and CounterExpression regions. The counter - /// expression operand IDs must be unique across both types. - fn next_expression(&mut self) -> InjectedExpressionIndex { - assert!(self.next_counter_id < u32::MAX - self.num_expressions); - let next = u32::MAX - self.num_expressions; - self.num_expressions += 1; - InjectedExpressionIndex::from(next) - } + fn inject_counters(&'a mut self) { + let tcx = self.tcx; + let source_map = tcx.sess.source_map(); + let mir_source = self.mir_body.source; + let def_id = mir_source.def_id(); + let body_span = self.body_span; - fn dominators(&self) -> &Dominators { - self.dominators.as_ref().expect("dominators must be initialized before calling") - } + debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); - fn basic_coverage_blocks(&self) -> &BasicCoverageBlocks { - self.basic_coverage_blocks - .as_ref() - .expect("basic_coverage_blocks must be initialized before calling") - } + //////////////////////////////////////////////////// + // Compute `CoverageSpan`s from the `BasicCoverageBlocks`. + let coverage_spans = CoverageSpans::generate_coverage_spans( + &self.mir_body, + body_span, + &self.basic_coverage_blocks, + ); - fn function_source_hash(&mut self) -> u64 { - match self.function_source_hash { - Some(hash) => hash, - None => { - let hash = hash_mir_source(self.tcx, self.hir_body); - self.function_source_hash.replace(hash); - hash - } + if pretty::dump_enabled(tcx, self.pass_name, def_id) { + dump_coverage_spanview( + tcx, + self.mir_body, + &self.basic_coverage_blocks, + self.pass_name, + &coverage_spans, + ); } + + self.inject_coverage_span_counters(coverage_spans); } - fn inject_counters(&mut self) { + /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given + /// BCB, but only one actual counter needs to be incremented per BCB. `bcb_counters` maps each + /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has + /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to + /// the BCB `Counter` value. + fn inject_coverage_span_counters(&mut self, coverage_spans: Vec) { let tcx = self.tcx; let source_map = tcx.sess.source_map(); - let def_id = self.mir_body.source.def_id(); - let mir_body = &self.mir_body; - let body_span = self.body_span(); + let body_span = self.body_span; let source_file = source_map.lookup_source_file(body_span.lo()); let file_name = Symbol::intern(&source_file.name.to_string()); - debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); - - self.dominators.replace(mir_body.dominators()); - self.basic_coverage_blocks.replace(BasicCoverageBlocks::from_mir(mir_body)); - - let coverage_spans = self.coverage_spans(); - - let span_viewables = if pretty::dump_enabled(tcx, self.pass_name, def_id) { - Some(self.span_viewables(&coverage_spans)) - } else { - None - }; - - // Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a - // given BCB, but only one actual counter needs to be incremented per BCB. `bb_counters` - // maps each `bcb_leader_bb` to its `Counter`, when injected. Subsequent `CoverageSpan`s - // for a BCB that already has a `Counter` will inject a `CounterExpression` instead, and - // compute its value by adding `ZERO` to the BCB `Counter` value. - let mut bb_counters = IndexVec::from_elem_n(None, mir_body.basic_blocks().len()); + let mut bb_counters = IndexVec::from_elem_n(None, self.mir_body.basic_blocks().len()); for CoverageSpan { span, bcb_leader_bb: bb, .. } in coverage_spans { if let Some(&counter_operand) = bb_counters[bb].as_ref() { - let expression = - self.make_expression(counter_operand, Op::Add, ExpressionOperandId::ZERO); + let expression = self.coverage_counters.make_expression( + counter_operand, + Op::Add, + ExpressionOperandId::ZERO, + ); debug!( "Injecting counter expression {:?} at: {:?}:\n{}\n==========", expression, span, source_map.span_to_snippet(span).expect("Error getting source for span"), ); - self.inject_statement(file_name, &source_file, expression, span, bb); + let code_region = make_code_region(file_name, &source_file, span, body_span); + inject_statement(self.mir_body, expression, bb, Some(code_region)); } else { - let counter = self.make_counter(); + let counter = self.coverage_counters.make_counter(); debug!( "Injecting counter {:?} at: {:?}:\n{}\n==========", counter, @@ -589,126 +640,212 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { ); let counter_operand = counter.as_operand_id(); bb_counters[bb] = Some(counter_operand); - self.inject_statement(file_name, &source_file, counter, span, bb); + let code_region = make_code_region(file_name, &source_file, span, body_span); + inject_statement(self.mir_body, counter, bb, Some(code_region)); } } + } +} - if let Some(span_viewables) = span_viewables { - let mut file = pretty::create_dump_file( - tcx, - "html", - None, - self.pass_name, - &0, - self.mir_body.source, - ) - .expect("Unexpected error creating MIR spanview HTML file"); - let crate_name = tcx.crate_name(def_id.krate); - let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate(); - let title = format!("{}.{} - Coverage Spans", crate_name, item_name); - spanview::write_document(tcx, def_id, span_viewables, &title, &mut file) - .expect("Unexpected IO error dumping coverage spans as HTML"); +/// Generates the MIR pass `CoverageSpan`-specific spanview dump file. +fn dump_coverage_spanview( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + basic_coverage_blocks: &BasicCoverageBlocks, + pass_name: &str, + coverage_spans: &Vec, +) { + let mir_source = mir_body.source; + let def_id = mir_source.def_id(); + + let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans); + let mut file = pretty::create_dump_file(tcx, "html", None, pass_name, &0, mir_source) + .expect("Unexpected error creating MIR spanview HTML file"); + let crate_name = tcx.crate_name(def_id.krate); + let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate(); + let title = format!("{}.{} - Coverage Spans", crate_name, item_name); + spanview::write_document(tcx, def_id, span_viewables, &title, &mut file) + .expect("Unexpected IO error dumping coverage spans as HTML"); +} + +/// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s. +fn span_viewables( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + basic_coverage_blocks: &BasicCoverageBlocks, + coverage_spans: &Vec, +) -> Vec { + let mut span_viewables = Vec::new(); + for coverage_span in coverage_spans { + let tooltip = coverage_span.format_coverage_statements(tcx, mir_body); + let CoverageSpan { span, bcb_leader_bb: bb, .. } = coverage_span; + let bcb = &basic_coverage_blocks[*bb]; + let id = bcb.id(); + let leader_bb = bcb.leader_bb(); + span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip }); + } + span_viewables +} + +/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR +/// `Coverage` statements. +struct CoverageCounters { + function_source_hash: u64, + next_counter_id: u32, + num_expressions: u32, +} + +impl CoverageCounters { + pub fn new(function_source_hash: u64) -> Self { + Self { + function_source_hash, + next_counter_id: CounterValueReference::START.as_u32(), + num_expressions: 0, } } - fn make_counter(&mut self) -> CoverageKind { + pub fn make_counter(&mut self) -> CoverageKind { CoverageKind::Counter { - function_source_hash: self.function_source_hash(), + function_source_hash: self.function_source_hash, id: self.next_counter(), } } - fn make_expression( + pub fn make_expression( &mut self, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, ) -> CoverageKind { - CoverageKind::Expression { id: self.next_expression(), lhs, op, rhs } + let id = self.next_expression(); + CoverageKind::Expression { id, lhs, op, rhs } } - fn inject_statement( - &mut self, - file_name: Symbol, - source_file: &Lrc, - coverage_kind: CoverageKind, - span: Span, - block: BasicBlock, - ) { - let code_region = make_code_region(file_name, source_file, span); - debug!(" injecting statement {:?} covering {:?}", coverage_kind, code_region); - - let data = &mut self.mir_body[block]; - let source_info = data.terminator().source_info; - let statement = Statement { - source_info, - kind: StatementKind::Coverage(box Coverage { kind: coverage_kind, code_region }), - }; - data.statements.push(statement); + /// Counter IDs start from one and go up. + fn next_counter(&mut self) -> CounterValueReference { + assert!(self.next_counter_id < u32::MAX - self.num_expressions); + let next = self.next_counter_id; + self.next_counter_id += 1; + CounterValueReference::from(next) } - /// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s. - fn span_viewables(&self, coverage_spans: &Vec) -> Vec { - let tcx = self.tcx; - let mir_body = &self.mir_body; - let mut span_viewables = Vec::new(); - for coverage_span in coverage_spans { - let bcb = self.bcb_from_coverage_span(coverage_span); - let CoverageSpan { span, bcb_leader_bb: bb, coverage_statements, .. } = coverage_span; - let id = bcb.id(); - let mut sorted_coverage_statements = coverage_statements.clone(); - sorted_coverage_statements.sort_unstable_by_key(|covstmt| match *covstmt { - CoverageStatement::Statement(bb, _, index) => (bb, index), - CoverageStatement::Terminator(bb, _) => (bb, usize::MAX), - }); - let tooltip = sorted_coverage_statements - .iter() - .map(|covstmt| covstmt.format(tcx, mir_body)) - .collect::>() - .join("\n"); - span_viewables.push(SpanViewable { bb: *bb, span: *span, id, tooltip }); - } - span_viewables + /// Expression IDs start from u32::MAX and go down because a Expression can reference + /// (add or subtract counts) of both Counter regions and Expression regions. The counter + /// expression operand IDs must be unique across both types. + fn next_expression(&mut self) -> InjectedExpressionId { + assert!(self.next_counter_id < u32::MAX - self.num_expressions); + let next = u32::MAX - self.num_expressions; + self.num_expressions += 1; + InjectedExpressionId::from(next) } +} +fn inject_statement( + mir_body: &mut mir::Body<'tcx>, + counter_kind: CoverageKind, + bb: BasicBlock, + some_code_region: Option, +) { + debug!( + " injecting statement {:?} for {:?} at code region: {:?}", + counter_kind, bb, some_code_region + ); + let data = &mut mir_body[bb]; + let source_info = data.terminator().source_info; + let statement = Statement { + source_info, + kind: StatementKind::Coverage(box Coverage { + kind: counter_kind, + code_region: some_code_region, + }), + }; + data.statements.push(statement); +} - #[inline(always)] - fn bcb_from_coverage_span(&self, coverage_span: &CoverageSpan) -> &BasicCoverageBlock { - &self.basic_coverage_blocks()[coverage_span.bcb_leader_bb] - } +/// Converts the initial set of `CoverageSpan`s (one per MIR `Statement` or `Terminator`) into a +/// minimal set of `CoverageSpan`s, using the BCB CFG to determine where it is safe and useful to: +/// +/// * Remove duplicate source code coverage regions +/// * Merge spans that represent continuous (both in source code and control flow), non-branching +/// execution +/// * Carve out (leave uncovered) any span that will be counted by another MIR (notably, closures) +pub struct CoverageSpans<'a, 'tcx> { + /// The MIR, used to look up `BasicBlockData`. + mir_body: &'a mir::Body<'tcx>, + + /// A snapshot of the MIR CFG dominators before injecting any coverage statements. + dominators: Dominators, + + /// A `Span` covering the function body of the MIR (typically from left curly brace to right + /// curly brace). + body_span: Span, + + /// The BasicCoverageBlock Control Flow Graph (BCB CFG). + basic_coverage_blocks: &'a BasicCoverageBlocks, + + /// The initial set of `CoverageSpan`s, sorted by `Span` (`lo` and `hi`) and by relative + /// dominance between the `BasicCoverageBlock`s of equal `Span`s. + sorted_spans_iter: Option>, + + /// The current `CoverageSpan` to compare to its `prev`, to possibly merge, discard, force the + /// discard of the `prev` (and or `pending_dups`), or keep both (with `prev` moved to + /// `pending_dups`). If `curr` is not discarded or merged, it becomes `prev` for the next + /// iteration. + some_curr: Option, - #[inline(always)] - fn body_span(&self) -> Span { - self.hir_body.value.span - } + /// The original `span` for `curr`, in case the `curr` span is modified. + curr_original_span: Span, - // Generate a set of `CoverageSpan`s from the filtered set of `Statement`s and `Terminator`s of - // the `BasicBlock`(s) in the given `BasicCoverageBlock`. One `CoverageSpan` is generated for - // each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will - // merge some `CoverageSpan`s, at which point a `CoverageSpan` may represent multiple - // `Statement`s and/or `Terminator`s.) - fn extract_spans(&self, bcb: &'a BasicCoverageBlock) -> Vec { - let body_span = self.body_span(); - let mir_basic_blocks = self.mir_body.basic_blocks(); - bcb.blocks - .iter() - .map(|bbref| { - let bb = *bbref; - let data = &mir_basic_blocks[bb]; - data.statements - .iter() - .enumerate() - .filter_map(move |(index, statement)| { - filtered_statement_span(statement, body_span).map(|span| { - CoverageSpan::for_statement(statement, span, bcb, bb, index) - }) - }) - .chain( - filtered_terminator_span(data.terminator(), body_span) - .map(|span| CoverageSpan::for_terminator(span, bcb, bb)), - ) - }) - .flatten() - .collect() + /// The CoverageSpan from a prior iteration; typically assigned from that iteration's `curr`. + /// If that `curr` was discarded, `prev` retains its value from the previous iteration. + some_prev: Option, + + /// Assigned from `curr_original_span` from the previous iteration. + prev_original_span: Span, + + /// One or more `CoverageSpan`s with the same `Span` but different `BasicCoverageBlock`s, and + /// no `BasicCoverageBlock` in this list dominates another `BasicCoverageBlock` in the list. + /// If a new `curr` span also fits this criteria (compared to an existing list of + /// `pending_dups`), that `curr` `CoverageSpan` moves to `prev` before possibly being added to + /// the `pending_dups` list, on the next iteration. As a result, if `prev` and `pending_dups` + /// have the same `Span`, the criteria for `pending_dups` holds for `prev` as well: a `prev` + /// with a matching `Span` does not dominate any `pending_dup` and no `pending_dup` dominates a + /// `prev` with a matching `Span`) + pending_dups: Vec, + + /// The final `CoverageSpan`s to add to the coverage map. A `Counter` or `Expression` + /// will also be injected into the MIR for each `CoverageSpan`. + refined_spans: Vec, +} + +impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { + fn generate_coverage_spans( + mir_body: &'a mir::Body<'tcx>, + body_span: Span, + basic_coverage_blocks: &'a BasicCoverageBlocks, + ) -> Vec { + let dominators = mir_body.dominators(); + let mut coverage_spans = CoverageSpans { + mir_body, + dominators, + body_span, + basic_coverage_blocks, + sorted_spans_iter: None, + refined_spans: Vec::with_capacity(basic_coverage_blocks.num_nodes() * 2), + some_curr: None, + curr_original_span: Span::with_root_ctxt(BytePos(0), BytePos(0)), + some_prev: None, + prev_original_span: Span::with_root_ctxt(BytePos(0), BytePos(0)), + pending_dups: Vec::new(), + }; + + let sorted_spans = coverage_spans.mir_to_initial_sorted_coverage_spans(); + + coverage_spans.sorted_spans_iter = Some(sorted_spans.into_iter()); + coverage_spans.some_prev = coverage_spans.sorted_spans_iter.as_mut().unwrap().next(); + coverage_spans.prev_original_span = + coverage_spans.some_prev.as_ref().expect("at least one span").span; + + coverage_spans.to_refined_spans() } /// Generate a minimal set of `CoverageSpan`s, each representing a contiguous code region to be @@ -732,11 +869,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { /// /// Note the resulting vector of `CoverageSpan`s does may not be fully sorted (and does not need /// to be). - fn coverage_spans(&self) -> Vec { - let mut initial_spans = - Vec::::with_capacity(self.mir_body.basic_blocks().len() * 2); - for bcb in self.basic_coverage_blocks().iter() { - for coverage_span in self.extract_spans(bcb) { + fn mir_to_initial_sorted_coverage_spans(&self) -> Vec { + let mut initial_spans = Vec::::with_capacity(self.mir_body.num_nodes() * 2); + for bcb in self.basic_coverage_blocks.iter() { + for coverage_span in self.bcb_to_initial_coverage_spans(bcb) { initial_spans.push(coverage_span); } } @@ -757,14 +893,14 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { // dominators always come after the dominated equal spans). When later // comparing two spans in order, the first will either dominate the second, // or they will have no dominator relationship. - self.dominators().rank_partial_cmp(b.bcb_leader_bb, a.bcb_leader_bb) + self.dominators.rank_partial_cmp(b.bcb_leader_bb, a.bcb_leader_bb) } } else { // Sort hi() in reverse order so shorter spans are attempted after longer spans. - // This guarantees that, if a `prev` span overlaps, and is not equal to, a `curr` - // span, the prev span either extends further left of the curr span, or they - // start at the same position and the prev span extends further right of the end - // of the curr span. + // This guarantees that, if a `prev` span overlaps, and is not equal to, a + // `curr` span, the prev span either extends further left of the curr span, or + // they start at the same position and the prev span extends further right of + // the end of the curr span. b.span.hi().partial_cmp(&a.span.hi()) } } else { @@ -773,41 +909,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { .unwrap() }); - let refinery = CoverageSpanRefinery::from_sorted_spans(initial_spans, self.dominators()); - refinery.to_refined_spans() - } -} - -struct CoverageSpanRefinery<'a> { - sorted_spans_iter: std::vec::IntoIter, - dominators: &'a Dominators, - some_curr: Option, - curr_original_span: Span, - some_prev: Option, - prev_original_span: Span, - pending_dups: Vec, - refined_spans: Vec, -} - -impl<'a> CoverageSpanRefinery<'a> { - fn from_sorted_spans( - sorted_spans: Vec, - dominators: &'a Dominators, - ) -> Self { - let refined_spans = Vec::with_capacity(sorted_spans.len()); - let mut sorted_spans_iter = sorted_spans.into_iter(); - let prev = sorted_spans_iter.next().expect("at least one span"); - let prev_original_span = prev.span; - Self { - sorted_spans_iter, - dominators, - refined_spans, - some_curr: None, - curr_original_span: Span::with_root_ctxt(BytePos(0), BytePos(0)), - some_prev: Some(prev), - prev_original_span, - pending_dups: Vec::new(), - } + initial_spans } /// Iterate through the sorted `CoverageSpan`s, and return the refined list of merged and @@ -826,7 +928,7 @@ impl<'a> CoverageSpanRefinery<'a> { self.prev() ); let prev = self.take_prev(); - self.add_refined_span(prev); + self.refined_spans.push(prev); } else if self.prev().is_closure { // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the // next iter @@ -839,38 +941,72 @@ impl<'a> CoverageSpanRefinery<'a> { } else if self.curr().is_closure { self.carve_out_span_for_closure(); } else if self.prev_original_span == self.curr().span { + // Note that this compares the new span to `prev_original_span`, which may not + // be the full `prev.span` (if merged during the previous iteration). self.hold_pending_dups_unless_dominated(); } else { self.cutoff_prev_at_overlapping_curr(); } } + debug!(" AT END, adding last prev={:?}", self.prev()); - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups.into_iter() { + let prev = self.take_prev(); + let CoverageSpans { + mir_body, basic_coverage_blocks, pending_dups, mut refined_spans, .. + } = self; + for dup in pending_dups { debug!(" ...adding at least one pending dup={:?}", dup); - self.add_refined_span(dup); + refined_spans.push(dup); } - let prev = self.take_prev(); - self.add_refined_span(prev); - - // FIXME(richkadel): Replace some counters with expressions if they can be calculated based - // on branching. (For example, one branch of a SwitchInt can be computed from the counter - // for the CoverageSpan just prior to the SwitchInt minus the sum of the counters of all - // other branches). - - self.to_refined_spans_without_closures() - } + refined_spans.push(prev); + + // Remove `CoverageSpan`s with empty spans ONLY if the empty `CoverageSpan`s BCB also has at + // least one other non-empty `CoverageSpan`. + let mut has_coverage = BitSet::new_empty(basic_coverage_blocks.num_nodes()); + for covspan in &refined_spans { + if !covspan.span.is_empty() { + has_coverage.insert(covspan.bcb_leader_bb); + } + } + refined_spans.retain(|covspan| { + !(covspan.span.is_empty() + && is_goto(&mir_body[covspan.bcb_leader_bb].terminator().kind) + && has_coverage.contains(covspan.bcb_leader_bb)) + }); - fn add_refined_span(&mut self, coverage_span: CoverageSpan) { - self.refined_spans.push(coverage_span); + // Remove `CoverageSpan`s derived from closures, originally added to ensure the coverage + // regions for the current function leave room for the closure's own coverage regions + // (injected separately, from the closure's own MIR). + refined_spans.retain(|covspan| !covspan.is_closure); + refined_spans } - /// Remove `CoverageSpan`s derived from closures, originally added to ensure the coverage - /// regions for the current function leave room for the closure's own coverage regions - /// (injected separately, from the closure's own MIR). - fn to_refined_spans_without_closures(mut self) -> Vec { - self.refined_spans.retain(|covspan| !covspan.is_closure); - self.refined_spans + // Generate a set of `CoverageSpan`s from the filtered set of `Statement`s and `Terminator`s of + // the `BasicBlock`(s) in the given `BasicCoverageBlock`. One `CoverageSpan` is generated + // for each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will + // merge some `CoverageSpan`s, at which point a `CoverageSpan` may represent multiple + // `Statement`s and/or `Terminator`s.) + fn bcb_to_initial_coverage_spans(&self, bcb: &BasicCoverageBlock) -> Vec { + bcb.blocks + .iter() + .map(|bbref| { + let bb = *bbref; + let data = &self.mir_body[bb]; + data.statements + .iter() + .enumerate() + .filter_map(move |(index, statement)| { + filtered_statement_span(statement, self.body_span).map(|span| { + CoverageSpan::for_statement(statement, span, bcb, bb, index) + }) + }) + .chain( + filtered_terminator_span(data.terminator(), self.body_span) + .map(|span| CoverageSpan::for_terminator(span, bcb, bb)), + ) + }) + .flatten() + .collect() } fn curr(&self) -> &CoverageSpan { @@ -904,9 +1040,10 @@ impl<'a> CoverageSpanRefinery<'a> { /// If there are `pending_dups` but `prev` is not a matching dup (`prev.span` doesn't match the /// `pending_dups` spans), then one of the following two things happened during the previous /// iteration: - /// * the `span` of prev was modified (by `curr_mut().merge_from(prev)`); or - /// * the `span` of prev advanced past the end of the span of pending_dups - /// (`prev().span.hi() <= curr().span.lo()`) + /// * the previous `curr` span (which is now `prev`) was not a duplicate of the pending_dups + /// (in which case there should be at least two spans in `pending_dups`); or + /// * the `span` of `prev` was modified by `curr_mut().merge_from(prev)` (in which case + /// `pending_dups` could have as few as one span) /// In either case, no more spans will match the span of `pending_dups`, so /// add the `pending_dups` if they don't overlap `curr`, and clear the list. fn check_pending_dups(&mut self) { @@ -920,7 +1057,7 @@ impl<'a> CoverageSpanRefinery<'a> { let pending_dups = self.pending_dups.split_off(0); for dup in pending_dups.into_iter() { debug!(" ...adding at least one pending={:?}", dup); - self.add_refined_span(dup); + self.refined_spans.push(dup); } } else { self.pending_dups.clear(); @@ -935,7 +1072,7 @@ impl<'a> CoverageSpanRefinery<'a> { self.some_prev = Some(curr); self.prev_original_span = self.curr_original_span; } - while let Some(curr) = self.sorted_spans_iter.next() { + while let Some(curr) = self.sorted_spans_iter.as_mut().unwrap().next() { debug!("FOR curr={:?}", curr); if self.prev_starts_after_next(&curr) { debug!( @@ -994,10 +1131,10 @@ impl<'a> CoverageSpanRefinery<'a> { for mut dup in pending_dups.iter().cloned() { dup.span = dup.span.with_hi(left_cutoff); debug!(" ...and at least one pre_closure dup={:?}", dup); - self.add_refined_span(dup); + self.refined_spans.push(dup); } } - self.add_refined_span(pre_closure); + self.refined_spans.push(pre_closure); } if has_post_closure_span { // Update prev.span to start after the closure (and discard curr) @@ -1013,33 +1150,56 @@ impl<'a> CoverageSpanRefinery<'a> { } } + /// Called if `curr.span` equals `prev_original_span` (and potentially equal to all + /// `pending_dups` spans, if any); but keep in mind, `prev.span` may start at a `Span.lo()` that + /// is less than (further left of) `prev_original_span.lo()`. + /// /// When two `CoverageSpan`s have the same `Span`, dominated spans can be discarded; but if /// neither `CoverageSpan` dominates the other, both (or possibly more than two) are held, /// until their disposition is determined. In this latter case, the `prev` dup is moved into /// `pending_dups` so the new `curr` dup can be moved to `prev` for the next iteration. fn hold_pending_dups_unless_dominated(&mut self) { - // equal coverage spans are ordered by dominators before dominated (if any) - debug_assert!(!self.prev().is_dominated_by(self.curr(), self.dominators)); - - if self.curr().is_dominated_by(&self.prev(), self.dominators) { - // If one span dominates the other, assocate the span with the dominator only. - // - // For example: - // match somenum { - // x if x < 1 => { ... } - // }... - // The span for the first `x` is referenced by both the pattern block (every - // time it is evaluated) and the arm code (only when matched). The counter - // will be applied only to the dominator block. - // - // The dominator's (`prev`) execution count may be higher than the dominated - // block's execution count, so drop `curr`. + // Equal coverage spans are ordered by dominators before dominated (if any), so it should be + // impossible for `curr` to dominate any previous `CoverageSpan`. + debug_assert!(!self.span_bcb_is_dominated_by(self.prev(), self.curr())); + + let initial_pending_count = self.pending_dups.len(); + if initial_pending_count > 0 { + let mut pending_dups = self.pending_dups.split_off(0); + pending_dups.retain(|dup| !self.span_bcb_is_dominated_by(self.curr(), dup)); + self.pending_dups.append(&mut pending_dups); + if self.pending_dups.len() < initial_pending_count { + debug!( + " discarded {} of {} pending_dups that dominated curr", + initial_pending_count - self.pending_dups.len(), + initial_pending_count + ); + } + } + + if self.span_bcb_is_dominated_by(self.curr(), self.prev()) { debug!( - " different bcbs but SAME spans, and prev dominates curr. Drop curr and \ - keep prev for next iter. prev={:?}", + " different bcbs but SAME spans, and prev dominates curr. Discard prev={:?}", self.prev() ); - self.discard_curr(); + self.cutoff_prev_at_overlapping_curr(); + // If one span dominates the other, assocate the span with the code from the dominated + // block only (`curr`), and discard the overlapping portion of the `prev` span. (Note + // that if `prev.span` is wider than `prev_original_span`, a `CoverageSpan` will still + // be created for `prev`s block, for the non-overlapping portion, left of `curr.span`.) + // + // For example: + // match somenum { + // x if x < 1 => { ... } + // }... + // + // The span for the first `x` is referenced by both the pattern block (every time it is + // evaluated) and the arm code (only when matched). The counter will be applied only to + // the dominated block. This allows coverage to track and highlight things like the + // assignment of `x` above, if the branch is matched, making `x` available to the arm + // code; and to track and highlight the question mark `?` "try" operator at the end of + // a function call returning a `Result`, so the `?` is covered when the function returns + // an `Err`, and not counted as covered if the function always returns `Ok`. } else { // Save `prev` in `pending_dups`. (`curr` will become `prev` in the next iteration.) // If the `curr` CoverageSpan is later discarded, `pending_dups` can be discarded as @@ -1064,7 +1224,7 @@ impl<'a> CoverageSpanRefinery<'a> { fn cutoff_prev_at_overlapping_curr(&mut self) { debug!( " different bcbs, overlapping spans, so ignore/drop pending and only add prev \ - if it has statements that end before curr={:?}", + if it has statements that end before curr; prev={:?}", self.prev() ); if self.pending_dups.is_empty() { @@ -1075,13 +1235,17 @@ impl<'a> CoverageSpanRefinery<'a> { } else { debug!(" ... adding modified prev={:?}", self.prev()); let prev = self.take_prev(); - self.add_refined_span(prev); + self.refined_spans.push(prev); } } else { // with `pending_dups`, `prev` cannot have any statements that don't overlap self.pending_dups.clear(); } } + + fn span_bcb_is_dominated_by(&self, covspan: &CoverageSpan, dom_covspan: &CoverageSpan) -> bool { + self.dominators.is_dominated_by(covspan.bcb_leader_bb, dom_covspan.bcb_leader_bb) + } } fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> Option { @@ -1126,7 +1290,7 @@ fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> O | StatementKind::LlvmInlineAsm(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) => { - Some(source_info_span(&statement.source_info, body_span)) + Some(function_source_span(statement.source_info.span, body_span)) } } } @@ -1138,15 +1302,43 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) - // an `if condition { block }` has a span that includes the executed block, if true, // but for coverage, the code region executed, up to *and* through the SwitchInt, // actually stops before the if's block.) - TerminatorKind::Unreachable // Unreachable blocks are not connected to the CFG + TerminatorKind::Unreachable // Unreachable blocks are not connected to the MIR CFG | TerminatorKind::Assert { .. } | TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } | TerminatorKind::SwitchInt { .. } - | TerminatorKind::Goto { .. } // For `FalseEdge`, only the `real` branch is taken, so it is similar to a `Goto`. + // FIXME(richkadel): Note that `Goto` was moved to it's own match arm, for the reasons + // described below. Add tests to confirm whether or not similar cases also apply to + // `FalseEdge`. | TerminatorKind::FalseEdge { .. } => None, + // FIXME(richkadel): Note that `Goto` was initially filtered out (by returning `None`, as + // with the `TerminatorKind`s above) because its `Span` was way to broad to be beneficial, + // and, at the time, `Goto` didn't seem to provide any additional contributions to the + // coverage analysis. Upon further review, `Goto` terminated blocks do appear to benefit + // the coverage analysis, and the BCB CFG. To overcome the issues with the `Spans`, the + // coverage algorithms--and the final coverage map generation--include some exceptional + // behaviors. + // + // `Goto`s are often the targets of `SwitchInt` branches, and certain important + // optimizations to replace some `Counter`s with `Expression`s require a separate + // `BasicCoverageBlock` for each branch, to support the `Counter`, when needed. + // + // Also, some test cases showed that `Goto` terminators, and to some degree their `Span`s, + // provided useful context for coverage, such as to count and show when `if` blocks + // _without_ `else` blocks execute the `false` case (counting when the body of the `if` + // was _not_ taken). In these cases, the `Goto` span is ultimately given a `CoverageSpan` + // of 1 character, at the end of it's original `Span`. + // + // However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto` + // block must still be counted (for example, to contribute its count to an `Expression` + // that reports the execution count for some other block). In these cases, the code region + // is set to `None`. + TerminatorKind::Goto { .. } => { + Some(function_source_span(terminator.source_info.span.shrink_to_hi(), body_span)) + } + // Retain spans from all other terminators TerminatorKind::Resume | TerminatorKind::Abort @@ -1156,25 +1348,38 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) - | TerminatorKind::GeneratorDrop | TerminatorKind::FalseUnwind { .. } | TerminatorKind::InlineAsm { .. } => { - Some(source_info_span(&terminator.source_info, body_span)) + Some(function_source_span(terminator.source_info.span, body_span)) } } } #[inline(always)] -fn source_info_span(source_info: &SourceInfo, body_span: Span) -> Span { - let span = original_sp(source_info.span, body_span).with_ctxt(SyntaxContext::root()); +fn function_source_span(span: Span, body_span: Span) -> Span { + let span = original_sp(span, body_span).with_ctxt(SyntaxContext::root()); if body_span.contains(span) { span } else { body_span } } +#[inline(always)] +fn is_goto(term_kind: &TerminatorKind<'tcx>) -> bool { + match term_kind { + TerminatorKind::Goto { .. } => true, + _ => false, + } +} + /// Convert the Span into its file name, start line and column, and end line and column -fn make_code_region(file_name: Symbol, source_file: &Lrc, span: Span) -> CodeRegion { +fn make_code_region( + file_name: Symbol, + source_file: &Lrc, + span: Span, + body_span: Span, +) -> CodeRegion { let (start_line, mut start_col) = source_file.lookup_file_pos(span.lo()); let (end_line, end_col) = if span.hi() == span.lo() { let (end_line, mut end_col) = (start_line, start_col); // Extend an empty span by one character so the region will be counted. let CharPos(char_pos) = start_col; - if char_pos > 0 { + if span.hi() == body_span.hi() { start_col = CharPos(char_pos - 1); } else { end_col = CharPos(char_pos + 1); diff --git a/compiler/rustc_mir/src/util/graphviz.rs b/compiler/rustc_mir/src/util/graphviz.rs index e04f07774ed0b..625f1a3e6844e 100644 --- a/compiler/rustc_mir/src/util/graphviz.rs +++ b/compiler/rustc_mir/src/util/graphviz.rs @@ -62,6 +62,7 @@ where let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode; if dark_mode { graph_attrs.push(r#"bgcolor="black""#); + graph_attrs.push(r#"fontcolor="white""#); content_attrs.push(r#"color="white""#); content_attrs.push(r#"fontcolor="white""#); } @@ -112,7 +113,8 @@ where // Basic block number at the top. let (blk, bgcolor) = if data.is_cleanup { - (format!("{} (cleanup)", block.index()), "lightblue") + let color = if dark_mode { "royalblue" } else { "lightblue" }; + (format!("{} (cleanup)", block.index()), color) } else { let color = if dark_mode { "dimgray" } else { "gray" }; (format!("{}", block.index()), color) diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index 598727e677ca2..ddc65085e8093 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -26,13 +26,15 @@ } bb3: { -+ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 ++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 ++ Coverage::Expression(4294967295) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb4: { _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 ++ Coverage::Counter(3) for /the/src/instrument_coverage.rs:15:6 - 15:7; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } diff --git a/src/test/mir-opt/instrument_coverage.rs b/src/test/mir-opt/instrument_coverage.rs index d9c8e8d43a469..18863edac97e4 100644 --- a/src/test/mir-opt/instrument_coverage.rs +++ b/src/test/mir-opt/instrument_coverage.rs @@ -1,10 +1,10 @@ -// Test that the initial version of Rust coverage injects Coverage statements at the top of each -// function. The Coverage Counter statements are later converted into LLVM instrprof.increment -// intrinsics, during codegen. +// Test that `-Z instrument-coverage` injects Coverage statements. The Coverage Counter statements +// are later converted into LLVM instrprof.increment intrinsics, during codegen. // needs-profiler-support // ignore-windows -// compile-flags: -Zinstrument-coverage --remap-path-prefix={{src-base}}=/the/src +// compile-flags: -Z instrument-coverage --remap-path-prefix={{src-base}}=/the/src + // EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff // EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff fn main() { diff --git a/src/test/run-make-fulldeps/coverage-llvmir-base/filecheck.testprog.txt b/src/test/run-make-fulldeps/coverage-llvmir-base/filecheck.testprog.txt index 0a3c4aedd5569..bd2a2475d9e10 100644 --- a/src/test/run-make-fulldeps/coverage-llvmir-base/filecheck.testprog.txt +++ b/src/test/run-make-fulldeps/coverage-llvmir-base/filecheck.testprog.txt @@ -34,7 +34,7 @@ CHECK-SAME: section "llvm.metadata" CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} { CHECK-NEXT: start: -CHECK-NOT: bb{{[0-9]+}}: +CHECK-NOT: [[DEFINE_INTERNAL]] CHECK: %pgocount = load i64, i64* getelementptr inbounds CHECK-SAME: * @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, diff --git a/src/test/run-make-fulldeps/coverage-reports-base/Makefile b/src/test/run-make-fulldeps/coverage-reports-base/Makefile index 880d7fdb1b040..bfecc5fd7f557 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports-base/Makefile @@ -21,6 +21,7 @@ clear_expected_if_blessed: ifdef RUSTC_BLESS_TEST rm -f expected_export_coverage.*.json rm -f expected_show_coverage.*.txt + rm -f expected_show_coverage_counters.*.txt endif -include clear_expected_if_blessed @@ -54,14 +55,19 @@ endif # when comparing the JSON `export`, the `show` output may be useful when # debugging. "$(LLVM_BIN_DIR)"/llvm-cov show \ + --debug \ --Xdemangler="$(RUST_DEMANGLER)" \ --show-line-counts-or-regions \ --instr-profile="$(TMPDIR)"/$@.profdata \ $(call BIN,"$(TMPDIR)"/$@) \ - > "$(TMPDIR)"/actual_show_coverage.$@.txt + > "$(TMPDIR)"/actual_show_coverage.$@.txt \ + 2> "$(TMPDIR)"/actual_show_coverage_counters.$@.txt ifdef RUSTC_BLESS_TEST - cp "$(TMPDIR)"/actual_show_coverage.$@.txt expected_show_coverage.$@.txt + cp "$(TMPDIR)"/actual_show_coverage.$@.txt \ + expected_show_coverage.$@.txt + cp "$(TMPDIR)"/actual_show_coverage_counters.$@.txt \ + expected_show_coverage_counters.$@.txt else # Compare the show coverage output (`--bless` refreshes `typical` files) # Note `llvm-cov show` output for some programs can vary, but can be ignored @@ -75,6 +81,14 @@ else false \ ) + $(DIFF) expected_show_coverage_counters.$@.txt "$(TMPDIR)"/actual_show_coverage_counters.$@.txt || \ + ( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \ + >&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \ + ) || \ + ( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \ + false \ + ) + endif # Generate a coverage report in JSON, using `llvm-cov export`, and fail if diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.closure.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.closure.json index 8c6edae280397..bff55300b3ca3 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.closure.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.closure.json @@ -17,14 +17,14 @@ }, "lines": { "count": 91, - "covered": 75, - "percent": 82.41758241758241 + "covered": 77, + "percent": 84.61538461538461 }, "regions": { - "count": 21, - "covered": 11, - "notcovered": 10, - "percent": 52.38095238095239 + "count": 25, + "covered": 13, + "notcovered": 12, + "percent": 52 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 91, - "covered": 75, - "percent": 82.41758241758241 + "covered": 77, + "percent": 84.61538461538461 }, "regions": { - "count": 21, - "covered": 11, - "notcovered": 10, - "percent": 52.38095238095239 + "count": 25, + "covered": 13, + "notcovered": 12, + "percent": 52 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json index bd2e2d56d4a55..7a7e4c04f0018 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 5, - "covered": 5, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 5, - "covered": 5, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json index a50f4657e20aa..1025cd3de80d2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 7, + "covered": 7, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 7, + "covered": 7, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if.json index 2ff53ad33fa99..84dcc251f3f4b 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 4, + "count": 5, "covered": 4, - "notcovered": 0, - "percent": 100 + "notcovered": 1, + "percent": 80 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 4, + "count": 5, "covered": 4, - "notcovered": 0, - "percent": 100 + "notcovered": 1, + "percent": 80 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json index 36f81ceae19bf..2d2ad1dbe3f71 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 28, - "covered": 19, - "percent": 67.85714285714286 + "count": 29, + "covered": 21, + "percent": 72.41379310344827 }, "regions": { - "count": 7, - "covered": 5, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 71.42857142857143 + "percent": 77.77777777777779 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 28, - "covered": 19, - "percent": 67.85714285714286 + "count": 29, + "covered": 21, + "percent": 72.41379310344827 }, "regions": { - "count": 7, - "covered": 5, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 71.42857142857143 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.inner_items.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.inner_items.json index a24e6a33a3397..c178e7f93476f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.inner_items.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.inner_items.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 13, + "count": 15, "covered": 13, - "notcovered": 0, - "percent": 100 + "notcovered": 2, + "percent": 86.66666666666667 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 13, + "count": 15, "covered": 13, - "notcovered": 0, - "percent": 100 + "notcovered": 2, + "percent": 86.66666666666667 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json index 585346dc32a60..95a1dcd3b8eee 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 21, - "covered": 19, - "percent": 90.47619047619048 + "count": 40, + "covered": 32, + "percent": 80 }, "regions": { - "count": 16, - "covered": 14, - "notcovered": 2, - "percent": 87.5 + "count": 39, + "covered": 28, + "notcovered": 11, + "percent": 71.7948717948718 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 21, - "covered": 19, - "percent": 90.47619047619048 + "count": 40, + "covered": 32, + "percent": 80 }, "regions": { - "count": 16, - "covered": 14, - "notcovered": 2, - "percent": 87.5 + "count": 39, + "covered": 28, + "notcovered": 11, + "percent": 71.7948717948718 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json new file mode 100644 index 0000000000000..aec85cd0329cb --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/loops_and_branches.rs", + "summary": { + "functions": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "instantiations": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "lines": { + "count": 11, + "covered": 11, + "percent": 100 + }, + "regions": { + "count": 10, + "covered": 8, + "notcovered": 2, + "percent": 80 + } + } + } + ], + "totals": { + "functions": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "instantiations": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "lines": { + "count": 11, + "covered": 11, + "percent": 100 + }, + "regions": { + "count": 10, + "covered": 8, + "notcovered": 2, + "percent": 80 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json new file mode 100644 index 0000000000000..dbe4f9ca6fd17 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/nested_loops.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 21, + "covered": 17, + "percent": 80.95238095238095 + }, + "regions": { + "count": 20, + "covered": 16, + "notcovered": 4, + "percent": 80 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 21, + "covered": 17, + "percent": 80.95238095238095 + }, + "regions": { + "count": 20, + "covered": 16, + "notcovered": 4, + "percent": 80 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.partial_eq_counter_without_region.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.partial_eq_counter_without_region.json new file mode 100644 index 0000000000000..8081fba9e22ee --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.partial_eq_counter_without_region.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/partial_eq_counter_without_region.rs", + "summary": { + "functions": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "instantiations": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "lines": { + "count": 15, + "covered": 15, + "percent": 100 + }, + "regions": { + "count": 6, + "covered": 6, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "totals": { + "functions": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "instantiations": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "lines": { + "count": 15, + "covered": 15, + "percent": 100 + }, + "regions": { + "count": 6, + "covered": 6, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_loop.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_loop.json index 38bc96898ea36..ada6bb062dd1e 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_loop.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_loop.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 18, - "covered": 18, + "count": 19, + "covered": 19, "percent": 100 }, "regions": { - "count": 7, - "covered": 7, - "notcovered": 0, - "percent": 100 + "count": 9, + "covered": 8, + "notcovered": 1, + "percent": 88.88888888888889 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 18, - "covered": 18, + "count": 19, + "covered": 19, "percent": 100 }, "regions": { - "count": 7, - "covered": 7, - "notcovered": 0, - "percent": 100 + "count": 9, + "covered": 8, + "notcovered": 1, + "percent": 88.88888888888889 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_match.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_match.json index f9d91d66f1db2..63d1ae74c5f5d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_match.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.simple_match.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 26, - "covered": 26, + "count": 24, + "covered": 24, "percent": 100 }, "regions": { - "count": 9, - "covered": 9, - "notcovered": 0, - "percent": 100 + "count": 15, + "covered": 14, + "notcovered": 1, + "percent": 93.33333333333333 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 26, - "covered": 26, + "count": 24, + "covered": 24, "percent": 100 }, "regions": { - "count": 9, - "covered": 9, - "notcovered": 0, - "percent": 100 + "count": 15, + "covered": 14, + "notcovered": 1, + "percent": 93.33333333333333 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.tight_infinite_loop.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.tight_infinite_loop.json new file mode 100644 index 0000000000000..3fa6821cd1df9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.tight_infinite_loop.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/tight_infinite_loop.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "regions": { + "count": 2, + "covered": 2, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "regions": { + "count": 2, + "covered": 2, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json index e6ef2c1ab899e..e845ee29fa452 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 20, + "covered": 19, + "percent": 95 }, "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 + "count": 20, + "covered": 17, + "notcovered": 3, + "percent": 85 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 20, + "covered": 19, + "percent": 95 }, "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 + "count": 20, + "covered": 17, + "notcovered": 3, + "percent": 85 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json index 410821ea33592..464bb614ea1b1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json @@ -21,10 +21,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 51, + "count": 70, "covered": 19, - "notcovered": 32, - "percent": 37.254901960784316 + "notcovered": 51, + "percent": 27.142857142857142 } } } @@ -46,10 +46,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 51, + "count": 70, "covered": 19, - "notcovered": 32, - "percent": 37.254901960784316 + "notcovered": 51, + "percent": 27.142857142857142 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json new file mode 100644 index 0000000000000..27862087ed567 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/while.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 4, + "covered": 3, + "percent": 75 + }, + "regions": { + "count": 5, + "covered": 3, + "notcovered": 2, + "percent": 60 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 4, + "covered": 3, + "percent": 75 + }, + "regions": { + "count": 5, + "covered": 3, + "notcovered": 2, + "percent": 60 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json index 865b705fa2007..555ac745d5371 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json @@ -17,14 +17,14 @@ }, "lines": { "count": 18, - "covered": 16, - "percent": 88.88888888888889 + "covered": 15, + "percent": 83.33333333333334 }, "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 + "count": 11, + "covered": 8, + "notcovered": 3, + "percent": 72.72727272727273 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 18, - "covered": 16, - "percent": 88.88888888888889 + "covered": 15, + "percent": 83.33333333333334 }, "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 + "count": 11, + "covered": 8, + "notcovered": 3, + "percent": 72.72727272727273 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.closure.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.closure.txt index 17054490e9b3c..aef26a62e25fb 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.closure.txt @@ -62,7 +62,7 @@ 62| 1| let mut countdown = 0; 63| 1| if is_false { 64| 0| countdown = 10; - 65| 0| } + 65| 1| } 66| 1| "alt string 3".to_owned() 67| 1| } 68| 1| ) @@ -77,7 +77,7 @@ 77| 1| let mut countdown = 0; 78| 1| if is_false { 79| 0| countdown = 10; - 80| 0| } + 80| 1| } 81| 1| "alt string 4".to_owned() 82| 1| }; 83| 1| println!( diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt index 72aa020ca1691..43592df1059aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt @@ -24,7 +24,7 @@ 24| | let _ = Firework { strength: 1000 }; 25| | 26| | Ok(()) - 27| 1|} + 27| 2|} 28| | 29| |// Expected program output: 30| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt index 86199d7476302..11dc0aa65e2d1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt @@ -57,7 +57,7 @@ 35| | let _ = Firework { strength: 1000 }; 36| | 37| | Ok(()) - 38| 1|} + 38| 2|} 39| | 40| |// Expected program output: 41| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if.txt index bc2f9b108b2f3..85e6440ab3729 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if.txt @@ -25,5 +25,6 @@ 25| 1| 10 26| 1| ; 27| 1| } + ^0 28| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt index 5f899723e2554..64cbc262521bf 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt @@ -20,7 +20,7 @@ 20| 0| countdown 21| 0| = 22| 0| 100 - 23| | } + 23| 1| } 24| | 25| | if 26| 1| is_true @@ -36,6 +36,6 @@ 36| 0| = 37| 0| 100 38| 0| ; - 39| 0| } + 39| 1| } 40| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.inner_items.txt index b13ca83d018f9..4a51f842a4bb2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.inner_items.txt @@ -10,6 +10,7 @@ 10| 1| if is_true { 11| 1| countdown = 10; 12| 1| } + ^0 13| | 14| | mod in_mod { 15| | const IN_MOD_CONST: u32 = 1000; @@ -48,6 +49,7 @@ 48| 1| if is_true { 49| 1| in_func(countdown); 50| 1| } + ^0 51| | 52| 1| let mut val = InStruct { 53| 1| in_struct_field: 101, diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt index ded4369751587..f01f69f2496ee 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt @@ -12,12 +12,14 @@ 12| 1| b = 10; 13| 1| c = 100; 14| 1| } + ^0 15| | let 16| 1| somebool 17| | = 18| 1| a < b 19| | || - 20| 0| b < c + 20| 1| b < c + ^0 21| | ; 22| | let 23| 1| somebool @@ -26,19 +28,38 @@ 26| | || 27| 1| b < c 28| | ; - 29| | let - 30| 1| somebool - 31| | = - 32| 1| a < b - 33| | && - 34| 1| b < c - 35| | ; - 36| | let - 37| 1| somebool - 38| | = - 39| 1| b < a - 40| | && - 41| 0| b < c - 42| | ; - 43| 1|} + 29| 1| let somebool = a < b && b < c; + 30| 1| let somebool = b < a && b < c; + ^0 + 31| | + 32| | if + 33| 1| ! + 34| 1| is_true + 35| 0| { + 36| 0| a = 2 + 37| 0| ; + 38| 1| } + 39| | + 40| | if + 41| 1| is_true + 42| 1| { + 43| 1| b = 30 + 44| 1| ; + 45| 1| } + 46| | else + 47| 0| { + 48| 0| c = 400 + 49| 0| ; + 50| 1| } + 51| | + 52| 1| if !is_true { + 53| 0| a = 2; + 54| 1| } + 55| | + 56| 1| if is_true { + 57| 1| b = 30; + 58| 1| } else { + 59| 0| c = 400; + 60| 1| } + 61| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.loops_and_branches.txt new file mode 100644 index 0000000000000..3a969a6b89869 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.loops_and_branches.txt @@ -0,0 +1,38 @@ + 1| |#![allow(unused_assignments)] + 2| | + 3| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the + 4| |// structure of this `fmt` function. + 5| | + 6| |struct DebugTest; + 7| | + 8| |impl std::fmt::Debug for DebugTest { + 9| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + 10| 1| if true { + 11| 1| if false { + 12| | while true { + 13| | } + 14| 1| } + 15| 1| write!(f, "error")?; + ^0 + 16| | } else { + 17| 1| } + 18| 1| Ok(()) + 19| 1| } + 20| |} + 21| | + 22| 1|fn main() { + 23| 1| let debug_test = DebugTest; + 24| 1| println!("{:?}", debug_test); + 25| 1|} + 26| | + 27| |/* + 28| | + 29| |This is the error message generated, before the issue was fixed: + 30| | + 31| |error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42: + 32| |Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt): + 33| |Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: + 34| |[bcb6, bcb7, bcb9]" } + 35| | + 36| |*/ + diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt new file mode 100644 index 0000000000000..e0545c76f780f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt @@ -0,0 +1,26 @@ + 1| |fn main() { + 2| 1| let is_true = std::env::args().len() == 1; + 3| 1| let mut countdown = 10; + 4| | + 5| 1| 'outer: while countdown > 0 { + 6| 1| let mut a = 100; + 7| 1| let mut b = 100; + 8| 3| for _ in 0..50 { + 9| 3| if a < 30 { + 10| 0| break; + 11| | } + 12| 3| a -= 5; + 13| 3| b -= 5; + 14| 3| if b < 90 { + 15| 1| a -= 10; + 16| 1| if is_true { + 17| 1| break 'outer; + 18| | } else { + 19| 0| a -= 2; + 20| 0| } + 21| 2| } + 22| 3| } + 23| 0| countdown -= 1; + 24| 1| } + 25| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.partial_eq_counter_without_region.txt new file mode 100644 index 0000000000000..310bf13a695af --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.partial_eq_counter_without_region.txt @@ -0,0 +1,101 @@ + 1| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the + 2| |// structure of this test. + 3| | + 4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + ^1 ^1 + 5| |pub struct Version { + 6| | major: usize, + 7| 1| minor: usize, + 8| | patch: usize, + 9| |} + 10| | + 11| |impl Version { + 12| | pub fn new(major: usize, minor: usize, patch: usize) -> Self { + 13| 2| Self { + 14| 2| major, + 15| 2| minor, + 16| 2| patch, + 17| 2| } + 18| 2| } + 19| |} + 20| | + 21| 1|fn main() { + 22| 1| let version_3_2_1 = Version::new(3, 2, 1); + 23| 1| let version_3_3_0 = Version::new(3, 3, 0); + 24| 1| + 25| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); + 26| 1|} + 27| | + 28| |/* + 29| | + 30| |This test verifies a bug was fixed that otherwise generated this error: + 31| | + 32| |thread 'rustc' panicked at 'No counters provided the source_hash for function: + 33| | Instance { + 34| | def: Item(WithOptConstParam { + 35| | did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp), + 36| | const_param_did: None + 37| | }), + 38| | substs: [] + 39| | }' + 40| |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage + 41| |without a code region associated with any `Counter`. Code regions were associated with at least + 42| |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen + 43| |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the + 44| |`function_source_hash` without a code region, if necessary. + 45| | + 46| |*/ + 47| | + 48| |// FIXME(richkadel): It may be worth investigating why the coverage report for this test produces + 49| |// the following results: + 50| | + 51| |/* + 52| | + 53| |1. Why are their two counts below different characters (first and last) of `PartialOrd`, on line 17? + 54| | + 55| |2. Line 17 is counted twice, but the `::lt` instance shows a line count of 1? Is there a missing + 56| | line count with a different instance? Or was it really only called once? + 57| | + 58| |3. Line 20 shows another line count (of 1) for a line within a `struct` declaration (on only one of + 59| | its 3 fields). I doubt the specific field (`minor`) is relevant, but rather I suspect there's a + 60| | problem computing the file position here, for some reason. + 61| | + 62| | + 63| | 16| | + 64| | 17| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + 65| | ^1 ^1 + 66| |------------------ + 67| ||Unexecuted instantiation: ::gt + 68| |------------------ + 69| ||Unexecuted instantiation: ::le + 70| |------------------ + 71| ||Unexecuted instantiation: ::ge + 72| |------------------ + 73| ||::lt: + 74| || 17| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + 75| |------------------ + 76| | 18| |pub struct Version { + 77| | 19| | major: usize, + 78| | 20| 1| minor: usize, + 79| | 21| | patch: usize, + 80| | 22| |} + 81| | 23| | + 82| | 24| |impl Version { + 83| | 25| | pub fn new(major: usize, minor: usize, patch: usize) -> Self { + 84| | 26| 2| Version { + 85| | 27| 2| major, + 86| | 28| 2| minor, + 87| | 29| 2| patch, + 88| | 30| 2| } + 89| | 31| 2| } + 90| | 32| |} + 91| | 33| | + 92| | 34| 1|fn main() { + 93| | 35| 1| let version_3_2_1 = Version::new(3, 2, 1); + 94| | 36| 1| let version_3_3_0 = Version::new(3, 3, 0); + 95| | 37| 1| + 96| | 38| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version + 97| |_3_3_0); + 98| | 39| 1|} + 99| |*/ + diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_loop.txt index f1acb7c545940..064930dd75c93 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_loop.txt @@ -16,6 +16,7 @@ 16| 1| 10 17| 1| ; 18| 1| } + ^0 19| | 20| | loop 21| | { @@ -31,6 +32,6 @@ 31| 10| -= 32| 10| 1 33| | ; - 34| | } + 34| 1| } 35| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_match.txt index e42f22cd047fc..1f7e71d3eb0e7 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.simple_match.txt @@ -10,22 +10,24 @@ 10| 1| if is_true { 11| 1| countdown = 0; 12| 1| } + ^0 13| | - 14| 3| for - 15| 3| _ + 14| | for + 15| 2| _ 16| | in - 17| 1| 0..2 + 17| 3| 0..2 18| | { 19| | let z 20| | ; 21| | match 22| 2| countdown - 23| 2| { - 24| 2| x - 25| 2| if + 23| | { + 24| 1| x + 25| | if 26| 2| x 27| 2| < 28| 2| 1 + ^1 29| | => 30| 1| { 31| 1| z = countdown @@ -39,6 +41,6 @@ 39| | => 40| 1| {} 41| | } - 42| | } + 42| 3| } 43| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.tight_infinite_loop.txt new file mode 100644 index 0000000000000..e02eac03a6b15 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.tight_infinite_loop.txt @@ -0,0 +1,6 @@ + 1| |fn main() { + 2| 1| if false { + 3| | loop {} + 4| | } + 5| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt index ae288d7d7a000..05d72d0de46e6 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt @@ -6,22 +6,22 @@ 6| 1| Err(()) 7| | } else { 8| 5| Ok(()) - 9| | } + 9| 1| } 10| 6|} 11| | 12| |fn main() -> Result<(),()> { 13| 1| let mut 14| 1| countdown = 10 15| | ; - 16| 6| for + 16| | for 17| 6| _ 18| | in - 19| 1| 0..10 + 19| 6| 0..10 20| | { 21| 6| countdown 22| 6| -= 1 - 23| | ; - 24| | if + 23| 6| ; + 24| 6| if 25| 6| countdown < 5 26| | { 27| 1| call(/*return_error=*/ true)?; @@ -29,8 +29,9 @@ 29| | else 30| | { 31| 5| call(/*return_error=*/ false)?; - 32| | } - 33| | } + ^0 + 32| 5| } + 33| 6| } 34| 0| Ok(()) - 35| 1|} + 35| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt index 173ff4aa4c481..e0efe75043d4a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt @@ -65,5 +65,5 @@ 64| | } else { 65| 0| return; 66| | }; - 67| 1|} + 67| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while.txt new file mode 100644 index 0000000000000..194325b6b9eca --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while.txt @@ -0,0 +1,6 @@ + 1| |fn main() { + 2| 1| let num = 9; + 3| 1| while num >= 10 { + 4| 0| } + 5| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt index 7dce94f25f304..2e0c4022bedb8 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt @@ -3,7 +3,7 @@ 3| | 4| |fn main() -> Result<(),u8> { 5| 1| let mut countdown = 10; - 6| 7| while + 6| | while 7| 7| countdown 8| 7| > 9| 7| 0 @@ -24,7 +24,7 @@ 24| | else 25| | { 26| 1| Err(1) - 27| | } + 27| 0| } 28| | ; 29| | } 30| 6| countdown @@ -33,7 +33,7 @@ 33| | ; 34| | } 35| 0| Ok(()) - 36| 1|} + 36| 2|} 37| | 38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and 39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt new file mode 100644 index 0000000000000..3eb07757c0da5 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt @@ -0,0 +1,95 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/closure.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/closure +Counter in file 0 20:21 -> 20:38, #1 +Counter in file 0 21:20 -> 21:28, (#1 + 0) +Counter in file 0 21:29 -> 23:18, #2 +Counter in file 0 23:18 -> 23:19, #3 +Counter in file 0 24:17 -> 25:14, #4 +Counter in file 0 3:11 -> 18:13, #1 +Counter in file 0 25:14 -> 33:9, (#1 + 0) +Counter in file 0 40:6 -> 60:13, (#1 + 0) +Counter in file 0 67:14 -> 75:9, (#1 + 0) +Counter in file 0 82:6 -> 93:2, (#1 + 0) +Counter in file 0 77:13 -> 77:30, #1 +Counter in file 0 78:12 -> 78:20, (#1 + 0) +Counter in file 0 78:21 -> 80:10, #2 +Counter in file 0 80:10 -> 80:11, #3 +Counter in file 0 81:9 -> 82:6, #4 +Counter in file 0 62:21 -> 62:38, #1 +Counter in file 0 63:20 -> 63:28, (#1 + 0) +Counter in file 0 63:29 -> 65:18, #2 +Counter in file 0 65:18 -> 65:19, #3 +Counter in file 0 66:17 -> 67:14, #4 +Counter in file 0 35:13 -> 35:30, #1 +Counter in file 0 36:12 -> 36:20, (#1 + 0) +Counter in file 0 36:21 -> 38:10, #2 +Counter in file 0 38:10 -> 38:11, #3 +Counter in file 0 39:9 -> 40:6, #4 +Emitting segments for file: ../coverage/closure.rs +Combined regions: + 3:11 -> 18:13 (count=1) + 20:21 -> 20:38 (count=0) + 21:20 -> 21:28 (count=0) + 21:29 -> 23:18 (count=0) + 23:18 -> 23:19 (count=0) + 24:17 -> 25:14 (count=0) + 25:14 -> 33:9 (count=1) + 35:13 -> 35:30 (count=0) + 36:12 -> 36:20 (count=0) + 36:21 -> 38:10 (count=0) + 38:10 -> 38:11 (count=0) + 39:9 -> 40:6 (count=0) + 40:6 -> 60:13 (count=1) + 62:21 -> 62:38 (count=1) + 63:20 -> 63:28 (count=1) + 63:29 -> 65:18 (count=0) + 65:18 -> 65:19 (count=1) + 66:17 -> 67:14 (count=1) + 67:14 -> 75:9 (count=1) + 77:13 -> 77:30 (count=1) + 78:12 -> 78:20 (count=1) + 78:21 -> 80:10 (count=0) + 80:10 -> 80:11 (count=1) + 81:9 -> 82:6 (count=1) + 82:6 -> 93:2 (count=1) +Segment at 3:11 (count = 1), RegionEntry +Segment at 18:13 (count = 0), Skipped +Segment at 20:21 (count = 0), RegionEntry +Segment at 20:38 (count = 0), Skipped +Segment at 21:20 (count = 0), RegionEntry +Segment at 21:28 (count = 0), Skipped +Segment at 21:29 (count = 0), RegionEntry +Segment at 23:18 (count = 0), RegionEntry +Segment at 23:19 (count = 0), Skipped +Segment at 24:17 (count = 0), RegionEntry +Segment at 25:14 (count = 1), RegionEntry +Segment at 33:9 (count = 0), Skipped +Segment at 35:13 (count = 0), RegionEntry +Segment at 35:30 (count = 0), Skipped +Segment at 36:12 (count = 0), RegionEntry +Segment at 36:20 (count = 0), Skipped +Segment at 36:21 (count = 0), RegionEntry +Segment at 38:10 (count = 0), RegionEntry +Segment at 38:11 (count = 0), Skipped +Segment at 39:9 (count = 0), RegionEntry +Segment at 40:6 (count = 1), RegionEntry +Segment at 60:13 (count = 0), Skipped +Segment at 62:21 (count = 1), RegionEntry +Segment at 62:38 (count = 0), Skipped +Segment at 63:20 (count = 1), RegionEntry +Segment at 63:28 (count = 0), Skipped +Segment at 63:29 (count = 0), RegionEntry +Segment at 65:18 (count = 1), RegionEntry +Segment at 65:19 (count = 0), Skipped +Segment at 66:17 (count = 1), RegionEntry +Segment at 67:14 (count = 1), RegionEntry +Segment at 75:9 (count = 0), Skipped +Segment at 77:13 (count = 1), RegionEntry +Segment at 77:30 (count = 0), Skipped +Segment at 78:12 (count = 1), RegionEntry +Segment at 78:20 (count = 0), Skipped +Segment at 78:21 (count = 0), RegionEntry +Segment at 80:10 (count = 1), RegionEntry +Segment at 80:11 (count = 0), Skipped +Segment at 81:9 (count = 1), RegionEntry +Segment at 82:6 (count = 1), RegionEntry +Segment at 93:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt new file mode 100644 index 0000000000000..447c3c8956230 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt @@ -0,0 +1,24 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/drop_trait.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/drop_trait +Counter in file 0 9:24 -> 11:6, #1 +Counter in file 0 15:9 -> 17:42, #1 +Counter in file 0 19:8 -> 19:12, (#1 + 0) +Counter in file 0 20:9 -> 21:22, #2 +Counter in file 0 27:1 -> 27:2, #4 +Counter in file 0 27:1 -> 27:2, (#2 + 0) +Emitting segments for file: ../coverage/drop_trait.rs +Combined regions: + 9:24 -> 11:6 (count=2) + 15:9 -> 17:42 (count=1) + 19:8 -> 19:12 (count=1) + 20:9 -> 21:22 (count=1) + 27:1 -> 27:2 (count=2) +Segment at 9:24 (count = 2), RegionEntry +Segment at 11:6 (count = 0), Skipped +Segment at 15:9 (count = 1), RegionEntry +Segment at 17:42 (count = 0), Skipped +Segment at 19:8 (count = 1), RegionEntry +Segment at 19:12 (count = 0), Skipped +Segment at 20:9 (count = 1), RegionEntry +Segment at 21:22 (count = 0), Skipped +Segment at 27:1 (count = 2), RegionEntry +Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt new file mode 100644 index 0000000000000..5843b9175883f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt @@ -0,0 +1,50 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/generics.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/generics +Counter in file 0 17:24 -> 19:6, #1 +Counter in file 0 17:24 -> 19:6, #1 +Counter in file 0 23:9 -> 28:28, #1 +Counter in file 0 30:8 -> 30:12, (#1 + 0) +Counter in file 0 31:9 -> 32:22, #2 +Counter in file 0 38:1 -> 38:2, #4 +Counter in file 0 38:1 -> 38:2, (#2 + 0) +Counter in file 0 10:49 -> 12:6, #1 +Counter in file 0 10:49 -> 12:6, #1 +Emitting segments for file: ../coverage/generics.rs +Combined regions: + 10:49 -> 12:6 (count=3) + 17:24 -> 19:6 (count=2) + 23:9 -> 28:28 (count=1) + 30:8 -> 30:12 (count=1) + 31:9 -> 32:22 (count=1) + 38:1 -> 38:2 (count=2) +Segment at 10:49 (count = 3), RegionEntry +Segment at 12:6 (count = 0), Skipped +Segment at 17:24 (count = 2), RegionEntry +Segment at 19:6 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 28:28 (count = 0), Skipped +Segment at 30:8 (count = 1), RegionEntry +Segment at 30:12 (count = 0), Skipped +Segment at 31:9 (count = 1), RegionEntry +Segment at 32:22 (count = 0), Skipped +Segment at 38:1 (count = 2), RegionEntry +Segment at 38:2 (count = 0), Skipped +Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_ +Combined regions: + 10:49 -> 12:6 (count=2) +Segment at 10:49 (count = 2), RegionEntry +Segment at 12:6 (count = 0), Skipped +Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworklE12set_strengthB2_ +Combined regions: + 10:49 -> 12:6 (count=1) +Segment at 10:49 (count = 1), RegionEntry +Segment at 12:6 (count = 0), Skipped +Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_ +Combined regions: + 17:24 -> 19:6 (count=1) +Segment at 17:24 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped +Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_ +Combined regions: + 17:24 -> 19:6 (count=1) +Segment at 17:24 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt new file mode 100644 index 0000000000000..2f063de5a3959 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt @@ -0,0 +1,22 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if +Counter in file 0 8:5 -> 18:10, #1 +Counter in file 0 21:9 -> 21:16, (#1 + 0) +Counter in file 0 22:5 -> 27:6, #2 +Counter in file 0 27:6 -> 27:7, #3 +Counter in file 0 28:1 -> 28:2, #4 +Emitting segments for file: ../coverage/if.rs +Combined regions: + 8:5 -> 18:10 (count=1) + 21:9 -> 21:16 (count=1) + 22:5 -> 27:6 (count=1) + 27:6 -> 27:7 (count=0) + 28:1 -> 28:2 (count=1) +Segment at 8:5 (count = 1), RegionEntry +Segment at 18:10 (count = 0), Skipped +Segment at 21:9 (count = 1), RegionEntry +Segment at 21:16 (count = 0), Skipped +Segment at 22:5 (count = 1), RegionEntry +Segment at 27:6 (count = 0), RegionEntry +Segment at 27:7 (count = 0), Skipped +Segment at 28:1 (count = 1), RegionEntry +Segment at 28:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt new file mode 100644 index 0000000000000..660e85f91f52b --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt @@ -0,0 +1,38 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else +Counter in file 0 7:9 -> 11:16, #1 +Counter in file 0 12:5 -> 17:6, #2 +Counter in file 0 20:9 -> 22:16, #3 +Counter in file 0 23:6 -> 23:7, (#2 + 0) +Counter in file 0 26:9 -> 26:16, #4 +Counter in file 0 27:5 -> 32:6, #5 +Counter in file 0 34:5 -> 39:6, #6 +Counter in file 0 39:6 -> 39:7, (#5 + 0) +Counter in file 0 40:1 -> 40:2, #7 +Emitting segments for file: ../coverage/if_else.rs +Combined regions: + 7:9 -> 11:16 (count=1) + 12:5 -> 17:6 (count=1) + 20:9 -> 22:16 (count=0) + 23:6 -> 23:7 (count=1) + 26:9 -> 26:16 (count=1) + 27:5 -> 32:6 (count=1) + 34:5 -> 39:6 (count=0) + 39:6 -> 39:7 (count=1) + 40:1 -> 40:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 11:16 (count = 0), Skipped +Segment at 12:5 (count = 1), RegionEntry +Segment at 17:6 (count = 0), Skipped +Segment at 20:9 (count = 0), RegionEntry +Segment at 22:16 (count = 0), Skipped +Segment at 23:6 (count = 1), RegionEntry +Segment at 23:7 (count = 0), Skipped +Segment at 26:9 (count = 1), RegionEntry +Segment at 26:16 (count = 0), Skipped +Segment at 27:5 (count = 1), RegionEntry +Segment at 32:6 (count = 0), Skipped +Segment at 34:5 (count = 0), RegionEntry +Segment at 39:6 (count = 1), RegionEntry +Segment at 39:7 (count = 0), Skipped +Segment at 40:1 (count = 1), RegionEntry +Segment at 40:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt new file mode 100644 index 0000000000000..fb863c73a6366 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt @@ -0,0 +1,61 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/inner_items.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/inner_items +Counter in file 0 19:13 -> 19:18, #1 +Counter in file 0 20:13 -> 20:14, #2 +Counter in file 0 20:17 -> 20:22, (#1 + 0) +Counter in file 0 21:9 -> 22:6, (#2 + 0) +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 12:6, #2 +Counter in file 0 12:6 -> 12:7, #3 +Counter in file 0 48:8 -> 48:15, #4 +Counter in file 0 48:16 -> 50:6, #5 +Counter in file 0 50:6 -> 50:7, #6 +Counter in file 0 52:9 -> 57:2, #7 +Counter in file 0 33:42 -> 36:10, #1 +Counter in file 0 41:37 -> 41:41, #1 +Counter in file 0 42:13 -> 43:10, #2 +Emitting segments for file: ../coverage/inner_items.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 12:6 (count=1) + 12:6 -> 12:7 (count=0) + 19:13 -> 19:18 (count=3) + 20:13 -> 20:14 (count=3) + 20:17 -> 20:22 (count=3) + 21:9 -> 22:6 (count=3) + 33:42 -> 36:10 (count=1) + 41:37 -> 41:41 (count=1) + 42:13 -> 43:10 (count=1) + 48:8 -> 48:15 (count=1) + 48:16 -> 50:6 (count=1) + 50:6 -> 50:7 (count=0) + 52:9 -> 57:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 12:6 (count = 0), RegionEntry +Segment at 12:7 (count = 0), Skipped +Segment at 19:13 (count = 3), RegionEntry +Segment at 19:18 (count = 0), Skipped +Segment at 20:13 (count = 3), RegionEntry +Segment at 20:14 (count = 0), Skipped +Segment at 20:17 (count = 3), RegionEntry +Segment at 20:22 (count = 0), Skipped +Segment at 21:9 (count = 3), RegionEntry +Segment at 22:6 (count = 0), Skipped +Segment at 33:42 (count = 1), RegionEntry +Segment at 36:10 (count = 0), Skipped +Segment at 41:37 (count = 1), RegionEntry +Segment at 41:41 (count = 0), Skipped +Segment at 42:13 (count = 1), RegionEntry +Segment at 43:10 (count = 0), Skipped +Segment at 48:8 (count = 1), RegionEntry +Segment at 48:15 (count = 0), Skipped +Segment at 48:16 (count = 1), RegionEntry +Segment at 50:6 (count = 0), RegionEntry +Segment at 50:7 (count = 0), Skipped +Segment at 52:9 (count = 1), RegionEntry +Segment at 57:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt new file mode 100644 index 0000000000000..dd93c3a9392c9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt @@ -0,0 +1,138 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/lazy_boolean.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/lazy_boolean +Counter in file 0 7:9 -> 9:42, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 14:6, #2 +Counter in file 0 14:6 -> 14:7, #3 +Counter in file 0 16:9 -> 16:17, #4 +Counter in file 0 18:13 -> 18:18, #5 +Counter in file 0 20:13 -> 20:18, #6 +Counter in file 0 20:18 -> 20:19, #7 +Counter in file 0 20:18 -> 20:19, #8 +Counter in file 0 23:9 -> 23:17, #9 +Counter in file 0 25:13 -> 25:18, (#4 + 0) +Counter in file 0 27:13 -> 27:18, #10 +Counter in file 0 27:18 -> 27:19, #11 +Counter in file 0 27:18 -> 27:19, #12 +Counter in file 0 29:9 -> 29:17, #13 +Counter in file 0 29:20 -> 29:25, (#9 + 0) +Counter in file 0 29:29 -> 29:34, #14 +Counter in file 0 29:34 -> 29:35, #15 +Counter in file 0 29:34 -> 29:35, #16 +Counter in file 0 30:9 -> 30:17, #17 +Counter in file 0 30:20 -> 30:25, (#13 + 0) +Counter in file 0 30:29 -> 30:34, #18 +Counter in file 0 30:34 -> 30:35, #19 +Counter in file 0 30:34 -> 30:35, #20 +Counter in file 0 33:9 -> 34:16, (#17 + 0) +Counter in file 0 35:5 -> 38:6, #21 +Counter in file 0 38:6 -> 38:7, #22 +Counter in file 0 41:9 -> 41:16, #23 +Counter in file 0 42:5 -> 45:6, #24 +Counter in file 0 47:5 -> 50:6, #25 +Counter in file 0 50:6 -> 50:7, (#24 + 0) +Counter in file 0 52:8 -> 52:16, #26 +Counter in file 0 52:17 -> 54:6, #27 +Counter in file 0 54:6 -> 54:7, #28 +Counter in file 0 56:8 -> 56:15, #29 +Counter in file 0 56:16 -> 58:6, #30 +Counter in file 0 58:12 -> 60:6, #31 +Counter in file 0 60:6 -> 60:7, (#30 + 0) +Counter in file 0 61:1 -> 61:2, #32 +Emitting segments for file: ../coverage/lazy_boolean.rs +Combined regions: + 7:9 -> 9:42 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 14:6 (count=1) + 14:6 -> 14:7 (count=0) + 16:9 -> 16:17 (count=1) + 18:13 -> 18:18 (count=1) + 20:13 -> 20:18 (count=0) + 20:18 -> 20:19 (count=1) + 23:9 -> 23:17 (count=1) + 25:13 -> 25:18 (count=1) + 27:13 -> 27:18 (count=1) + 27:18 -> 27:19 (count=1) + 29:9 -> 29:17 (count=1) + 29:20 -> 29:25 (count=1) + 29:29 -> 29:34 (count=1) + 29:34 -> 29:35 (count=1) + 30:9 -> 30:17 (count=1) + 30:20 -> 30:25 (count=1) + 30:29 -> 30:34 (count=0) + 30:34 -> 30:35 (count=1) + 33:9 -> 34:16 (count=1) + 35:5 -> 38:6 (count=0) + 38:6 -> 38:7 (count=1) + 41:9 -> 41:16 (count=1) + 42:5 -> 45:6 (count=1) + 47:5 -> 50:6 (count=0) + 50:6 -> 50:7 (count=1) + 52:8 -> 52:16 (count=1) + 52:17 -> 54:6 (count=0) + 54:6 -> 54:7 (count=1) + 56:8 -> 56:15 (count=1) + 56:16 -> 58:6 (count=1) + 58:12 -> 60:6 (count=0) + 60:6 -> 60:7 (count=1) + 61:1 -> 61:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:42 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 14:6 (count = 0), RegionEntry +Segment at 14:7 (count = 0), Skipped +Segment at 16:9 (count = 1), RegionEntry +Segment at 16:17 (count = 0), Skipped +Segment at 18:13 (count = 1), RegionEntry +Segment at 18:18 (count = 0), Skipped +Segment at 20:13 (count = 0), RegionEntry +Segment at 20:18 (count = 1), RegionEntry +Segment at 20:19 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 23:17 (count = 0), Skipped +Segment at 25:13 (count = 1), RegionEntry +Segment at 25:18 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:18 (count = 1), RegionEntry +Segment at 27:19 (count = 0), Skipped +Segment at 29:9 (count = 1), RegionEntry +Segment at 29:17 (count = 0), Skipped +Segment at 29:20 (count = 1), RegionEntry +Segment at 29:25 (count = 0), Skipped +Segment at 29:29 (count = 1), RegionEntry +Segment at 29:34 (count = 1), RegionEntry +Segment at 29:35 (count = 0), Skipped +Segment at 30:9 (count = 1), RegionEntry +Segment at 30:17 (count = 0), Skipped +Segment at 30:20 (count = 1), RegionEntry +Segment at 30:25 (count = 0), Skipped +Segment at 30:29 (count = 0), RegionEntry +Segment at 30:34 (count = 1), RegionEntry +Segment at 30:35 (count = 0), Skipped +Segment at 33:9 (count = 1), RegionEntry +Segment at 34:16 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 38:6 (count = 1), RegionEntry +Segment at 38:7 (count = 0), Skipped +Segment at 41:9 (count = 1), RegionEntry +Segment at 41:16 (count = 0), Skipped +Segment at 42:5 (count = 1), RegionEntry +Segment at 45:6 (count = 0), Skipped +Segment at 47:5 (count = 0), RegionEntry +Segment at 50:6 (count = 1), RegionEntry +Segment at 50:7 (count = 0), Skipped +Segment at 52:8 (count = 1), RegionEntry +Segment at 52:16 (count = 0), Skipped +Segment at 52:17 (count = 0), RegionEntry +Segment at 54:6 (count = 1), RegionEntry +Segment at 54:7 (count = 0), Skipped +Segment at 56:8 (count = 1), RegionEntry +Segment at 56:15 (count = 0), Skipped +Segment at 56:16 (count = 1), RegionEntry +Segment at 58:6 (count = 0), Skipped +Segment at 58:12 (count = 0), RegionEntry +Segment at 60:6 (count = 1), RegionEntry +Segment at 60:7 (count = 0), Skipped +Segment at 61:1 (count = 1), RegionEntry +Segment at 61:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt new file mode 100644 index 0000000000000..df16c54617c43 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt @@ -0,0 +1,7 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loop_break_value.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loop_break_value +Counter in file 0 3:11 -> 13:2, #1 +Emitting segments for file: ../coverage/loop_break_value.rs +Combined regions: + 3:11 -> 13:2 (count=1) +Segment at 3:11 (count = 1), RegionEntry +Segment at 13:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt new file mode 100644 index 0000000000000..d6e4403268a1d --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt @@ -0,0 +1,39 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches +Counter in file 0 10:12 -> 10:16, #1 +Counter in file 0 11:16 -> 11:21, #2 +Counter in file 0 14:14 -> 14:15, #6 +Counter in file 0 15:13 -> 15:31, #7 +Counter in file 0 15:31 -> 15:32, #8 +Counter in file 0 17:10 -> 17:11, #10 +Counter in file 0 18:9 -> 18:15, #11 +Counter in file 0 19:5 -> 19:6, #12 +Counter in file 0 19:5 -> 19:6, (#8 + 0) +Counter in file 0 22:11 -> 25:2, #1 +Emitting segments for file: ../coverage/loops_and_branches.rs +Combined regions: + 10:12 -> 10:16 (count=1) + 11:16 -> 11:21 (count=1) + 14:14 -> 14:15 (count=1) + 15:13 -> 15:31 (count=1) + 15:31 -> 15:32 (count=0) + 17:10 -> 17:11 (count=1) + 18:9 -> 18:15 (count=1) + 19:5 -> 19:6 (count=1) + 22:11 -> 25:2 (count=1) +Segment at 10:12 (count = 1), RegionEntry +Segment at 10:16 (count = 0), Skipped +Segment at 11:16 (count = 1), RegionEntry +Segment at 11:21 (count = 0), Skipped +Segment at 14:14 (count = 1), RegionEntry +Segment at 14:15 (count = 0), Skipped +Segment at 15:13 (count = 1), RegionEntry +Segment at 15:31 (count = 0), RegionEntry +Segment at 15:32 (count = 0), Skipped +Segment at 17:10 (count = 1), RegionEntry +Segment at 17:11 (count = 0), Skipped +Segment at 18:9 (count = 1), RegionEntry +Segment at 18:15 (count = 0), Skipped +Segment at 19:5 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped +Segment at 22:11 (count = 1), RegionEntry +Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt new file mode 100644 index 0000000000000..eec4aec79e6b5 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt @@ -0,0 +1,76 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops +Counter in file 0 2:9 -> 3:27, #1 +Counter in file 0 5:19 -> 5:32, #2 +Counter in file 0 6:13 -> 7:24, #3 +Counter in file 0 8:13 -> 8:14, #4 +Counter in file 0 8:18 -> 8:23, #5 +Counter in file 0 9:16 -> 9:22, (#4 + 0) +Counter in file 0 10:17 -> 10:22, #6 +Counter in file 0 12:13 -> 12:19, #7 +Counter in file 0 13:13 -> 13:19, #8 +Counter in file 0 14:16 -> 14:22, (#8 + 0) +Counter in file 0 15:17 -> 16:27, #9 +Counter in file 0 17:21 -> 17:33, #10 +Counter in file 0 19:21 -> 21:14, #11 +Counter in file 0 21:14 -> 21:15, #12 +Counter in file 0 22:10 -> 22:11, #13 +Counter in file 0 22:10 -> 22:11, (#3 + 0) +Counter in file 0 23:9 -> 23:23, #14 +Counter in file 0 24:6 -> 24:7, #15 +Counter in file 0 24:6 -> 24:7, (#1 + 0) +Counter in file 0 25:1 -> 25:2, #16 +Emitting segments for file: ../coverage/nested_loops.rs +Combined regions: + 2:9 -> 3:27 (count=1) + 5:19 -> 5:32 (count=1) + 6:13 -> 7:24 (count=1) + 8:13 -> 8:14 (count=3) + 8:18 -> 8:23 (count=3) + 9:16 -> 9:22 (count=3) + 10:17 -> 10:22 (count=0) + 12:13 -> 12:19 (count=3) + 13:13 -> 13:19 (count=3) + 14:16 -> 14:22 (count=3) + 15:17 -> 16:27 (count=1) + 17:21 -> 17:33 (count=1) + 19:21 -> 21:14 (count=0) + 21:14 -> 21:15 (count=2) + 22:10 -> 22:11 (count=3) + 23:9 -> 23:23 (count=0) + 24:6 -> 24:7 (count=1) + 25:1 -> 25:2 (count=1) +Segment at 2:9 (count = 1), RegionEntry +Segment at 3:27 (count = 0), Skipped +Segment at 5:19 (count = 1), RegionEntry +Segment at 5:32 (count = 0), Skipped +Segment at 6:13 (count = 1), RegionEntry +Segment at 7:24 (count = 0), Skipped +Segment at 8:13 (count = 3), RegionEntry +Segment at 8:14 (count = 0), Skipped +Segment at 8:18 (count = 3), RegionEntry +Segment at 8:23 (count = 0), Skipped +Segment at 9:16 (count = 3), RegionEntry +Segment at 9:22 (count = 0), Skipped +Segment at 10:17 (count = 0), RegionEntry +Segment at 10:22 (count = 0), Skipped +Segment at 12:13 (count = 3), RegionEntry +Segment at 12:19 (count = 0), Skipped +Segment at 13:13 (count = 3), RegionEntry +Segment at 13:19 (count = 0), Skipped +Segment at 14:16 (count = 3), RegionEntry +Segment at 14:22 (count = 0), Skipped +Segment at 15:17 (count = 1), RegionEntry +Segment at 16:27 (count = 0), Skipped +Segment at 17:21 (count = 1), RegionEntry +Segment at 17:33 (count = 0), Skipped +Segment at 19:21 (count = 0), RegionEntry +Segment at 21:14 (count = 2), RegionEntry +Segment at 21:15 (count = 0), Skipped +Segment at 22:10 (count = 3), RegionEntry +Segment at 22:11 (count = 0), Skipped +Segment at 23:9 (count = 0), RegionEntry +Segment at 23:23 (count = 0), Skipped +Segment at 24:6 (count = 1), RegionEntry +Segment at 24:7 (count = 0), Skipped +Segment at 25:1 (count = 1), RegionEntry +Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt new file mode 100644 index 0000000000000..d2a68ab32022d --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -0,0 +1,28 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/partial_eq_counter_without_region +Counter in file 0 7:5 -> 7:6, #1 +Counter in file 0 21:11 -> 26:2, #1 +Counter in file 0 4:17 -> 4:22, #1 +Counter in file 0 13:9 -> 18:6, #1 +Counter in file 0 4:39 -> 4:40, #1 +Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 8:5 -> 8:17, #1 +Emitting segments for file: ../coverage/partial_eq_counter_without_region.rs +Combined regions: + 4:17 -> 4:22 (count=2) + 4:39 -> 4:40 (count=1) + 4:48 -> 4:49 (count=1) + 7:5 -> 7:6 (count=1) + 13:9 -> 18:6 (count=2) + 21:11 -> 26:2 (count=1) +Segment at 4:17 (count = 2), RegionEntry +Segment at 4:22 (count = 0), Skipped +Segment at 4:39 (count = 1), RegionEntry +Segment at 4:40 (count = 0), Skipped +Segment at 4:48 (count = 1), RegionEntry +Segment at 4:49 (count = 0), Skipped +Segment at 7:5 (count = 1), RegionEntry +Segment at 7:6 (count = 0), Skipped +Segment at 13:9 (count = 2), RegionEntry +Segment at 18:6 (count = 0), Skipped +Segment at 21:11 (count = 1), RegionEntry +Segment at 26:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt new file mode 100644 index 0000000000000..d828e40ca3fa6 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt @@ -0,0 +1,38 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_loop +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 12:9 -> 12:16, (#1 + 0) +Counter in file 0 13:5 -> 18:6, #2 +Counter in file 0 18:6 -> 18:7, #3 +Counter in file 0 23:13 -> 25:14, #4 +Counter in file 0 27:13 -> 27:18, #5 +Counter in file 0 30:9 -> 32:10, #6 +Counter in file 0 34:6 -> 34:7, #7 +Counter in file 0 35:1 -> 35:2, (#5 + 0) +Emitting segments for file: ../coverage/simple_loop.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 12:9 -> 12:16 (count=1) + 13:5 -> 18:6 (count=1) + 18:6 -> 18:7 (count=0) + 23:13 -> 25:14 (count=11) + 27:13 -> 27:18 (count=1) + 30:9 -> 32:10 (count=10) + 34:6 -> 34:7 (count=1) + 35:1 -> 35:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 12:9 (count = 1), RegionEntry +Segment at 12:16 (count = 0), Skipped +Segment at 13:5 (count = 1), RegionEntry +Segment at 18:6 (count = 0), RegionEntry +Segment at 18:7 (count = 0), Skipped +Segment at 23:13 (count = 11), RegionEntry +Segment at 25:14 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:18 (count = 0), Skipped +Segment at 30:9 (count = 10), RegionEntry +Segment at 32:10 (count = 0), Skipped +Segment at 34:6 (count = 1), RegionEntry +Segment at 34:7 (count = 0), Skipped +Segment at 35:1 (count = 1), RegionEntry +Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt new file mode 100644 index 0000000000000..e7932e0be0473 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt @@ -0,0 +1,58 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_match.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_match +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 12:6, #2 +Counter in file 0 12:6 -> 12:7, #3 +Counter in file 0 15:9 -> 15:10, #4 +Counter in file 0 17:9 -> 17:13, #5 +Counter in file 0 22:13 -> 22:22, (#4 + 0) +Counter in file 0 24:13 -> 24:14, #6 +Counter in file 0 26:17 -> 28:18, (#4 + 0) +Counter in file 0 28:18 -> 28:19, #7 +Counter in file 0 30:13 -> 37:14, (#6 + 0) +Counter in file 0 40:13 -> 40:15, #8 +Counter in file 0 42:6 -> 42:7, #9 +Counter in file 0 42:6 -> 42:7, #10 +Counter in file 0 43:1 -> 43:2, #11 +Emitting segments for file: ../coverage/simple_match.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 12:6 (count=1) + 12:6 -> 12:7 (count=0) + 15:9 -> 15:10 (count=2) + 17:9 -> 17:13 (count=3) + 22:13 -> 22:22 (count=2) + 24:13 -> 24:14 (count=1) + 26:17 -> 28:18 (count=2) + 28:18 -> 28:19 (count=1) + 30:13 -> 37:14 (count=1) + 40:13 -> 40:15 (count=1) + 42:6 -> 42:7 (count=3) + 43:1 -> 43:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 12:6 (count = 0), RegionEntry +Segment at 12:7 (count = 0), Skipped +Segment at 15:9 (count = 2), RegionEntry +Segment at 15:10 (count = 0), Skipped +Segment at 17:9 (count = 3), RegionEntry +Segment at 17:13 (count = 0), Skipped +Segment at 22:13 (count = 2), RegionEntry +Segment at 22:22 (count = 0), Skipped +Segment at 24:13 (count = 1), RegionEntry +Segment at 24:14 (count = 0), Skipped +Segment at 26:17 (count = 2), RegionEntry +Segment at 28:18 (count = 1), RegionEntry +Segment at 28:19 (count = 0), Skipped +Segment at 30:13 (count = 1), RegionEntry +Segment at 37:14 (count = 0), Skipped +Segment at 40:13 (count = 1), RegionEntry +Segment at 40:15 (count = 0), Skipped +Segment at 42:6 (count = 3), RegionEntry +Segment at 42:7 (count = 0), Skipped +Segment at 43:1 (count = 1), RegionEntry +Segment at 43:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt new file mode 100644 index 0000000000000..a690874e3c007 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt @@ -0,0 +1,11 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop +Counter in file 0 2:8 -> 2:13, #1 +Counter in file 0 5:1 -> 5:2, #4 +Emitting segments for file: ../coverage/tight_infinite_loop.rs +Combined regions: + 2:8 -> 2:13 (count=1) + 5:1 -> 5:2 (count=1) +Segment at 2:8 (count = 1), RegionEntry +Segment at 2:13 (count = 0), Skipped +Segment at 5:1 (count = 1), RegionEntry +Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt new file mode 100644 index 0000000000000..d510223417aac --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt @@ -0,0 +1,72 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result +Counter in file 0 13:9 -> 14:23, #1 +Counter in file 0 17:9 -> 17:10, #2 +Counter in file 0 19:9 -> 19:14, #3 +Counter in file 0 21:9 -> 25:26, #4 +Counter in file 0 27:13 -> 27:41, #5 +Counter in file 0 27:41 -> 27:42, #6 +Counter in file 0 31:13 -> 31:42, #7 +Counter in file 0 31:42 -> 31:43, #8 +Counter in file 0 32:10 -> 32:11, #9 +Counter in file 0 32:10 -> 32:11, #10 +Counter in file 0 33:6 -> 33:7, #11 +Counter in file 0 33:6 -> 33:7, (#1 + 0) +Counter in file 0 34:5 -> 34:11, #12 +Counter in file 0 35:1 -> 35:2, #13 +Counter in file 0 35:1 -> 35:2, #14 +Counter in file 0 5:8 -> 5:20, #1 +Counter in file 0 6:9 -> 6:16, #2 +Counter in file 0 8:9 -> 8:15, #3 +Counter in file 0 9:6 -> 9:7, (#2 + 0) +Counter in file 0 10:1 -> 10:2, #4 +Emitting segments for file: ../coverage/try_error_result.rs +Combined regions: + 5:8 -> 5:20 (count=6) + 6:9 -> 6:16 (count=1) + 8:9 -> 8:15 (count=5) + 9:6 -> 9:7 (count=1) + 10:1 -> 10:2 (count=6) + 13:9 -> 14:23 (count=1) + 17:9 -> 17:10 (count=6) + 19:9 -> 19:14 (count=6) + 21:9 -> 25:26 (count=6) + 27:13 -> 27:41 (count=1) + 27:41 -> 27:42 (count=1) + 31:13 -> 31:42 (count=5) + 31:42 -> 31:43 (count=0) + 32:10 -> 32:11 (count=5) + 33:6 -> 33:7 (count=6) + 34:5 -> 34:11 (count=0) + 35:1 -> 35:2 (count=2) +Segment at 5:8 (count = 6), RegionEntry +Segment at 5:20 (count = 0), Skipped +Segment at 6:9 (count = 1), RegionEntry +Segment at 6:16 (count = 0), Skipped +Segment at 8:9 (count = 5), RegionEntry +Segment at 8:15 (count = 0), Skipped +Segment at 9:6 (count = 1), RegionEntry +Segment at 9:7 (count = 0), Skipped +Segment at 10:1 (count = 6), RegionEntry +Segment at 10:2 (count = 0), Skipped +Segment at 13:9 (count = 1), RegionEntry +Segment at 14:23 (count = 0), Skipped +Segment at 17:9 (count = 6), RegionEntry +Segment at 17:10 (count = 0), Skipped +Segment at 19:9 (count = 6), RegionEntry +Segment at 19:14 (count = 0), Skipped +Segment at 21:9 (count = 6), RegionEntry +Segment at 25:26 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:41 (count = 1), RegionEntry +Segment at 27:42 (count = 0), Skipped +Segment at 31:13 (count = 5), RegionEntry +Segment at 31:42 (count = 0), RegionEntry +Segment at 31:43 (count = 0), Skipped +Segment at 32:10 (count = 5), RegionEntry +Segment at 32:11 (count = 0), Skipped +Segment at 33:6 (count = 6), RegionEntry +Segment at 33:7 (count = 0), Skipped +Segment at 34:5 (count = 0), RegionEntry +Segment at 34:11 (count = 0), Skipped +Segment at 35:1 (count = 2), RegionEntry +Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt new file mode 100644 index 0000000000000..0fb135b2cc994 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt @@ -0,0 +1,240 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/various_conditions.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/various_conditions +Counter in file 0 4:9 -> 4:26, #1 +Counter in file 0 5:8 -> 5:12, (#1 + 0) +Counter in file 0 5:13 -> 7:6, #2 +Counter in file 0 10:9 -> 10:10, #4 +Counter in file 0 10:16 -> 10:29, #5 +Counter in file 0 11:9 -> 12:10, #6 +Counter in file 0 13:15 -> 13:28, #7 +Counter in file 0 14:12 -> 14:25, #8 +Counter in file 0 14:29 -> 14:42, #9 +Counter in file 0 14:42 -> 14:43, #10 +Counter in file 0 14:42 -> 14:43, #11 +Counter in file 0 14:46 -> 14:60, #12 +Counter in file 0 14:60 -> 14:61, #13 +Counter in file 0 14:60 -> 14:61, #14 +Counter in file 0 14:61 -> 16:10, #15 +Counter in file 0 16:10 -> 16:11, #16 +Counter in file 0 17:9 -> 18:18, #17 +Counter in file 0 20:9 -> 20:15, #18 +Counter in file 0 23:9 -> 23:26, (#4 + 0) +Counter in file 0 24:8 -> 24:12, (#4 + 0) +Counter in file 0 24:13 -> 26:6, #19 +Counter in file 0 28:8 -> 28:21, #21 +Counter in file 0 29:9 -> 29:23, #22 +Counter in file 0 30:15 -> 30:28, #23 +Counter in file 0 31:12 -> 31:25, #24 +Counter in file 0 31:29 -> 31:42, #25 +Counter in file 0 31:42 -> 31:43, #26 +Counter in file 0 31:42 -> 31:43, #27 +Counter in file 0 31:46 -> 31:60, #28 +Counter in file 0 31:60 -> 31:61, #29 +Counter in file 0 31:60 -> 31:61, #30 +Counter in file 0 31:61 -> 33:10, #31 +Counter in file 0 33:10 -> 33:11, #32 +Counter in file 0 34:9 -> 34:23, #33 +Counter in file 0 36:9 -> 36:15, #34 +Counter in file 0 39:9 -> 39:26, #35 +Counter in file 0 40:8 -> 40:12, (#35 + 0) +Counter in file 0 40:13 -> 42:6, #36 +Counter in file 0 44:9 -> 44:10, #38 +Counter in file 0 44:16 -> 44:29, #39 +Counter in file 0 45:9 -> 45:23, #40 +Counter in file 0 46:15 -> 46:28, #41 +Counter in file 0 47:12 -> 47:25, #42 +Counter in file 0 47:29 -> 47:42, #43 +Counter in file 0 47:42 -> 47:43, #44 +Counter in file 0 47:42 -> 47:43, #45 +Counter in file 0 47:46 -> 47:60, #46 +Counter in file 0 47:60 -> 47:61, #47 +Counter in file 0 47:60 -> 47:61, #48 +Counter in file 0 47:61 -> 49:10, #49 +Counter in file 0 49:10 -> 49:11, #50 +Counter in file 0 50:9 -> 50:23, #51 +Counter in file 0 52:13 -> 54:15, #52 +Counter in file 0 57:9 -> 57:10, #53 +Counter in file 0 57:16 -> 57:29, (#38 + 0) +Counter in file 0 58:9 -> 58:23, #54 +Counter in file 0 59:15 -> 59:28, #55 +Counter in file 0 60:12 -> 60:25, #56 +Counter in file 0 60:29 -> 60:42, #57 +Counter in file 0 60:42 -> 60:43, #58 +Counter in file 0 60:42 -> 60:43, #59 +Counter in file 0 60:46 -> 60:60, #60 +Counter in file 0 60:60 -> 60:61, #61 +Counter in file 0 60:60 -> 60:61, #62 +Counter in file 0 60:61 -> 62:10, #63 +Counter in file 0 62:10 -> 62:11, #64 +Counter in file 0 63:9 -> 63:23, #65 +Counter in file 0 65:9 -> 65:15, #66 +Counter in file 0 67:1 -> 67:2, #67 +Counter in file 0 67:1 -> 67:2, #68 +Emitting segments for file: ../coverage/various_conditions.rs +Combined regions: + 4:9 -> 4:26 (count=1) + 5:8 -> 5:12 (count=1) + 5:13 -> 7:6 (count=1) + 10:9 -> 10:10 (count=1) + 10:16 -> 10:29 (count=1) + 11:9 -> 12:10 (count=1) + 13:15 -> 13:28 (count=0) + 14:12 -> 14:25 (count=0) + 14:29 -> 14:42 (count=0) + 14:42 -> 14:43 (count=0) + 14:46 -> 14:60 (count=0) + 14:60 -> 14:61 (count=0) + 14:61 -> 16:10 (count=0) + 16:10 -> 16:11 (count=0) + 17:9 -> 18:18 (count=0) + 20:9 -> 20:15 (count=0) + 23:9 -> 23:26 (count=1) + 24:8 -> 24:12 (count=1) + 24:13 -> 26:6 (count=1) + 28:8 -> 28:21 (count=1) + 29:9 -> 29:23 (count=1) + 30:15 -> 30:28 (count=0) + 31:12 -> 31:25 (count=0) + 31:29 -> 31:42 (count=0) + 31:42 -> 31:43 (count=0) + 31:46 -> 31:60 (count=0) + 31:60 -> 31:61 (count=0) + 31:61 -> 33:10 (count=0) + 33:10 -> 33:11 (count=0) + 34:9 -> 34:23 (count=0) + 36:9 -> 36:15 (count=0) + 39:9 -> 39:26 (count=1) + 40:8 -> 40:12 (count=1) + 40:13 -> 42:6 (count=1) + 44:9 -> 44:10 (count=0) + 44:16 -> 44:29 (count=1) + 45:9 -> 45:23 (count=0) + 46:15 -> 46:28 (count=1) + 47:12 -> 47:25 (count=0) + 47:29 -> 47:42 (count=0) + 47:42 -> 47:43 (count=0) + 47:46 -> 47:60 (count=0) + 47:60 -> 47:61 (count=0) + 47:61 -> 49:10 (count=0) + 49:10 -> 49:11 (count=0) + 50:9 -> 50:23 (count=0) + 52:13 -> 54:15 (count=1) + 57:9 -> 57:10 (count=0) + 57:16 -> 57:29 (count=0) + 58:9 -> 58:23 (count=0) + 59:15 -> 59:28 (count=0) + 60:12 -> 60:25 (count=0) + 60:29 -> 60:42 (count=0) + 60:42 -> 60:43 (count=0) + 60:46 -> 60:60 (count=0) + 60:60 -> 60:61 (count=0) + 60:61 -> 62:10 (count=0) + 62:10 -> 62:11 (count=0) + 63:9 -> 63:23 (count=0) + 65:9 -> 65:15 (count=0) + 67:1 -> 67:2 (count=2) +Segment at 4:9 (count = 1), RegionEntry +Segment at 4:26 (count = 0), Skipped +Segment at 5:8 (count = 1), RegionEntry +Segment at 5:12 (count = 0), Skipped +Segment at 5:13 (count = 1), RegionEntry +Segment at 7:6 (count = 0), Skipped +Segment at 10:9 (count = 1), RegionEntry +Segment at 10:10 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 10:29 (count = 0), Skipped +Segment at 11:9 (count = 1), RegionEntry +Segment at 12:10 (count = 0), Skipped +Segment at 13:15 (count = 0), RegionEntry +Segment at 13:28 (count = 0), Skipped +Segment at 14:12 (count = 0), RegionEntry +Segment at 14:25 (count = 0), Skipped +Segment at 14:29 (count = 0), RegionEntry +Segment at 14:42 (count = 0), RegionEntry +Segment at 14:43 (count = 0), Skipped +Segment at 14:46 (count = 0), RegionEntry +Segment at 14:60 (count = 0), RegionEntry +Segment at 14:61 (count = 0), RegionEntry +Segment at 16:10 (count = 0), RegionEntry +Segment at 16:11 (count = 0), Skipped +Segment at 17:9 (count = 0), RegionEntry +Segment at 18:18 (count = 0), Skipped +Segment at 20:9 (count = 0), RegionEntry +Segment at 20:15 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 23:26 (count = 0), Skipped +Segment at 24:8 (count = 1), RegionEntry +Segment at 24:12 (count = 0), Skipped +Segment at 24:13 (count = 1), RegionEntry +Segment at 26:6 (count = 0), Skipped +Segment at 28:8 (count = 1), RegionEntry +Segment at 28:21 (count = 0), Skipped +Segment at 29:9 (count = 1), RegionEntry +Segment at 29:23 (count = 0), Skipped +Segment at 30:15 (count = 0), RegionEntry +Segment at 30:28 (count = 0), Skipped +Segment at 31:12 (count = 0), RegionEntry +Segment at 31:25 (count = 0), Skipped +Segment at 31:29 (count = 0), RegionEntry +Segment at 31:42 (count = 0), RegionEntry +Segment at 31:43 (count = 0), Skipped +Segment at 31:46 (count = 0), RegionEntry +Segment at 31:60 (count = 0), RegionEntry +Segment at 31:61 (count = 0), RegionEntry +Segment at 33:10 (count = 0), RegionEntry +Segment at 33:11 (count = 0), Skipped +Segment at 34:9 (count = 0), RegionEntry +Segment at 34:23 (count = 0), Skipped +Segment at 36:9 (count = 0), RegionEntry +Segment at 36:15 (count = 0), Skipped +Segment at 39:9 (count = 1), RegionEntry +Segment at 39:26 (count = 0), Skipped +Segment at 40:8 (count = 1), RegionEntry +Segment at 40:12 (count = 0), Skipped +Segment at 40:13 (count = 1), RegionEntry +Segment at 42:6 (count = 0), Skipped +Segment at 44:9 (count = 0), RegionEntry +Segment at 44:10 (count = 0), Skipped +Segment at 44:16 (count = 1), RegionEntry +Segment at 44:29 (count = 0), Skipped +Segment at 45:9 (count = 0), RegionEntry +Segment at 45:23 (count = 0), Skipped +Segment at 46:15 (count = 1), RegionEntry +Segment at 46:28 (count = 0), Skipped +Segment at 47:12 (count = 0), RegionEntry +Segment at 47:25 (count = 0), Skipped +Segment at 47:29 (count = 0), RegionEntry +Segment at 47:42 (count = 0), RegionEntry +Segment at 47:43 (count = 0), Skipped +Segment at 47:46 (count = 0), RegionEntry +Segment at 47:60 (count = 0), RegionEntry +Segment at 47:61 (count = 0), RegionEntry +Segment at 49:10 (count = 0), RegionEntry +Segment at 49:11 (count = 0), Skipped +Segment at 50:9 (count = 0), RegionEntry +Segment at 50:23 (count = 0), Skipped +Segment at 52:13 (count = 1), RegionEntry +Segment at 54:15 (count = 0), Skipped +Segment at 57:9 (count = 0), RegionEntry +Segment at 57:10 (count = 0), Skipped +Segment at 57:16 (count = 0), RegionEntry +Segment at 57:29 (count = 0), Skipped +Segment at 58:9 (count = 0), RegionEntry +Segment at 58:23 (count = 0), Skipped +Segment at 59:15 (count = 0), RegionEntry +Segment at 59:28 (count = 0), Skipped +Segment at 60:12 (count = 0), RegionEntry +Segment at 60:25 (count = 0), Skipped +Segment at 60:29 (count = 0), RegionEntry +Segment at 60:42 (count = 0), RegionEntry +Segment at 60:43 (count = 0), Skipped +Segment at 60:46 (count = 0), RegionEntry +Segment at 60:60 (count = 0), RegionEntry +Segment at 60:61 (count = 0), RegionEntry +Segment at 62:10 (count = 0), RegionEntry +Segment at 62:11 (count = 0), Skipped +Segment at 63:9 (count = 0), RegionEntry +Segment at 63:23 (count = 0), Skipped +Segment at 65:9 (count = 0), RegionEntry +Segment at 65:15 (count = 0), Skipped +Segment at 67:1 (count = 2), RegionEntry +Segment at 67:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt new file mode 100644 index 0000000000000..52c809b53255c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt @@ -0,0 +1,22 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while +Counter in file 0 2:9 -> 2:16, #1 +Counter in file 0 3:11 -> 3:20, #2 +Counter in file 0 3:21 -> 4:6, #3 +Counter in file 0 4:6 -> 4:7, (#3 + 0) +Counter in file 0 5:1 -> 5:2, #4 +Emitting segments for file: ../coverage/while.rs +Combined regions: + 2:9 -> 2:16 (count=1) + 3:11 -> 3:20 (count=1) + 3:21 -> 4:6 (count=0) + 4:6 -> 4:7 (count=0) + 5:1 -> 5:2 (count=1) +Segment at 2:9 (count = 1), RegionEntry +Segment at 2:16 (count = 0), Skipped +Segment at 3:11 (count = 1), RegionEntry +Segment at 3:20 (count = 0), Skipped +Segment at 3:21 (count = 0), RegionEntry +Segment at 4:6 (count = 0), RegionEntry +Segment at 4:7 (count = 0), Skipped +Segment at 5:1 (count = 1), RegionEntry +Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt new file mode 100644 index 0000000000000..30d14f4f987f7 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt @@ -0,0 +1,44 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return +Counter in file 0 5:9 -> 5:27, #1 +Counter in file 0 7:9 -> 9:10, #2 +Counter in file 0 12:13 -> 14:14, #3 +Counter in file 0 18:21 -> 20:22, #4 +Counter in file 0 22:21 -> 22:27, #5 +Counter in file 0 26:21 -> 26:27, #6 +Counter in file 0 27:18 -> 27:19, (#5 + 0) +Counter in file 0 30:9 -> 32:10, #7 +Counter in file 0 35:5 -> 35:11, #8 +Counter in file 0 36:1 -> 36:2, #9 +Counter in file 0 36:1 -> 36:2, #10 +Emitting segments for file: ../coverage/while_early_return.rs +Combined regions: + 5:9 -> 5:27 (count=1) + 7:9 -> 9:10 (count=7) + 12:13 -> 14:14 (count=7) + 18:21 -> 20:22 (count=1) + 22:21 -> 22:27 (count=0) + 26:21 -> 26:27 (count=1) + 27:18 -> 27:19 (count=0) + 30:9 -> 32:10 (count=6) + 35:5 -> 35:11 (count=0) + 36:1 -> 36:2 (count=2) +Segment at 5:9 (count = 1), RegionEntry +Segment at 5:27 (count = 0), Skipped +Segment at 7:9 (count = 7), RegionEntry +Segment at 9:10 (count = 0), Skipped +Segment at 12:13 (count = 7), RegionEntry +Segment at 14:14 (count = 0), Skipped +Segment at 18:21 (count = 1), RegionEntry +Segment at 20:22 (count = 0), Skipped +Segment at 22:21 (count = 0), RegionEntry +Segment at 22:27 (count = 0), Skipped +Segment at 26:21 (count = 1), RegionEntry +Segment at 26:27 (count = 0), Skipped +Segment at 27:18 (count = 0), RegionEntry +Segment at 27:19 (count = 0), Skipped +Segment at 30:9 (count = 6), RegionEntry +Segment at 32:10 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 35:11 (count = 0), Skipped +Segment at 36:1 (count = 2), RegionEntry +Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.closure.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.closure.json index 8c6edae280397..bff55300b3ca3 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.closure.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.closure.json @@ -17,14 +17,14 @@ }, "lines": { "count": 91, - "covered": 75, - "percent": 82.41758241758241 + "covered": 77, + "percent": 84.61538461538461 }, "regions": { - "count": 21, - "covered": 11, - "notcovered": 10, - "percent": 52.38095238095239 + "count": 25, + "covered": 13, + "notcovered": 12, + "percent": 52 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 91, - "covered": 75, - "percent": 82.41758241758241 + "covered": 77, + "percent": 84.61538461538461 }, "regions": { - "count": 21, - "covered": 11, - "notcovered": 10, - "percent": 52.38095238095239 + "count": 25, + "covered": 13, + "notcovered": 12, + "percent": 52 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json index bd2e2d56d4a55..7a7e4c04f0018 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 5, - "covered": 5, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 5, - "covered": 5, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json index a50f4657e20aa..1025cd3de80d2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 7, + "covered": 7, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 7, + "covered": 7, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if.json index 2ff53ad33fa99..84dcc251f3f4b 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 4, + "count": 5, "covered": 4, - "notcovered": 0, - "percent": 100 + "notcovered": 1, + "percent": 80 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 4, + "count": 5, "covered": 4, - "notcovered": 0, - "percent": 100 + "notcovered": 1, + "percent": 80 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json index 36f81ceae19bf..2d2ad1dbe3f71 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 28, - "covered": 19, - "percent": 67.85714285714286 + "count": 29, + "covered": 21, + "percent": 72.41379310344827 }, "regions": { - "count": 7, - "covered": 5, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 71.42857142857143 + "percent": 77.77777777777779 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 28, - "covered": 19, - "percent": 67.85714285714286 + "count": 29, + "covered": 21, + "percent": 72.41379310344827 }, "regions": { - "count": 7, - "covered": 5, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 71.42857142857143 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.inner_items.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.inner_items.json index a24e6a33a3397..c178e7f93476f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.inner_items.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.inner_items.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 13, + "count": 15, "covered": 13, - "notcovered": 0, - "percent": 100 + "notcovered": 2, + "percent": 86.66666666666667 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 13, + "count": 15, "covered": 13, - "notcovered": 0, - "percent": 100 + "notcovered": 2, + "percent": 86.66666666666667 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json index 585346dc32a60..95a1dcd3b8eee 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 21, - "covered": 19, - "percent": 90.47619047619048 + "count": 40, + "covered": 32, + "percent": 80 }, "regions": { - "count": 16, - "covered": 14, - "notcovered": 2, - "percent": 87.5 + "count": 39, + "covered": 28, + "notcovered": 11, + "percent": 71.7948717948718 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 21, - "covered": 19, - "percent": 90.47619047619048 + "count": 40, + "covered": 32, + "percent": 80 }, "regions": { - "count": 16, - "covered": 14, - "notcovered": 2, - "percent": 87.5 + "count": 39, + "covered": 28, + "notcovered": 11, + "percent": 71.7948717948718 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json new file mode 100644 index 0000000000000..aec85cd0329cb --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/loops_and_branches.rs", + "summary": { + "functions": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "instantiations": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "lines": { + "count": 11, + "covered": 11, + "percent": 100 + }, + "regions": { + "count": 10, + "covered": 8, + "notcovered": 2, + "percent": 80 + } + } + } + ], + "totals": { + "functions": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "instantiations": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "lines": { + "count": 11, + "covered": 11, + "percent": 100 + }, + "regions": { + "count": 10, + "covered": 8, + "notcovered": 2, + "percent": 80 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json new file mode 100644 index 0000000000000..dbe4f9ca6fd17 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/nested_loops.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 21, + "covered": 17, + "percent": 80.95238095238095 + }, + "regions": { + "count": 20, + "covered": 16, + "notcovered": 4, + "percent": 80 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 21, + "covered": 17, + "percent": 80.95238095238095 + }, + "regions": { + "count": 20, + "covered": 16, + "notcovered": 4, + "percent": 80 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.partial_eq_counter_without_region.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.partial_eq_counter_without_region.json new file mode 100644 index 0000000000000..779bfe9904ced --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.partial_eq_counter_without_region.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/partial_eq_counter_without_region.rs", + "summary": { + "functions": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "instantiations": { + "count": 8, + "covered": 5, + "percent": 62.5 + }, + "lines": { + "count": 15, + "covered": 15, + "percent": 100 + }, + "regions": { + "count": 6, + "covered": 6, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "totals": { + "functions": { + "count": 5, + "covered": 5, + "percent": 100 + }, + "instantiations": { + "count": 8, + "covered": 5, + "percent": 62.5 + }, + "lines": { + "count": 15, + "covered": 15, + "percent": 100 + }, + "regions": { + "count": 6, + "covered": 6, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_loop.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_loop.json index 38bc96898ea36..ada6bb062dd1e 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_loop.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_loop.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 18, - "covered": 18, + "count": 19, + "covered": 19, "percent": 100 }, "regions": { - "count": 7, - "covered": 7, - "notcovered": 0, - "percent": 100 + "count": 9, + "covered": 8, + "notcovered": 1, + "percent": 88.88888888888889 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 18, - "covered": 18, + "count": 19, + "covered": 19, "percent": 100 }, "regions": { - "count": 7, - "covered": 7, - "notcovered": 0, - "percent": 100 + "count": 9, + "covered": 8, + "notcovered": 1, + "percent": 88.88888888888889 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_match.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_match.json index f9d91d66f1db2..63d1ae74c5f5d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_match.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.simple_match.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 26, - "covered": 26, + "count": 24, + "covered": 24, "percent": 100 }, "regions": { - "count": 9, - "covered": 9, - "notcovered": 0, - "percent": 100 + "count": 15, + "covered": 14, + "notcovered": 1, + "percent": 93.33333333333333 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 26, - "covered": 26, + "count": 24, + "covered": 24, "percent": 100 }, "regions": { - "count": 9, - "covered": 9, - "notcovered": 0, - "percent": 100 + "count": 15, + "covered": 14, + "notcovered": 1, + "percent": 93.33333333333333 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.tight_infinite_loop.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.tight_infinite_loop.json new file mode 100644 index 0000000000000..3fa6821cd1df9 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.tight_infinite_loop.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/tight_infinite_loop.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "regions": { + "count": 2, + "covered": 2, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 2, + "covered": 2, + "percent": 100 + }, + "regions": { + "count": 2, + "covered": 2, + "notcovered": 0, + "percent": 100 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json index e6ef2c1ab899e..e845ee29fa452 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 20, + "covered": 19, + "percent": 95 }, "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 + "count": 20, + "covered": 17, + "notcovered": 3, + "percent": 85 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 16, - "covered": 15, - "percent": 93.75 + "count": 20, + "covered": 19, + "percent": 95 }, "regions": { - "count": 13, - "covered": 12, - "notcovered": 1, - "percent": 92.3076923076923 + "count": 20, + "covered": 17, + "notcovered": 3, + "percent": 85 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json index 410821ea33592..464bb614ea1b1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json @@ -21,10 +21,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 51, + "count": 70, "covered": 19, - "notcovered": 32, - "percent": 37.254901960784316 + "notcovered": 51, + "percent": 27.142857142857142 } } } @@ -46,10 +46,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 51, + "count": 70, "covered": 19, - "notcovered": 32, - "percent": 37.254901960784316 + "notcovered": 51, + "percent": 27.142857142857142 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json new file mode 100644 index 0000000000000..27862087ed567 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json @@ -0,0 +1,59 @@ +{ + "data": [ + { + "files": [ + { + "filename": "../coverage/while.rs", + "summary": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 4, + "covered": 3, + "percent": 75 + }, + "regions": { + "count": 5, + "covered": 3, + "notcovered": 2, + "percent": 60 + } + } + } + ], + "totals": { + "functions": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "instantiations": { + "count": 1, + "covered": 1, + "percent": 100 + }, + "lines": { + "count": 4, + "covered": 3, + "percent": 75 + }, + "regions": { + "count": 5, + "covered": 3, + "notcovered": 2, + "percent": 60 + } + } + } + ], + "type": "llvm.coverage.json.export", + "version": "2.0.1" +} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json index 865b705fa2007..555ac745d5371 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json @@ -17,14 +17,14 @@ }, "lines": { "count": 18, - "covered": 16, - "percent": 88.88888888888889 + "covered": 15, + "percent": 83.33333333333334 }, "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 + "count": 11, + "covered": 8, + "notcovered": 3, + "percent": 72.72727272727273 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 18, - "covered": 16, - "percent": 88.88888888888889 + "covered": 15, + "percent": 83.33333333333334 }, "regions": { - "count": 9, - "covered": 7, - "notcovered": 2, - "percent": 77.77777777777779 + "count": 11, + "covered": 8, + "notcovered": 3, + "percent": 72.72727272727273 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.closure.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.closure.txt index 17054490e9b3c..aef26a62e25fb 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.closure.txt @@ -62,7 +62,7 @@ 62| 1| let mut countdown = 0; 63| 1| if is_false { 64| 0| countdown = 10; - 65| 0| } + 65| 1| } 66| 1| "alt string 3".to_owned() 67| 1| } 68| 1| ) @@ -77,7 +77,7 @@ 77| 1| let mut countdown = 0; 78| 1| if is_false { 79| 0| countdown = 10; - 80| 0| } + 80| 1| } 81| 1| "alt string 4".to_owned() 82| 1| }; 83| 1| println!( diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt index 72aa020ca1691..43592df1059aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt @@ -24,7 +24,7 @@ 24| | let _ = Firework { strength: 1000 }; 25| | 26| | Ok(()) - 27| 1|} + 27| 2|} 28| | 29| |// Expected program output: 30| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt index 86199d7476302..11dc0aa65e2d1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt @@ -57,7 +57,7 @@ 35| | let _ = Firework { strength: 1000 }; 36| | 37| | Ok(()) - 38| 1|} + 38| 2|} 39| | 40| |// Expected program output: 41| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if.txt index bc2f9b108b2f3..85e6440ab3729 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if.txt @@ -25,5 +25,6 @@ 25| 1| 10 26| 1| ; 27| 1| } + ^0 28| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt index 5f899723e2554..64cbc262521bf 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt @@ -20,7 +20,7 @@ 20| 0| countdown 21| 0| = 22| 0| 100 - 23| | } + 23| 1| } 24| | 25| | if 26| 1| is_true @@ -36,6 +36,6 @@ 36| 0| = 37| 0| 100 38| 0| ; - 39| 0| } + 39| 1| } 40| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.inner_items.txt index b13ca83d018f9..4a51f842a4bb2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.inner_items.txt @@ -10,6 +10,7 @@ 10| 1| if is_true { 11| 1| countdown = 10; 12| 1| } + ^0 13| | 14| | mod in_mod { 15| | const IN_MOD_CONST: u32 = 1000; @@ -48,6 +49,7 @@ 48| 1| if is_true { 49| 1| in_func(countdown); 50| 1| } + ^0 51| | 52| 1| let mut val = InStruct { 53| 1| in_struct_field: 101, diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt index ded4369751587..f01f69f2496ee 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt @@ -12,12 +12,14 @@ 12| 1| b = 10; 13| 1| c = 100; 14| 1| } + ^0 15| | let 16| 1| somebool 17| | = 18| 1| a < b 19| | || - 20| 0| b < c + 20| 1| b < c + ^0 21| | ; 22| | let 23| 1| somebool @@ -26,19 +28,38 @@ 26| | || 27| 1| b < c 28| | ; - 29| | let - 30| 1| somebool - 31| | = - 32| 1| a < b - 33| | && - 34| 1| b < c - 35| | ; - 36| | let - 37| 1| somebool - 38| | = - 39| 1| b < a - 40| | && - 41| 0| b < c - 42| | ; - 43| 1|} + 29| 1| let somebool = a < b && b < c; + 30| 1| let somebool = b < a && b < c; + ^0 + 31| | + 32| | if + 33| 1| ! + 34| 1| is_true + 35| 0| { + 36| 0| a = 2 + 37| 0| ; + 38| 1| } + 39| | + 40| | if + 41| 1| is_true + 42| 1| { + 43| 1| b = 30 + 44| 1| ; + 45| 1| } + 46| | else + 47| 0| { + 48| 0| c = 400 + 49| 0| ; + 50| 1| } + 51| | + 52| 1| if !is_true { + 53| 0| a = 2; + 54| 1| } + 55| | + 56| 1| if is_true { + 57| 1| b = 30; + 58| 1| } else { + 59| 0| c = 400; + 60| 1| } + 61| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.loops_and_branches.txt new file mode 100644 index 0000000000000..3a969a6b89869 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.loops_and_branches.txt @@ -0,0 +1,38 @@ + 1| |#![allow(unused_assignments)] + 2| | + 3| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the + 4| |// structure of this `fmt` function. + 5| | + 6| |struct DebugTest; + 7| | + 8| |impl std::fmt::Debug for DebugTest { + 9| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + 10| 1| if true { + 11| 1| if false { + 12| | while true { + 13| | } + 14| 1| } + 15| 1| write!(f, "error")?; + ^0 + 16| | } else { + 17| 1| } + 18| 1| Ok(()) + 19| 1| } + 20| |} + 21| | + 22| 1|fn main() { + 23| 1| let debug_test = DebugTest; + 24| 1| println!("{:?}", debug_test); + 25| 1|} + 26| | + 27| |/* + 28| | + 29| |This is the error message generated, before the issue was fixed: + 30| | + 31| |error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42: + 32| |Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt): + 33| |Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: + 34| |[bcb6, bcb7, bcb9]" } + 35| | + 36| |*/ + diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt new file mode 100644 index 0000000000000..e0545c76f780f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt @@ -0,0 +1,26 @@ + 1| |fn main() { + 2| 1| let is_true = std::env::args().len() == 1; + 3| 1| let mut countdown = 10; + 4| | + 5| 1| 'outer: while countdown > 0 { + 6| 1| let mut a = 100; + 7| 1| let mut b = 100; + 8| 3| for _ in 0..50 { + 9| 3| if a < 30 { + 10| 0| break; + 11| | } + 12| 3| a -= 5; + 13| 3| b -= 5; + 14| 3| if b < 90 { + 15| 1| a -= 10; + 16| 1| if is_true { + 17| 1| break 'outer; + 18| | } else { + 19| 0| a -= 2; + 20| 0| } + 21| 2| } + 22| 3| } + 23| 0| countdown -= 1; + 24| 1| } + 25| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.partial_eq_counter_without_region.txt new file mode 100644 index 0000000000000..e7e4dfb5a86c4 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.partial_eq_counter_without_region.txt @@ -0,0 +1,111 @@ + 1| |// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the + 2| |// structure of this test. + 3| | + 4| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + ^1 ^1 + ------------------ + | Unexecuted instantiation: ::gt + ------------------ + | Unexecuted instantiation: ::le + ------------------ + | Unexecuted instantiation: ::ge + ------------------ + | ::lt: + | 4| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + ------------------ + 5| |pub struct Version { + 6| | major: usize, + 7| 1| minor: usize, + 8| | patch: usize, + 9| |} + 10| | + 11| |impl Version { + 12| | pub fn new(major: usize, minor: usize, patch: usize) -> Self { + 13| 2| Self { + 14| 2| major, + 15| 2| minor, + 16| 2| patch, + 17| 2| } + 18| 2| } + 19| |} + 20| | + 21| 1|fn main() { + 22| 1| let version_3_2_1 = Version::new(3, 2, 1); + 23| 1| let version_3_3_0 = Version::new(3, 3, 0); + 24| 1| + 25| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); + 26| 1|} + 27| | + 28| |/* + 29| | + 30| |This test verifies a bug was fixed that otherwise generated this error: + 31| | + 32| |thread 'rustc' panicked at 'No counters provided the source_hash for function: + 33| | Instance { + 34| | def: Item(WithOptConstParam { + 35| | did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp), + 36| | const_param_did: None + 37| | }), + 38| | substs: [] + 39| | }' + 40| |The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage + 41| |without a code region associated with any `Counter`. Code regions were associated with at least + 42| |one expression, which is allowed, but the `function_source_hash` was only passed to the codegen + 43| |(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the + 44| |`function_source_hash` without a code region, if necessary. + 45| | + 46| |*/ + 47| | + 48| |// FIXME(richkadel): It may be worth investigating why the coverage report for this test produces + 49| |// the following results: + 50| | + 51| |/* + 52| | + 53| |1. Why are their two counts below different characters (first and last) of `PartialOrd`, on line 17? + 54| | + 55| |2. Line 17 is counted twice, but the `::lt` instance shows a line count of 1? Is there a missing + 56| | line count with a different instance? Or was it really only called once? + 57| | + 58| |3. Line 20 shows another line count (of 1) for a line within a `struct` declaration (on only one of + 59| | its 3 fields). I doubt the specific field (`minor`) is relevant, but rather I suspect there's a + 60| | problem computing the file position here, for some reason. + 61| | + 62| | + 63| | 16| | + 64| | 17| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + 65| | ^1 ^1 + 66| |------------------ + 67| ||Unexecuted instantiation: ::gt + 68| |------------------ + 69| ||Unexecuted instantiation: ::le + 70| |------------------ + 71| ||Unexecuted instantiation: ::ge + 72| |------------------ + 73| ||::lt: + 74| || 17| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + 75| |------------------ + 76| | 18| |pub struct Version { + 77| | 19| | major: usize, + 78| | 20| 1| minor: usize, + 79| | 21| | patch: usize, + 80| | 22| |} + 81| | 23| | + 82| | 24| |impl Version { + 83| | 25| | pub fn new(major: usize, minor: usize, patch: usize) -> Self { + 84| | 26| 2| Version { + 85| | 27| 2| major, + 86| | 28| 2| minor, + 87| | 29| 2| patch, + 88| | 30| 2| } + 89| | 31| 2| } + 90| | 32| |} + 91| | 33| | + 92| | 34| 1|fn main() { + 93| | 35| 1| let version_3_2_1 = Version::new(3, 2, 1); + 94| | 36| 1| let version_3_3_0 = Version::new(3, 3, 0); + 95| | 37| 1| + 96| | 38| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version + 97| |_3_3_0); + 98| | 39| 1|} + 99| |*/ + diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_loop.txt index f1acb7c545940..064930dd75c93 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_loop.txt @@ -16,6 +16,7 @@ 16| 1| 10 17| 1| ; 18| 1| } + ^0 19| | 20| | loop 21| | { @@ -31,6 +32,6 @@ 31| 10| -= 32| 10| 1 33| | ; - 34| | } + 34| 1| } 35| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_match.txt index e42f22cd047fc..1f7e71d3eb0e7 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.simple_match.txt @@ -10,22 +10,24 @@ 10| 1| if is_true { 11| 1| countdown = 0; 12| 1| } + ^0 13| | - 14| 3| for - 15| 3| _ + 14| | for + 15| 2| _ 16| | in - 17| 1| 0..2 + 17| 3| 0..2 18| | { 19| | let z 20| | ; 21| | match 22| 2| countdown - 23| 2| { - 24| 2| x - 25| 2| if + 23| | { + 24| 1| x + 25| | if 26| 2| x 27| 2| < 28| 2| 1 + ^1 29| | => 30| 1| { 31| 1| z = countdown @@ -39,6 +41,6 @@ 39| | => 40| 1| {} 41| | } - 42| | } + 42| 3| } 43| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.tight_infinite_loop.txt new file mode 100644 index 0000000000000..e02eac03a6b15 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.tight_infinite_loop.txt @@ -0,0 +1,6 @@ + 1| |fn main() { + 2| 1| if false { + 3| | loop {} + 4| | } + 5| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt index ae288d7d7a000..05d72d0de46e6 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt @@ -6,22 +6,22 @@ 6| 1| Err(()) 7| | } else { 8| 5| Ok(()) - 9| | } + 9| 1| } 10| 6|} 11| | 12| |fn main() -> Result<(),()> { 13| 1| let mut 14| 1| countdown = 10 15| | ; - 16| 6| for + 16| | for 17| 6| _ 18| | in - 19| 1| 0..10 + 19| 6| 0..10 20| | { 21| 6| countdown 22| 6| -= 1 - 23| | ; - 24| | if + 23| 6| ; + 24| 6| if 25| 6| countdown < 5 26| | { 27| 1| call(/*return_error=*/ true)?; @@ -29,8 +29,9 @@ 29| | else 30| | { 31| 5| call(/*return_error=*/ false)?; - 32| | } - 33| | } + ^0 + 32| 5| } + 33| 6| } 34| 0| Ok(()) - 35| 1|} + 35| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt index 173ff4aa4c481..e0efe75043d4a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt @@ -65,5 +65,5 @@ 64| | } else { 65| 0| return; 66| | }; - 67| 1|} + 67| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while.txt new file mode 100644 index 0000000000000..194325b6b9eca --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while.txt @@ -0,0 +1,6 @@ + 1| |fn main() { + 2| 1| let num = 9; + 3| 1| while num >= 10 { + 4| 0| } + 5| 1|} + diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt index 7dce94f25f304..2e0c4022bedb8 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt @@ -3,7 +3,7 @@ 3| | 4| |fn main() -> Result<(),u8> { 5| 1| let mut countdown = 10; - 6| 7| while + 6| | while 7| 7| countdown 8| 7| > 9| 7| 0 @@ -24,7 +24,7 @@ 24| | else 25| | { 26| 1| Err(1) - 27| | } + 27| 0| } 28| | ; 29| | } 30| 6| countdown @@ -33,7 +33,7 @@ 33| | ; 34| | } 35| 0| Ok(()) - 36| 1|} + 36| 2|} 37| | 38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and 39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt new file mode 100644 index 0000000000000..39bf7bad9a1a2 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt @@ -0,0 +1,95 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/closure.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/closure +Counter in file 0 20:21 -> 20:38, #1 +Counter in file 0 21:20 -> 21:28, (#1 + 0) +Counter in file 0 21:29 -> 23:18, #2 +Counter in file 0 23:18 -> 23:19, #3 +Counter in file 0 24:17 -> 25:14, #4 +Counter in file 0 3:11 -> 18:13, #1 +Counter in file 0 25:14 -> 33:9, (#1 + 0) +Counter in file 0 40:6 -> 60:13, (#1 + 0) +Counter in file 0 67:14 -> 75:9, (#1 + 0) +Counter in file 0 82:6 -> 93:2, (#1 + 0) +Counter in file 0 77:13 -> 77:30, #1 +Counter in file 0 78:12 -> 78:20, (#1 + 0) +Counter in file 0 78:21 -> 80:10, #2 +Counter in file 0 80:10 -> 80:11, #3 +Counter in file 0 81:9 -> 82:6, #4 +Counter in file 0 62:21 -> 62:38, #1 +Counter in file 0 63:20 -> 63:28, (#1 + 0) +Counter in file 0 63:29 -> 65:18, #2 +Counter in file 0 65:18 -> 65:19, #3 +Counter in file 0 66:17 -> 67:14, #4 +Counter in file 0 35:13 -> 35:30, #1 +Counter in file 0 36:12 -> 36:20, (#1 + 0) +Counter in file 0 36:21 -> 38:10, #2 +Counter in file 0 38:10 -> 38:11, #3 +Counter in file 0 39:9 -> 40:6, #4 +Emitting segments for file: ../coverage/closure.rs +Combined regions: + 3:11 -> 18:13 (count=1) + 20:21 -> 20:38 (count=0) + 21:20 -> 21:28 (count=0) + 21:29 -> 23:18 (count=0) + 23:18 -> 23:19 (count=0) + 24:17 -> 25:14 (count=0) + 25:14 -> 33:9 (count=1) + 35:13 -> 35:30 (count=0) + 36:12 -> 36:20 (count=0) + 36:21 -> 38:10 (count=0) + 38:10 -> 38:11 (count=0) + 39:9 -> 40:6 (count=0) + 40:6 -> 60:13 (count=1) + 62:21 -> 62:38 (count=1) + 63:20 -> 63:28 (count=1) + 63:29 -> 65:18 (count=0) + 65:18 -> 65:19 (count=1) + 66:17 -> 67:14 (count=1) + 67:14 -> 75:9 (count=1) + 77:13 -> 77:30 (count=1) + 78:12 -> 78:20 (count=1) + 78:21 -> 80:10 (count=0) + 80:10 -> 80:11 (count=1) + 81:9 -> 82:6 (count=1) + 82:6 -> 93:2 (count=1) +Segment at 3:11 (count = 1), RegionEntry +Segment at 18:13 (count = 0), Skipped +Segment at 20:21 (count = 0), RegionEntry +Segment at 20:38 (count = 0), Skipped +Segment at 21:20 (count = 0), RegionEntry +Segment at 21:28 (count = 0), Skipped +Segment at 21:29 (count = 0), RegionEntry +Segment at 23:18 (count = 0), RegionEntry +Segment at 23:19 (count = 0), Skipped +Segment at 24:17 (count = 0), RegionEntry +Segment at 25:14 (count = 1), RegionEntry +Segment at 33:9 (count = 0), Skipped +Segment at 35:13 (count = 0), RegionEntry +Segment at 35:30 (count = 0), Skipped +Segment at 36:12 (count = 0), RegionEntry +Segment at 36:20 (count = 0), Skipped +Segment at 36:21 (count = 0), RegionEntry +Segment at 38:10 (count = 0), RegionEntry +Segment at 38:11 (count = 0), Skipped +Segment at 39:9 (count = 0), RegionEntry +Segment at 40:6 (count = 1), RegionEntry +Segment at 60:13 (count = 0), Skipped +Segment at 62:21 (count = 1), RegionEntry +Segment at 62:38 (count = 0), Skipped +Segment at 63:20 (count = 1), RegionEntry +Segment at 63:28 (count = 0), Skipped +Segment at 63:29 (count = 0), RegionEntry +Segment at 65:18 (count = 1), RegionEntry +Segment at 65:19 (count = 0), Skipped +Segment at 66:17 (count = 1), RegionEntry +Segment at 67:14 (count = 1), RegionEntry +Segment at 75:9 (count = 0), Skipped +Segment at 77:13 (count = 1), RegionEntry +Segment at 77:30 (count = 0), Skipped +Segment at 78:12 (count = 1), RegionEntry +Segment at 78:20 (count = 0), Skipped +Segment at 78:21 (count = 0), RegionEntry +Segment at 80:10 (count = 1), RegionEntry +Segment at 80:11 (count = 0), Skipped +Segment at 81:9 (count = 1), RegionEntry +Segment at 82:6 (count = 1), RegionEntry +Segment at 93:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt new file mode 100644 index 0000000000000..e416a84820a30 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt @@ -0,0 +1,24 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/drop_trait.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/drop_trait +Counter in file 0 9:24 -> 11:6, #1 +Counter in file 0 15:9 -> 17:42, #1 +Counter in file 0 19:8 -> 19:12, (#1 + 0) +Counter in file 0 20:9 -> 21:22, #2 +Counter in file 0 27:1 -> 27:2, #4 +Counter in file 0 27:1 -> 27:2, (#2 + 0) +Emitting segments for file: ../coverage/drop_trait.rs +Combined regions: + 9:24 -> 11:6 (count=2) + 15:9 -> 17:42 (count=1) + 19:8 -> 19:12 (count=1) + 20:9 -> 21:22 (count=1) + 27:1 -> 27:2 (count=2) +Segment at 9:24 (count = 2), RegionEntry +Segment at 11:6 (count = 0), Skipped +Segment at 15:9 (count = 1), RegionEntry +Segment at 17:42 (count = 0), Skipped +Segment at 19:8 (count = 1), RegionEntry +Segment at 19:12 (count = 0), Skipped +Segment at 20:9 (count = 1), RegionEntry +Segment at 21:22 (count = 0), Skipped +Segment at 27:1 (count = 2), RegionEntry +Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt new file mode 100644 index 0000000000000..9e33b48fc29c0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt @@ -0,0 +1,50 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/generics.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/generics +Counter in file 0 17:24 -> 19:6, #1 +Counter in file 0 17:24 -> 19:6, #1 +Counter in file 0 23:9 -> 28:28, #1 +Counter in file 0 30:8 -> 30:12, (#1 + 0) +Counter in file 0 31:9 -> 32:22, #2 +Counter in file 0 38:1 -> 38:2, #4 +Counter in file 0 38:1 -> 38:2, (#2 + 0) +Counter in file 0 10:49 -> 12:6, #1 +Counter in file 0 10:49 -> 12:6, #1 +Emitting segments for file: ../coverage/generics.rs +Combined regions: + 10:49 -> 12:6 (count=3) + 17:24 -> 19:6 (count=2) + 23:9 -> 28:28 (count=1) + 30:8 -> 30:12 (count=1) + 31:9 -> 32:22 (count=1) + 38:1 -> 38:2 (count=2) +Segment at 10:49 (count = 3), RegionEntry +Segment at 12:6 (count = 0), Skipped +Segment at 17:24 (count = 2), RegionEntry +Segment at 19:6 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 28:28 (count = 0), Skipped +Segment at 30:8 (count = 1), RegionEntry +Segment at 30:12 (count = 0), Skipped +Segment at 31:9 (count = 1), RegionEntry +Segment at 32:22 (count = 0), Skipped +Segment at 38:1 (count = 2), RegionEntry +Segment at 38:2 (count = 0), Skipped +Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_ +Combined regions: + 10:49 -> 12:6 (count=2) +Segment at 10:49 (count = 2), RegionEntry +Segment at 12:6 (count = 0), Skipped +Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworklE12set_strengthB2_ +Combined regions: + 10:49 -> 12:6 (count=1) +Segment at 10:49 (count = 1), RegionEntry +Segment at 12:6 (count = 0), Skipped +Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworklENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_ +Combined regions: + 17:24 -> 19:6 (count=1) +Segment at 17:24 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped +Emitting segments for function: _RNvXs_Cs4fqI2P2rA04_8genericsINtB4_8FireworkdENtNtNtCs7f2nZg1zwMz_4core3ops4drop4Drop4dropB4_ +Combined regions: + 17:24 -> 19:6 (count=1) +Segment at 17:24 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt new file mode 100644 index 0000000000000..325e6985e3041 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt @@ -0,0 +1,22 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if +Counter in file 0 8:5 -> 18:10, #1 +Counter in file 0 21:9 -> 21:16, (#1 + 0) +Counter in file 0 22:5 -> 27:6, #2 +Counter in file 0 27:6 -> 27:7, #3 +Counter in file 0 28:1 -> 28:2, #4 +Emitting segments for file: ../coverage/if.rs +Combined regions: + 8:5 -> 18:10 (count=1) + 21:9 -> 21:16 (count=1) + 22:5 -> 27:6 (count=1) + 27:6 -> 27:7 (count=0) + 28:1 -> 28:2 (count=1) +Segment at 8:5 (count = 1), RegionEntry +Segment at 18:10 (count = 0), Skipped +Segment at 21:9 (count = 1), RegionEntry +Segment at 21:16 (count = 0), Skipped +Segment at 22:5 (count = 1), RegionEntry +Segment at 27:6 (count = 0), RegionEntry +Segment at 27:7 (count = 0), Skipped +Segment at 28:1 (count = 1), RegionEntry +Segment at 28:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt new file mode 100644 index 0000000000000..a620bf8ae4a62 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt @@ -0,0 +1,38 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else +Counter in file 0 7:9 -> 11:16, #1 +Counter in file 0 12:5 -> 17:6, #2 +Counter in file 0 20:9 -> 22:16, #3 +Counter in file 0 23:6 -> 23:7, (#2 + 0) +Counter in file 0 26:9 -> 26:16, #4 +Counter in file 0 27:5 -> 32:6, #5 +Counter in file 0 34:5 -> 39:6, #6 +Counter in file 0 39:6 -> 39:7, (#5 + 0) +Counter in file 0 40:1 -> 40:2, #7 +Emitting segments for file: ../coverage/if_else.rs +Combined regions: + 7:9 -> 11:16 (count=1) + 12:5 -> 17:6 (count=1) + 20:9 -> 22:16 (count=0) + 23:6 -> 23:7 (count=1) + 26:9 -> 26:16 (count=1) + 27:5 -> 32:6 (count=1) + 34:5 -> 39:6 (count=0) + 39:6 -> 39:7 (count=1) + 40:1 -> 40:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 11:16 (count = 0), Skipped +Segment at 12:5 (count = 1), RegionEntry +Segment at 17:6 (count = 0), Skipped +Segment at 20:9 (count = 0), RegionEntry +Segment at 22:16 (count = 0), Skipped +Segment at 23:6 (count = 1), RegionEntry +Segment at 23:7 (count = 0), Skipped +Segment at 26:9 (count = 1), RegionEntry +Segment at 26:16 (count = 0), Skipped +Segment at 27:5 (count = 1), RegionEntry +Segment at 32:6 (count = 0), Skipped +Segment at 34:5 (count = 0), RegionEntry +Segment at 39:6 (count = 1), RegionEntry +Segment at 39:7 (count = 0), Skipped +Segment at 40:1 (count = 1), RegionEntry +Segment at 40:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt new file mode 100644 index 0000000000000..ea6db9452a75c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt @@ -0,0 +1,61 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/inner_items.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/inner_items +Counter in file 0 19:13 -> 19:18, #1 +Counter in file 0 20:13 -> 20:14, #2 +Counter in file 0 20:17 -> 20:22, (#1 + 0) +Counter in file 0 21:9 -> 22:6, (#2 + 0) +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 12:6, #2 +Counter in file 0 12:6 -> 12:7, #3 +Counter in file 0 48:8 -> 48:15, #4 +Counter in file 0 48:16 -> 50:6, #5 +Counter in file 0 50:6 -> 50:7, #6 +Counter in file 0 52:9 -> 57:2, #7 +Counter in file 0 33:42 -> 36:10, #1 +Counter in file 0 41:37 -> 41:41, #1 +Counter in file 0 42:13 -> 43:10, #2 +Emitting segments for file: ../coverage/inner_items.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 12:6 (count=1) + 12:6 -> 12:7 (count=0) + 19:13 -> 19:18 (count=3) + 20:13 -> 20:14 (count=3) + 20:17 -> 20:22 (count=3) + 21:9 -> 22:6 (count=3) + 33:42 -> 36:10 (count=1) + 41:37 -> 41:41 (count=1) + 42:13 -> 43:10 (count=1) + 48:8 -> 48:15 (count=1) + 48:16 -> 50:6 (count=1) + 50:6 -> 50:7 (count=0) + 52:9 -> 57:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 12:6 (count = 0), RegionEntry +Segment at 12:7 (count = 0), Skipped +Segment at 19:13 (count = 3), RegionEntry +Segment at 19:18 (count = 0), Skipped +Segment at 20:13 (count = 3), RegionEntry +Segment at 20:14 (count = 0), Skipped +Segment at 20:17 (count = 3), RegionEntry +Segment at 20:22 (count = 0), Skipped +Segment at 21:9 (count = 3), RegionEntry +Segment at 22:6 (count = 0), Skipped +Segment at 33:42 (count = 1), RegionEntry +Segment at 36:10 (count = 0), Skipped +Segment at 41:37 (count = 1), RegionEntry +Segment at 41:41 (count = 0), Skipped +Segment at 42:13 (count = 1), RegionEntry +Segment at 43:10 (count = 0), Skipped +Segment at 48:8 (count = 1), RegionEntry +Segment at 48:15 (count = 0), Skipped +Segment at 48:16 (count = 1), RegionEntry +Segment at 50:6 (count = 0), RegionEntry +Segment at 50:7 (count = 0), Skipped +Segment at 52:9 (count = 1), RegionEntry +Segment at 57:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt new file mode 100644 index 0000000000000..0f54f4904b054 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt @@ -0,0 +1,138 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/lazy_boolean.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/lazy_boolean +Counter in file 0 7:9 -> 9:42, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 14:6, #2 +Counter in file 0 14:6 -> 14:7, #3 +Counter in file 0 16:9 -> 16:17, #4 +Counter in file 0 18:13 -> 18:18, #5 +Counter in file 0 20:13 -> 20:18, #6 +Counter in file 0 20:18 -> 20:19, #7 +Counter in file 0 20:18 -> 20:19, #8 +Counter in file 0 23:9 -> 23:17, #9 +Counter in file 0 25:13 -> 25:18, (#4 + 0) +Counter in file 0 27:13 -> 27:18, #10 +Counter in file 0 27:18 -> 27:19, #11 +Counter in file 0 27:18 -> 27:19, #12 +Counter in file 0 29:9 -> 29:17, #13 +Counter in file 0 29:20 -> 29:25, (#9 + 0) +Counter in file 0 29:29 -> 29:34, #14 +Counter in file 0 29:34 -> 29:35, #15 +Counter in file 0 29:34 -> 29:35, #16 +Counter in file 0 30:9 -> 30:17, #17 +Counter in file 0 30:20 -> 30:25, (#13 + 0) +Counter in file 0 30:29 -> 30:34, #18 +Counter in file 0 30:34 -> 30:35, #19 +Counter in file 0 30:34 -> 30:35, #20 +Counter in file 0 33:9 -> 34:16, (#17 + 0) +Counter in file 0 35:5 -> 38:6, #21 +Counter in file 0 38:6 -> 38:7, #22 +Counter in file 0 41:9 -> 41:16, #23 +Counter in file 0 42:5 -> 45:6, #24 +Counter in file 0 47:5 -> 50:6, #25 +Counter in file 0 50:6 -> 50:7, (#24 + 0) +Counter in file 0 52:8 -> 52:16, #26 +Counter in file 0 52:17 -> 54:6, #27 +Counter in file 0 54:6 -> 54:7, #28 +Counter in file 0 56:8 -> 56:15, #29 +Counter in file 0 56:16 -> 58:6, #30 +Counter in file 0 58:12 -> 60:6, #31 +Counter in file 0 60:6 -> 60:7, (#30 + 0) +Counter in file 0 61:1 -> 61:2, #32 +Emitting segments for file: ../coverage/lazy_boolean.rs +Combined regions: + 7:9 -> 9:42 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 14:6 (count=1) + 14:6 -> 14:7 (count=0) + 16:9 -> 16:17 (count=1) + 18:13 -> 18:18 (count=1) + 20:13 -> 20:18 (count=0) + 20:18 -> 20:19 (count=1) + 23:9 -> 23:17 (count=1) + 25:13 -> 25:18 (count=1) + 27:13 -> 27:18 (count=1) + 27:18 -> 27:19 (count=1) + 29:9 -> 29:17 (count=1) + 29:20 -> 29:25 (count=1) + 29:29 -> 29:34 (count=1) + 29:34 -> 29:35 (count=1) + 30:9 -> 30:17 (count=1) + 30:20 -> 30:25 (count=1) + 30:29 -> 30:34 (count=0) + 30:34 -> 30:35 (count=1) + 33:9 -> 34:16 (count=1) + 35:5 -> 38:6 (count=0) + 38:6 -> 38:7 (count=1) + 41:9 -> 41:16 (count=1) + 42:5 -> 45:6 (count=1) + 47:5 -> 50:6 (count=0) + 50:6 -> 50:7 (count=1) + 52:8 -> 52:16 (count=1) + 52:17 -> 54:6 (count=0) + 54:6 -> 54:7 (count=1) + 56:8 -> 56:15 (count=1) + 56:16 -> 58:6 (count=1) + 58:12 -> 60:6 (count=0) + 60:6 -> 60:7 (count=1) + 61:1 -> 61:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:42 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 14:6 (count = 0), RegionEntry +Segment at 14:7 (count = 0), Skipped +Segment at 16:9 (count = 1), RegionEntry +Segment at 16:17 (count = 0), Skipped +Segment at 18:13 (count = 1), RegionEntry +Segment at 18:18 (count = 0), Skipped +Segment at 20:13 (count = 0), RegionEntry +Segment at 20:18 (count = 1), RegionEntry +Segment at 20:19 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 23:17 (count = 0), Skipped +Segment at 25:13 (count = 1), RegionEntry +Segment at 25:18 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:18 (count = 1), RegionEntry +Segment at 27:19 (count = 0), Skipped +Segment at 29:9 (count = 1), RegionEntry +Segment at 29:17 (count = 0), Skipped +Segment at 29:20 (count = 1), RegionEntry +Segment at 29:25 (count = 0), Skipped +Segment at 29:29 (count = 1), RegionEntry +Segment at 29:34 (count = 1), RegionEntry +Segment at 29:35 (count = 0), Skipped +Segment at 30:9 (count = 1), RegionEntry +Segment at 30:17 (count = 0), Skipped +Segment at 30:20 (count = 1), RegionEntry +Segment at 30:25 (count = 0), Skipped +Segment at 30:29 (count = 0), RegionEntry +Segment at 30:34 (count = 1), RegionEntry +Segment at 30:35 (count = 0), Skipped +Segment at 33:9 (count = 1), RegionEntry +Segment at 34:16 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 38:6 (count = 1), RegionEntry +Segment at 38:7 (count = 0), Skipped +Segment at 41:9 (count = 1), RegionEntry +Segment at 41:16 (count = 0), Skipped +Segment at 42:5 (count = 1), RegionEntry +Segment at 45:6 (count = 0), Skipped +Segment at 47:5 (count = 0), RegionEntry +Segment at 50:6 (count = 1), RegionEntry +Segment at 50:7 (count = 0), Skipped +Segment at 52:8 (count = 1), RegionEntry +Segment at 52:16 (count = 0), Skipped +Segment at 52:17 (count = 0), RegionEntry +Segment at 54:6 (count = 1), RegionEntry +Segment at 54:7 (count = 0), Skipped +Segment at 56:8 (count = 1), RegionEntry +Segment at 56:15 (count = 0), Skipped +Segment at 56:16 (count = 1), RegionEntry +Segment at 58:6 (count = 0), Skipped +Segment at 58:12 (count = 0), RegionEntry +Segment at 60:6 (count = 1), RegionEntry +Segment at 60:7 (count = 0), Skipped +Segment at 61:1 (count = 1), RegionEntry +Segment at 61:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt new file mode 100644 index 0000000000000..3f5fc4a440164 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt @@ -0,0 +1,7 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loop_break_value.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loop_break_value +Counter in file 0 3:11 -> 13:2, #1 +Emitting segments for file: ../coverage/loop_break_value.rs +Combined regions: + 3:11 -> 13:2 (count=1) +Segment at 3:11 (count = 1), RegionEntry +Segment at 13:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt new file mode 100644 index 0000000000000..ca3b1d6134333 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt @@ -0,0 +1,39 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches +Counter in file 0 10:12 -> 10:16, #1 +Counter in file 0 11:16 -> 11:21, #2 +Counter in file 0 14:14 -> 14:15, #6 +Counter in file 0 15:13 -> 15:31, #7 +Counter in file 0 15:31 -> 15:32, #8 +Counter in file 0 17:10 -> 17:11, #10 +Counter in file 0 18:9 -> 18:15, #11 +Counter in file 0 19:5 -> 19:6, #12 +Counter in file 0 19:5 -> 19:6, (#8 + 0) +Counter in file 0 22:11 -> 25:2, #1 +Emitting segments for file: ../coverage/loops_and_branches.rs +Combined regions: + 10:12 -> 10:16 (count=1) + 11:16 -> 11:21 (count=1) + 14:14 -> 14:15 (count=1) + 15:13 -> 15:31 (count=1) + 15:31 -> 15:32 (count=0) + 17:10 -> 17:11 (count=1) + 18:9 -> 18:15 (count=1) + 19:5 -> 19:6 (count=1) + 22:11 -> 25:2 (count=1) +Segment at 10:12 (count = 1), RegionEntry +Segment at 10:16 (count = 0), Skipped +Segment at 11:16 (count = 1), RegionEntry +Segment at 11:21 (count = 0), Skipped +Segment at 14:14 (count = 1), RegionEntry +Segment at 14:15 (count = 0), Skipped +Segment at 15:13 (count = 1), RegionEntry +Segment at 15:31 (count = 0), RegionEntry +Segment at 15:32 (count = 0), Skipped +Segment at 17:10 (count = 1), RegionEntry +Segment at 17:11 (count = 0), Skipped +Segment at 18:9 (count = 1), RegionEntry +Segment at 18:15 (count = 0), Skipped +Segment at 19:5 (count = 1), RegionEntry +Segment at 19:6 (count = 0), Skipped +Segment at 22:11 (count = 1), RegionEntry +Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt new file mode 100644 index 0000000000000..9c9c46a083404 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt @@ -0,0 +1,76 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops +Counter in file 0 2:9 -> 3:27, #1 +Counter in file 0 5:19 -> 5:32, #2 +Counter in file 0 6:13 -> 7:24, #3 +Counter in file 0 8:13 -> 8:14, #4 +Counter in file 0 8:18 -> 8:23, #5 +Counter in file 0 9:16 -> 9:22, (#4 + 0) +Counter in file 0 10:17 -> 10:22, #6 +Counter in file 0 12:13 -> 12:19, #7 +Counter in file 0 13:13 -> 13:19, #8 +Counter in file 0 14:16 -> 14:22, (#8 + 0) +Counter in file 0 15:17 -> 16:27, #9 +Counter in file 0 17:21 -> 17:33, #10 +Counter in file 0 19:21 -> 21:14, #11 +Counter in file 0 21:14 -> 21:15, #12 +Counter in file 0 22:10 -> 22:11, #13 +Counter in file 0 22:10 -> 22:11, (#3 + 0) +Counter in file 0 23:9 -> 23:23, #14 +Counter in file 0 24:6 -> 24:7, #15 +Counter in file 0 24:6 -> 24:7, (#1 + 0) +Counter in file 0 25:1 -> 25:2, #16 +Emitting segments for file: ../coverage/nested_loops.rs +Combined regions: + 2:9 -> 3:27 (count=1) + 5:19 -> 5:32 (count=1) + 6:13 -> 7:24 (count=1) + 8:13 -> 8:14 (count=3) + 8:18 -> 8:23 (count=3) + 9:16 -> 9:22 (count=3) + 10:17 -> 10:22 (count=0) + 12:13 -> 12:19 (count=3) + 13:13 -> 13:19 (count=3) + 14:16 -> 14:22 (count=3) + 15:17 -> 16:27 (count=1) + 17:21 -> 17:33 (count=1) + 19:21 -> 21:14 (count=0) + 21:14 -> 21:15 (count=2) + 22:10 -> 22:11 (count=3) + 23:9 -> 23:23 (count=0) + 24:6 -> 24:7 (count=1) + 25:1 -> 25:2 (count=1) +Segment at 2:9 (count = 1), RegionEntry +Segment at 3:27 (count = 0), Skipped +Segment at 5:19 (count = 1), RegionEntry +Segment at 5:32 (count = 0), Skipped +Segment at 6:13 (count = 1), RegionEntry +Segment at 7:24 (count = 0), Skipped +Segment at 8:13 (count = 3), RegionEntry +Segment at 8:14 (count = 0), Skipped +Segment at 8:18 (count = 3), RegionEntry +Segment at 8:23 (count = 0), Skipped +Segment at 9:16 (count = 3), RegionEntry +Segment at 9:22 (count = 0), Skipped +Segment at 10:17 (count = 0), RegionEntry +Segment at 10:22 (count = 0), Skipped +Segment at 12:13 (count = 3), RegionEntry +Segment at 12:19 (count = 0), Skipped +Segment at 13:13 (count = 3), RegionEntry +Segment at 13:19 (count = 0), Skipped +Segment at 14:16 (count = 3), RegionEntry +Segment at 14:22 (count = 0), Skipped +Segment at 15:17 (count = 1), RegionEntry +Segment at 16:27 (count = 0), Skipped +Segment at 17:21 (count = 1), RegionEntry +Segment at 17:33 (count = 0), Skipped +Segment at 19:21 (count = 0), RegionEntry +Segment at 21:14 (count = 2), RegionEntry +Segment at 21:15 (count = 0), Skipped +Segment at 22:10 (count = 3), RegionEntry +Segment at 22:11 (count = 0), Skipped +Segment at 23:9 (count = 0), RegionEntry +Segment at 23:23 (count = 0), Skipped +Segment at 24:6 (count = 1), RegionEntry +Segment at 24:7 (count = 0), Skipped +Segment at 25:1 (count = 1), RegionEntry +Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt new file mode 100644 index 0000000000000..dbcaa57b4b296 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -0,0 +1,68 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region +Counter in file 0 4:39 -> 4:49, #1 +Counter in file 0 4:39 -> 4:49, #2 +Counter in file 0 4:39 -> 4:49, #3 +Counter in file 0 4:39 -> 4:49, #4 +Counter in file 0 4:48 -> 4:49, #5 +Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 21:11 -> 26:2, #1 +Counter in file 0 4:39 -> 4:40, #1 +Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 7:5 -> 7:6, #1 +Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 4:39 -> 4:40, #1 +Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 4:24 -> 4:33, #1 +Counter in file 0 4:24 -> 4:33, #2 +Counter in file 0 4:24 -> 4:33, #3 +Counter in file 0 4:24 -> 4:33, #4 +Counter in file 0 4:32 -> 4:33, #5 +Counter in file 0 4:51 -> 4:54, #1 +Counter in file 0 4:51 -> 4:54, #2 +Counter in file 0 4:51 -> 4:54, #3 +Counter in file 0 4:51 -> 4:54, #4 +Counter in file 0 4:53 -> 4:54, #5 +Counter in file 0 13:9 -> 18:6, #1 +Counter in file 0 7:5 -> 7:6, #1 +Counter in file 0 4:39 -> 4:40, #1 +Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 7:5 -> 7:6, #1 +Counter in file 0 4:10 -> 4:15, #1 +Counter in file 0 4:35 -> 4:37, #1 +Counter in file 0 7:5 -> 7:6, #1 +Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 4:17 -> 4:22, #1 +Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 4:39 -> 4:40, #1 +Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 4:24 -> 4:33, #1 +Counter in file 0 4:24 -> 4:33, #2 +Counter in file 0 4:32 -> 4:33, #3 +Emitting segments for file: ../coverage/partial_eq_counter_without_region.rs +Combined regions: + 4:17 -> 4:22 (count=2) + 4:39 -> 4:40 (count=1) + 4:48 -> 4:49 (count=1) + 7:5 -> 7:6 (count=1) + 13:9 -> 18:6 (count=2) + 21:11 -> 26:2 (count=1) +Segment at 4:17 (count = 2), RegionEntry +Segment at 4:22 (count = 0), Skipped +Segment at 4:39 (count = 1), RegionEntry +Segment at 4:40 (count = 0), Skipped +Segment at 4:48 (count = 1), RegionEntry +Segment at 4:49 (count = 0), Skipped +Segment at 7:5 (count = 1), RegionEntry +Segment at 7:6 (count = 0), Skipped +Segment at 13:9 (count = 2), RegionEntry +Segment at 18:6 (count = 0), Skipped +Segment at 21:11 (count = 1), RegionEntry +Segment at 26:2 (count = 0), Skipped +Emitting segments for function: _RNvXs0_Cs4fqI2P2rA04_33partial_eq_counter_without_regionNtB5_7VersionNtNtCs7f2nZg1zwMz_4core3cmp10PartialOrd2ltB5_ +Combined regions: + 4:39 -> 4:40 (count=1) + 4:48 -> 4:49 (count=1) +Segment at 4:39 (count = 1), RegionEntry +Segment at 4:40 (count = 0), Skipped +Segment at 4:48 (count = 1), RegionEntry +Segment at 4:49 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt new file mode 100644 index 0000000000000..90e09099dcc4f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt @@ -0,0 +1,38 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_loop +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 12:9 -> 12:16, (#1 + 0) +Counter in file 0 13:5 -> 18:6, #2 +Counter in file 0 18:6 -> 18:7, #3 +Counter in file 0 23:13 -> 25:14, #4 +Counter in file 0 27:13 -> 27:18, #5 +Counter in file 0 30:9 -> 32:10, #6 +Counter in file 0 34:6 -> 34:7, #7 +Counter in file 0 35:1 -> 35:2, (#5 + 0) +Emitting segments for file: ../coverage/simple_loop.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 12:9 -> 12:16 (count=1) + 13:5 -> 18:6 (count=1) + 18:6 -> 18:7 (count=0) + 23:13 -> 25:14 (count=11) + 27:13 -> 27:18 (count=1) + 30:9 -> 32:10 (count=10) + 34:6 -> 34:7 (count=1) + 35:1 -> 35:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 12:9 (count = 1), RegionEntry +Segment at 12:16 (count = 0), Skipped +Segment at 13:5 (count = 1), RegionEntry +Segment at 18:6 (count = 0), RegionEntry +Segment at 18:7 (count = 0), Skipped +Segment at 23:13 (count = 11), RegionEntry +Segment at 25:14 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:18 (count = 0), Skipped +Segment at 30:9 (count = 10), RegionEntry +Segment at 32:10 (count = 0), Skipped +Segment at 34:6 (count = 1), RegionEntry +Segment at 34:7 (count = 0), Skipped +Segment at 35:1 (count = 1), RegionEntry +Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt new file mode 100644 index 0000000000000..39a986332cd9f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt @@ -0,0 +1,58 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_match.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_match +Counter in file 0 7:9 -> 9:26, #1 +Counter in file 0 10:8 -> 10:15, (#1 + 0) +Counter in file 0 10:16 -> 12:6, #2 +Counter in file 0 12:6 -> 12:7, #3 +Counter in file 0 15:9 -> 15:10, #4 +Counter in file 0 17:9 -> 17:13, #5 +Counter in file 0 22:13 -> 22:22, (#4 + 0) +Counter in file 0 24:13 -> 24:14, #6 +Counter in file 0 26:17 -> 28:18, (#4 + 0) +Counter in file 0 28:18 -> 28:19, #7 +Counter in file 0 30:13 -> 37:14, (#6 + 0) +Counter in file 0 40:13 -> 40:15, #8 +Counter in file 0 42:6 -> 42:7, #9 +Counter in file 0 42:6 -> 42:7, #10 +Counter in file 0 43:1 -> 43:2, #11 +Emitting segments for file: ../coverage/simple_match.rs +Combined regions: + 7:9 -> 9:26 (count=1) + 10:8 -> 10:15 (count=1) + 10:16 -> 12:6 (count=1) + 12:6 -> 12:7 (count=0) + 15:9 -> 15:10 (count=2) + 17:9 -> 17:13 (count=3) + 22:13 -> 22:22 (count=2) + 24:13 -> 24:14 (count=1) + 26:17 -> 28:18 (count=2) + 28:18 -> 28:19 (count=1) + 30:13 -> 37:14 (count=1) + 40:13 -> 40:15 (count=1) + 42:6 -> 42:7 (count=3) + 43:1 -> 43:2 (count=1) +Segment at 7:9 (count = 1), RegionEntry +Segment at 9:26 (count = 0), Skipped +Segment at 10:8 (count = 1), RegionEntry +Segment at 10:15 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 12:6 (count = 0), RegionEntry +Segment at 12:7 (count = 0), Skipped +Segment at 15:9 (count = 2), RegionEntry +Segment at 15:10 (count = 0), Skipped +Segment at 17:9 (count = 3), RegionEntry +Segment at 17:13 (count = 0), Skipped +Segment at 22:13 (count = 2), RegionEntry +Segment at 22:22 (count = 0), Skipped +Segment at 24:13 (count = 1), RegionEntry +Segment at 24:14 (count = 0), Skipped +Segment at 26:17 (count = 2), RegionEntry +Segment at 28:18 (count = 1), RegionEntry +Segment at 28:19 (count = 0), Skipped +Segment at 30:13 (count = 1), RegionEntry +Segment at 37:14 (count = 0), Skipped +Segment at 40:13 (count = 1), RegionEntry +Segment at 40:15 (count = 0), Skipped +Segment at 42:6 (count = 3), RegionEntry +Segment at 42:7 (count = 0), Skipped +Segment at 43:1 (count = 1), RegionEntry +Segment at 43:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt new file mode 100644 index 0000000000000..a0687815fb967 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt @@ -0,0 +1,11 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop +Counter in file 0 2:8 -> 2:13, #1 +Counter in file 0 5:1 -> 5:2, #4 +Emitting segments for file: ../coverage/tight_infinite_loop.rs +Combined regions: + 2:8 -> 2:13 (count=1) + 5:1 -> 5:2 (count=1) +Segment at 2:8 (count = 1), RegionEntry +Segment at 2:13 (count = 0), Skipped +Segment at 5:1 (count = 1), RegionEntry +Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt new file mode 100644 index 0000000000000..10fc52354b9b5 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt @@ -0,0 +1,72 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result +Counter in file 0 13:9 -> 14:23, #1 +Counter in file 0 17:9 -> 17:10, #2 +Counter in file 0 19:9 -> 19:14, #3 +Counter in file 0 21:9 -> 25:26, #4 +Counter in file 0 27:13 -> 27:41, #5 +Counter in file 0 27:41 -> 27:42, #6 +Counter in file 0 31:13 -> 31:42, #7 +Counter in file 0 31:42 -> 31:43, #8 +Counter in file 0 32:10 -> 32:11, #9 +Counter in file 0 32:10 -> 32:11, #10 +Counter in file 0 33:6 -> 33:7, #11 +Counter in file 0 33:6 -> 33:7, (#1 + 0) +Counter in file 0 34:5 -> 34:11, #12 +Counter in file 0 35:1 -> 35:2, #13 +Counter in file 0 35:1 -> 35:2, #14 +Counter in file 0 5:8 -> 5:20, #1 +Counter in file 0 6:9 -> 6:16, #2 +Counter in file 0 8:9 -> 8:15, #3 +Counter in file 0 9:6 -> 9:7, (#2 + 0) +Counter in file 0 10:1 -> 10:2, #4 +Emitting segments for file: ../coverage/try_error_result.rs +Combined regions: + 5:8 -> 5:20 (count=6) + 6:9 -> 6:16 (count=1) + 8:9 -> 8:15 (count=5) + 9:6 -> 9:7 (count=1) + 10:1 -> 10:2 (count=6) + 13:9 -> 14:23 (count=1) + 17:9 -> 17:10 (count=6) + 19:9 -> 19:14 (count=6) + 21:9 -> 25:26 (count=6) + 27:13 -> 27:41 (count=1) + 27:41 -> 27:42 (count=1) + 31:13 -> 31:42 (count=5) + 31:42 -> 31:43 (count=0) + 32:10 -> 32:11 (count=5) + 33:6 -> 33:7 (count=6) + 34:5 -> 34:11 (count=0) + 35:1 -> 35:2 (count=2) +Segment at 5:8 (count = 6), RegionEntry +Segment at 5:20 (count = 0), Skipped +Segment at 6:9 (count = 1), RegionEntry +Segment at 6:16 (count = 0), Skipped +Segment at 8:9 (count = 5), RegionEntry +Segment at 8:15 (count = 0), Skipped +Segment at 9:6 (count = 1), RegionEntry +Segment at 9:7 (count = 0), Skipped +Segment at 10:1 (count = 6), RegionEntry +Segment at 10:2 (count = 0), Skipped +Segment at 13:9 (count = 1), RegionEntry +Segment at 14:23 (count = 0), Skipped +Segment at 17:9 (count = 6), RegionEntry +Segment at 17:10 (count = 0), Skipped +Segment at 19:9 (count = 6), RegionEntry +Segment at 19:14 (count = 0), Skipped +Segment at 21:9 (count = 6), RegionEntry +Segment at 25:26 (count = 0), Skipped +Segment at 27:13 (count = 1), RegionEntry +Segment at 27:41 (count = 1), RegionEntry +Segment at 27:42 (count = 0), Skipped +Segment at 31:13 (count = 5), RegionEntry +Segment at 31:42 (count = 0), RegionEntry +Segment at 31:43 (count = 0), Skipped +Segment at 32:10 (count = 5), RegionEntry +Segment at 32:11 (count = 0), Skipped +Segment at 33:6 (count = 6), RegionEntry +Segment at 33:7 (count = 0), Skipped +Segment at 34:5 (count = 0), RegionEntry +Segment at 34:11 (count = 0), Skipped +Segment at 35:1 (count = 2), RegionEntry +Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt new file mode 100644 index 0000000000000..567c8cd9b6df0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt @@ -0,0 +1,240 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/various_conditions.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/various_conditions +Counter in file 0 4:9 -> 4:26, #1 +Counter in file 0 5:8 -> 5:12, (#1 + 0) +Counter in file 0 5:13 -> 7:6, #2 +Counter in file 0 10:9 -> 10:10, #4 +Counter in file 0 10:16 -> 10:29, #5 +Counter in file 0 11:9 -> 12:10, #6 +Counter in file 0 13:15 -> 13:28, #7 +Counter in file 0 14:12 -> 14:25, #8 +Counter in file 0 14:29 -> 14:42, #9 +Counter in file 0 14:42 -> 14:43, #10 +Counter in file 0 14:42 -> 14:43, #11 +Counter in file 0 14:46 -> 14:60, #12 +Counter in file 0 14:60 -> 14:61, #13 +Counter in file 0 14:60 -> 14:61, #14 +Counter in file 0 14:61 -> 16:10, #15 +Counter in file 0 16:10 -> 16:11, #16 +Counter in file 0 17:9 -> 18:18, #17 +Counter in file 0 20:9 -> 20:15, #18 +Counter in file 0 23:9 -> 23:26, (#4 + 0) +Counter in file 0 24:8 -> 24:12, (#4 + 0) +Counter in file 0 24:13 -> 26:6, #19 +Counter in file 0 28:8 -> 28:21, #21 +Counter in file 0 29:9 -> 29:23, #22 +Counter in file 0 30:15 -> 30:28, #23 +Counter in file 0 31:12 -> 31:25, #24 +Counter in file 0 31:29 -> 31:42, #25 +Counter in file 0 31:42 -> 31:43, #26 +Counter in file 0 31:42 -> 31:43, #27 +Counter in file 0 31:46 -> 31:60, #28 +Counter in file 0 31:60 -> 31:61, #29 +Counter in file 0 31:60 -> 31:61, #30 +Counter in file 0 31:61 -> 33:10, #31 +Counter in file 0 33:10 -> 33:11, #32 +Counter in file 0 34:9 -> 34:23, #33 +Counter in file 0 36:9 -> 36:15, #34 +Counter in file 0 39:9 -> 39:26, #35 +Counter in file 0 40:8 -> 40:12, (#35 + 0) +Counter in file 0 40:13 -> 42:6, #36 +Counter in file 0 44:9 -> 44:10, #38 +Counter in file 0 44:16 -> 44:29, #39 +Counter in file 0 45:9 -> 45:23, #40 +Counter in file 0 46:15 -> 46:28, #41 +Counter in file 0 47:12 -> 47:25, #42 +Counter in file 0 47:29 -> 47:42, #43 +Counter in file 0 47:42 -> 47:43, #44 +Counter in file 0 47:42 -> 47:43, #45 +Counter in file 0 47:46 -> 47:60, #46 +Counter in file 0 47:60 -> 47:61, #47 +Counter in file 0 47:60 -> 47:61, #48 +Counter in file 0 47:61 -> 49:10, #49 +Counter in file 0 49:10 -> 49:11, #50 +Counter in file 0 50:9 -> 50:23, #51 +Counter in file 0 52:13 -> 54:15, #52 +Counter in file 0 57:9 -> 57:10, #53 +Counter in file 0 57:16 -> 57:29, (#38 + 0) +Counter in file 0 58:9 -> 58:23, #54 +Counter in file 0 59:15 -> 59:28, #55 +Counter in file 0 60:12 -> 60:25, #56 +Counter in file 0 60:29 -> 60:42, #57 +Counter in file 0 60:42 -> 60:43, #58 +Counter in file 0 60:42 -> 60:43, #59 +Counter in file 0 60:46 -> 60:60, #60 +Counter in file 0 60:60 -> 60:61, #61 +Counter in file 0 60:60 -> 60:61, #62 +Counter in file 0 60:61 -> 62:10, #63 +Counter in file 0 62:10 -> 62:11, #64 +Counter in file 0 63:9 -> 63:23, #65 +Counter in file 0 65:9 -> 65:15, #66 +Counter in file 0 67:1 -> 67:2, #67 +Counter in file 0 67:1 -> 67:2, #68 +Emitting segments for file: ../coverage/various_conditions.rs +Combined regions: + 4:9 -> 4:26 (count=1) + 5:8 -> 5:12 (count=1) + 5:13 -> 7:6 (count=1) + 10:9 -> 10:10 (count=1) + 10:16 -> 10:29 (count=1) + 11:9 -> 12:10 (count=1) + 13:15 -> 13:28 (count=0) + 14:12 -> 14:25 (count=0) + 14:29 -> 14:42 (count=0) + 14:42 -> 14:43 (count=0) + 14:46 -> 14:60 (count=0) + 14:60 -> 14:61 (count=0) + 14:61 -> 16:10 (count=0) + 16:10 -> 16:11 (count=0) + 17:9 -> 18:18 (count=0) + 20:9 -> 20:15 (count=0) + 23:9 -> 23:26 (count=1) + 24:8 -> 24:12 (count=1) + 24:13 -> 26:6 (count=1) + 28:8 -> 28:21 (count=1) + 29:9 -> 29:23 (count=1) + 30:15 -> 30:28 (count=0) + 31:12 -> 31:25 (count=0) + 31:29 -> 31:42 (count=0) + 31:42 -> 31:43 (count=0) + 31:46 -> 31:60 (count=0) + 31:60 -> 31:61 (count=0) + 31:61 -> 33:10 (count=0) + 33:10 -> 33:11 (count=0) + 34:9 -> 34:23 (count=0) + 36:9 -> 36:15 (count=0) + 39:9 -> 39:26 (count=1) + 40:8 -> 40:12 (count=1) + 40:13 -> 42:6 (count=1) + 44:9 -> 44:10 (count=0) + 44:16 -> 44:29 (count=1) + 45:9 -> 45:23 (count=0) + 46:15 -> 46:28 (count=1) + 47:12 -> 47:25 (count=0) + 47:29 -> 47:42 (count=0) + 47:42 -> 47:43 (count=0) + 47:46 -> 47:60 (count=0) + 47:60 -> 47:61 (count=0) + 47:61 -> 49:10 (count=0) + 49:10 -> 49:11 (count=0) + 50:9 -> 50:23 (count=0) + 52:13 -> 54:15 (count=1) + 57:9 -> 57:10 (count=0) + 57:16 -> 57:29 (count=0) + 58:9 -> 58:23 (count=0) + 59:15 -> 59:28 (count=0) + 60:12 -> 60:25 (count=0) + 60:29 -> 60:42 (count=0) + 60:42 -> 60:43 (count=0) + 60:46 -> 60:60 (count=0) + 60:60 -> 60:61 (count=0) + 60:61 -> 62:10 (count=0) + 62:10 -> 62:11 (count=0) + 63:9 -> 63:23 (count=0) + 65:9 -> 65:15 (count=0) + 67:1 -> 67:2 (count=2) +Segment at 4:9 (count = 1), RegionEntry +Segment at 4:26 (count = 0), Skipped +Segment at 5:8 (count = 1), RegionEntry +Segment at 5:12 (count = 0), Skipped +Segment at 5:13 (count = 1), RegionEntry +Segment at 7:6 (count = 0), Skipped +Segment at 10:9 (count = 1), RegionEntry +Segment at 10:10 (count = 0), Skipped +Segment at 10:16 (count = 1), RegionEntry +Segment at 10:29 (count = 0), Skipped +Segment at 11:9 (count = 1), RegionEntry +Segment at 12:10 (count = 0), Skipped +Segment at 13:15 (count = 0), RegionEntry +Segment at 13:28 (count = 0), Skipped +Segment at 14:12 (count = 0), RegionEntry +Segment at 14:25 (count = 0), Skipped +Segment at 14:29 (count = 0), RegionEntry +Segment at 14:42 (count = 0), RegionEntry +Segment at 14:43 (count = 0), Skipped +Segment at 14:46 (count = 0), RegionEntry +Segment at 14:60 (count = 0), RegionEntry +Segment at 14:61 (count = 0), RegionEntry +Segment at 16:10 (count = 0), RegionEntry +Segment at 16:11 (count = 0), Skipped +Segment at 17:9 (count = 0), RegionEntry +Segment at 18:18 (count = 0), Skipped +Segment at 20:9 (count = 0), RegionEntry +Segment at 20:15 (count = 0), Skipped +Segment at 23:9 (count = 1), RegionEntry +Segment at 23:26 (count = 0), Skipped +Segment at 24:8 (count = 1), RegionEntry +Segment at 24:12 (count = 0), Skipped +Segment at 24:13 (count = 1), RegionEntry +Segment at 26:6 (count = 0), Skipped +Segment at 28:8 (count = 1), RegionEntry +Segment at 28:21 (count = 0), Skipped +Segment at 29:9 (count = 1), RegionEntry +Segment at 29:23 (count = 0), Skipped +Segment at 30:15 (count = 0), RegionEntry +Segment at 30:28 (count = 0), Skipped +Segment at 31:12 (count = 0), RegionEntry +Segment at 31:25 (count = 0), Skipped +Segment at 31:29 (count = 0), RegionEntry +Segment at 31:42 (count = 0), RegionEntry +Segment at 31:43 (count = 0), Skipped +Segment at 31:46 (count = 0), RegionEntry +Segment at 31:60 (count = 0), RegionEntry +Segment at 31:61 (count = 0), RegionEntry +Segment at 33:10 (count = 0), RegionEntry +Segment at 33:11 (count = 0), Skipped +Segment at 34:9 (count = 0), RegionEntry +Segment at 34:23 (count = 0), Skipped +Segment at 36:9 (count = 0), RegionEntry +Segment at 36:15 (count = 0), Skipped +Segment at 39:9 (count = 1), RegionEntry +Segment at 39:26 (count = 0), Skipped +Segment at 40:8 (count = 1), RegionEntry +Segment at 40:12 (count = 0), Skipped +Segment at 40:13 (count = 1), RegionEntry +Segment at 42:6 (count = 0), Skipped +Segment at 44:9 (count = 0), RegionEntry +Segment at 44:10 (count = 0), Skipped +Segment at 44:16 (count = 1), RegionEntry +Segment at 44:29 (count = 0), Skipped +Segment at 45:9 (count = 0), RegionEntry +Segment at 45:23 (count = 0), Skipped +Segment at 46:15 (count = 1), RegionEntry +Segment at 46:28 (count = 0), Skipped +Segment at 47:12 (count = 0), RegionEntry +Segment at 47:25 (count = 0), Skipped +Segment at 47:29 (count = 0), RegionEntry +Segment at 47:42 (count = 0), RegionEntry +Segment at 47:43 (count = 0), Skipped +Segment at 47:46 (count = 0), RegionEntry +Segment at 47:60 (count = 0), RegionEntry +Segment at 47:61 (count = 0), RegionEntry +Segment at 49:10 (count = 0), RegionEntry +Segment at 49:11 (count = 0), Skipped +Segment at 50:9 (count = 0), RegionEntry +Segment at 50:23 (count = 0), Skipped +Segment at 52:13 (count = 1), RegionEntry +Segment at 54:15 (count = 0), Skipped +Segment at 57:9 (count = 0), RegionEntry +Segment at 57:10 (count = 0), Skipped +Segment at 57:16 (count = 0), RegionEntry +Segment at 57:29 (count = 0), Skipped +Segment at 58:9 (count = 0), RegionEntry +Segment at 58:23 (count = 0), Skipped +Segment at 59:15 (count = 0), RegionEntry +Segment at 59:28 (count = 0), Skipped +Segment at 60:12 (count = 0), RegionEntry +Segment at 60:25 (count = 0), Skipped +Segment at 60:29 (count = 0), RegionEntry +Segment at 60:42 (count = 0), RegionEntry +Segment at 60:43 (count = 0), Skipped +Segment at 60:46 (count = 0), RegionEntry +Segment at 60:60 (count = 0), RegionEntry +Segment at 60:61 (count = 0), RegionEntry +Segment at 62:10 (count = 0), RegionEntry +Segment at 62:11 (count = 0), Skipped +Segment at 63:9 (count = 0), RegionEntry +Segment at 63:23 (count = 0), Skipped +Segment at 65:9 (count = 0), RegionEntry +Segment at 65:15 (count = 0), Skipped +Segment at 67:1 (count = 2), RegionEntry +Segment at 67:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt new file mode 100644 index 0000000000000..1aad1a3c83b85 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt @@ -0,0 +1,22 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while +Counter in file 0 2:9 -> 2:16, #1 +Counter in file 0 3:11 -> 3:20, #2 +Counter in file 0 3:21 -> 4:6, #3 +Counter in file 0 4:6 -> 4:7, (#3 + 0) +Counter in file 0 5:1 -> 5:2, #4 +Emitting segments for file: ../coverage/while.rs +Combined regions: + 2:9 -> 2:16 (count=1) + 3:11 -> 3:20 (count=1) + 3:21 -> 4:6 (count=0) + 4:6 -> 4:7 (count=0) + 5:1 -> 5:2 (count=1) +Segment at 2:9 (count = 1), RegionEntry +Segment at 2:16 (count = 0), Skipped +Segment at 3:11 (count = 1), RegionEntry +Segment at 3:20 (count = 0), Skipped +Segment at 3:21 (count = 0), RegionEntry +Segment at 4:6 (count = 0), RegionEntry +Segment at 4:7 (count = 0), Skipped +Segment at 5:1 (count = 1), RegionEntry +Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt new file mode 100644 index 0000000000000..7c24ea22d67e1 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt @@ -0,0 +1,44 @@ +Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return +Counter in file 0 5:9 -> 5:27, #1 +Counter in file 0 7:9 -> 9:10, #2 +Counter in file 0 12:13 -> 14:14, #3 +Counter in file 0 18:21 -> 20:22, #4 +Counter in file 0 22:21 -> 22:27, #5 +Counter in file 0 26:21 -> 26:27, #6 +Counter in file 0 27:18 -> 27:19, (#5 + 0) +Counter in file 0 30:9 -> 32:10, #7 +Counter in file 0 35:5 -> 35:11, #8 +Counter in file 0 36:1 -> 36:2, #9 +Counter in file 0 36:1 -> 36:2, #10 +Emitting segments for file: ../coverage/while_early_return.rs +Combined regions: + 5:9 -> 5:27 (count=1) + 7:9 -> 9:10 (count=7) + 12:13 -> 14:14 (count=7) + 18:21 -> 20:22 (count=1) + 22:21 -> 22:27 (count=0) + 26:21 -> 26:27 (count=1) + 27:18 -> 27:19 (count=0) + 30:9 -> 32:10 (count=6) + 35:5 -> 35:11 (count=0) + 36:1 -> 36:2 (count=2) +Segment at 5:9 (count = 1), RegionEntry +Segment at 5:27 (count = 0), Skipped +Segment at 7:9 (count = 7), RegionEntry +Segment at 9:10 (count = 0), Skipped +Segment at 12:13 (count = 7), RegionEntry +Segment at 14:14 (count = 0), Skipped +Segment at 18:21 (count = 1), RegionEntry +Segment at 20:22 (count = 0), Skipped +Segment at 22:21 (count = 0), RegionEntry +Segment at 22:27 (count = 0), Skipped +Segment at 26:21 (count = 1), RegionEntry +Segment at 26:27 (count = 0), Skipped +Segment at 27:18 (count = 0), RegionEntry +Segment at 27:19 (count = 0), Skipped +Segment at 30:9 (count = 6), RegionEntry +Segment at 32:10 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 35:11 (count = 0), Skipped +Segment at 36:1 (count = 2), RegionEntry +Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html index 43f75c574d0ee..0f076a93c0977 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 35:13-35:26: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +36:21-38:10: @3[1]: _3 = const () +38:10-38:10: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +36:21-38:10: @3[1]: _3 = const () +38:10-38:10: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 2".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html index 8f07ec5fcde66..bc78a604e311e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 77:13-77:26: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +78:21-80:10: @3[1]: _3 = const () +80:10-80:10: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +78:21-80:10: @3[1]: _3 = const () +80:10-80:10: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 4".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html index ca9031a1094a4..b0db2311730b0 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 20:21-20:34: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +21:29-23:18: @3[1]: _3 = const () +23:18-23:18: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +21:29-23:18: @3[1]: _3 = const () +23:18-23:18: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 1".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html index 820f8d9c6cf8f..ca07a8d3ce5b8 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 62:21-62:34: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +63:29-65:18: @3[1]: _3 = const () +65:18-65:18: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +63:29-65:18: @3[1]: _3 = const () +65:18-65:18: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 3".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 494e6f20ea763..325b6c64345a4 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -114,6 +114,6 @@ Ok(())⦉@2,6,7,8 -}@11⦊‸⦉@11 +}@1,3,4,5,9,10⦊‸⦉@1,3,4,5,9,10@2,6,7,8⦊‸⦉@2,6,7,8@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 6dc893d28ff52..55d7e8bfbae18 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -162,6 +162,6 @@ Ok(())⦉@5,9,10,11 -}@14⦊‸⦉@14 +}@4,6,7,8,12,13⦊‸⦉@4,6,7,8,12,13@5,9,10,11⦊‸⦉@5,9,10,11@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html index 0379d900e9409..0d4b940214e39 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html @@ -146,17 +146,23 @@ @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> countdown = +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> = 10 +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> 10 ; +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> ; }⦉@4,6 -}@7⦊‸⦉@7 +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 +}@7⦊‸⦉@7 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index b51c5c84c0d6e..094dacde9868d 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -128,36 +128,36 @@ 20:9-22:16: @5[1]: _6 = const ()"> = 100⦉@5 - } + }@4,6⦊‸⦉@4,6 if - @7⦊is_true⦉@7 - @8,10⦊{ - countdown - = - 10 - ; - }⦉@8,10 else - @9⦊{ - countdown - = - 100 - ; - }⦉@9 + }⦉@9@8,10⦊‸⦉@8,10 }@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html index 49639cc6884ba..7f1262a6abf0a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html @@ -63,8 +63,7 @@ let @0⦊b = 1⦉@0; let @1,2,3,4⦊c⦉@1,2,3,4 = @0⦊a + b⦉@0; +20:21-20:22: @0[7]: _5 = _2">@0⦊a + b⦉@0; fn trait_func(&mut self, incr: u32) { - @0⦊self.in_struct_field += incr⦉@0; + self.in_struct_field += @0⦊incr⦉@0; @1,2⦊in_func(self.in_struct_field); diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html index 56557b8ef955e..ec3517ec9eddd 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html @@ -86,11 +86,14 @@ 9:9-9:22: @3[3]: FakeRead(ForLet, _5)"> let mut countdown = 0⦉@0,1,2,3; if @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown = 10; +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> countdown = 10; }⦉@4,6 +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 mod in_mod { const IN_MOD_CONST: u32 = 1000; @@ -126,16 +129,19 @@ type InType = String; - if @7⦊is_true⦉@7 if @7⦊is_true⦉@7 @8,10,11⦊{ -@8,10,11⦊{ + in_func(countdown); - in_func(countdown); + }⦉@8,10,11 +48:16-50:6: @11[2]: _8 = const () +50:6-50:6: @11.Goto: goto -> bb12"> }⦉@8,10,11@9⦊‸⦉@9 let // Initialize test constants in a way that cannot be determined at compile time, to ensure // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from // dependent conditions. - let let @0,1,2,3⦊is_true = std::env::args().len() == 1; - -@0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7">@4,6⦊{ a = 1; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> a = 1; b = 10; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> b = 10; c = 100; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> c = 100; }⦉@4,6 +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 let - @11⦊somebool⦉@11 + @11⦊somebool⦉@11 = - @7⦊a < b⦉@7 || - @10⦊b < c⦉@10 +20:13-20:18: @10[5]: _15 = Lt(move _16, move _17)">@10⦊b < c⦉@10@8⦊‸⦉@8@9⦊‸⦉@9 ; let - @15⦊somebool⦉@15 + @15⦊somebool⦉@15 = - @11⦊b < a⦉@11 || - @14⦊b < c⦉@14 +27:13-27:18: @14[5]: _22 = Lt(move _23, move _24)">@14⦊b < c⦉@14@12⦊‸⦉@12@13⦊‸⦉@13 ; - let - @19⦊somebool⦉@19 - = - @15⦊a < b⦉@15 - && - @18⦊b < c⦉@18 - ; - let - @23⦊somebool⦉@23 - = - @19⦊b < a⦉@19 - && - @22⦊b < c⦉@22 - ; -}@23⦊‸⦉@23 + let @19⦊somebool⦉@19 = @15⦊a < b⦉@15 && @18⦊b < c⦉@18@16⦊‸⦉@16@17⦊‸⦉@17; + let @23⦊somebool⦉@23 = @19⦊b < a⦉@19 && @22⦊b < c⦉@22@20⦊‸⦉@20@21⦊‸⦉@21; + + if + @23⦊! + is_true⦉@23 + @24,26⦊{ + a = 2 + ; + }⦉@24,26@25⦊‸⦉@25 + + if + @27⦊is_true⦉@27 + @28,30⦊{ + b = 30 + ; + }⦉@28,30 + else + @29⦊{ + c = 400 + ; + }⦉@29@28,30⦊‸⦉@28,30 + + if @31⦊!is_true⦉@31 @32,34⦊{ + a = 2; + }⦉@32,34@33⦊‸⦉@33 + + if @35⦊is_true⦉@35 @36,38⦊{ + b = 30; + }⦉@36,38 else @37⦊{ + c = 400; + }⦉@37@36,38⦊‸⦉@36,38 +}@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a876c85822f32 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,151 @@ + + + +loops_and_branches.main - Coverage Spans + + + +
fn main() @0,1,2,3⦊{ + let debug_test = DebugTest; + println!("{:?}", debug_test); +}⦉@0,1,2,3
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..1b9767506f26a --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -0,0 +1,94 @@ + + + +loops_and_branches.{impl#0}-fmt - Coverage Spans + + + +
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if @0⦊true⦉@0 { + if @1,3⦊false⦉@1,3 { + while @6,7⦊true⦉@6,7 @8,10⦊{ + }⦉@8,10 + }@9⦊‸⦉@9@5⦊‸⦉@5 + @11,12,13,14⦊write!(f, "error")⦉@11,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; + } else @2⦊{ + }⦉@2@15⦊‸⦉@15 + @21⦊Ok(())⦉@21 + }@16,18,19,20⦊‸⦉@16,18,19,20@22⦊‸⦉@22
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..042845b70cc30 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,125 @@ + + + +nested_loops.main - Coverage Spans + + + +
fn main() { + let @0,1,2,3⦊is_true = std::env::args().len() == 1; + let mut countdown = 10⦉@0,1,2,3; + + 'outer: while @4,5⦊countdown > 0⦉@4,5 { + let @6,8,9⦊mut a = 100; + let mut b = 100⦉@6,8,9; + for @14,16⦊_⦉@14,16 in @10,11,12⦊0..50⦉@10,11,12 { + if @14,16⦊a < 30⦉@14,16 { + @17,19⦊break⦉@17,19; + } + @20⦊a -= 5⦉@20; + @21⦊b -= 5⦉@21; + if @21⦊b < 90⦉@21 { + @25⦊a -= 10; + if is_true⦉@25 { + @26,28⦊break 'outer⦉@26,28; + } else { + @29⦊a -= 2; + } + }⦉@29@23⦊‸⦉@23 + }@6,8,9⦊‸⦉@6,8,9@30⦊‸⦉@30 + @32⦊countdown -= 1⦉@32; + }@0,1,2,3⦊‸⦉@0,1,2,3@7⦊‸⦉@7 +}@33⦊‸⦉@33
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..3ebe51bc7ec36 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,285 @@ + + + +partial_eq_counter_without_region.main - Coverage Spans + + + +
fn main() @0,1,2,3,4,5,6,7,8⦊{ + let version_3_2_1 = Version::new(3, 2, 1); + let version_3_3_0 = Version::new(3, 3, 0); + + println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); +}⦉@0,1,2,3,4,5,6,7,8
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ee6a5489f267b --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html @@ -0,0 +1,94 @@ + + + +partial_eq_counter_without_region.{impl#0}-new - Coverage Spans + + + +
pub fn new(major: usize, minor: usize, patch: usize) -> Self { + @0⦊Self { + major, + minor, + patch, + } + }⦉@0
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a39772288a3e7 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -0,0 +1,70 @@ + + + +partial_eq_counter_without_region.{impl#1}-cmp - Coverage Spans + + + +
@14⦊@11,12⦊@10⦊@13⦊Ord⦉@13⦉@10⦉@11,12⦉@14@15⦊‸⦉@15
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..671cbea0ff305 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..6da79c4b130cb --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..5f5c31ce77591 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..fbdd0f7db42b4 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..736f203433333 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..0fec7c9932f22 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ff4eba107892b --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ccc86a7f92fea --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-le-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..682b9112c4cf8 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-le - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..e018c96c24f22 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a10032059b59e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..89dad0f90698c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..2c03e967eeb92 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-partial_cmp - Coverage Spans + + + +
@17⦊@14,15⦊@12⦊@16⦊PartialOrd⦉@16⦉@12⦉@14,15⦉@17@18⦊‸⦉@18
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..49d73b3457b7c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html @@ -0,0 +1,65 @@ + + + +partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq - Coverage Spans + + + +
@0⦊Eq⦉@0
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..bc34080f10974 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html @@ -0,0 +1,67 @@ + + + +partial_eq_counter_without_region.{impl#6}-eq - Coverage Spans + + + +
@2⦊@1⦊PartialEq⦉@1⦉@2@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..376c8dd80d096 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html @@ -0,0 +1,71 @@ + + + +partial_eq_counter_without_region.{impl#6}-ne - Coverage Spans + + + +
@2⦊@5⦊@6⦊@1⦊PartialEq⦉@1⦉@6⦉@5⦉@2@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..c3fed16a3b4ee --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html @@ -0,0 +1,99 @@ + + + +partial_eq_counter_without_region.{impl#7}-fmt - Coverage Spans + + + +
@0,1,2,3,4,5⦊Debug⦉@0,1,2,3,4,5
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..6a4f11e075446 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html @@ -0,0 +1,78 @@ + + + +partial_eq_counter_without_region.{impl#8}-clone - Coverage Spans + + + +
@0,1,2,3⦊Clone⦉@0,1,2,3
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html index 4b21d3fc263a3..618f84513e908 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html @@ -89,39 +89,45 @@ @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7">@4,6⦊{
countdown +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> countdown
= +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> = 10 +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> 10 ; +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> ; }⦉@4,6 +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 loop { if - @8,9⦊countdown - == - 0⦉@8,9 { - @10,12⦊break⦉@10,12 + @10,12⦊break⦉@10,12 ; } - @11⦊countdown - -= - 1⦉@11 + @13⦊countdown + -= + 1⦉@13 ; - } + }@7⦊‸⦉@7 }@10,12⦊‸⦉@10,12 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html index 5ba770ef6078e..66885d0612bfc 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html @@ -86,51 +86,39 @@ 9:9-9:22: @3[3]: FakeRead(ForLet, _5)"> let mut countdown = 1⦉@0,1,2,3; if @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown = 0; +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> countdown = 0; }⦉@4,6 +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 - @9,10,11⦊for - _⦉@9,10,11 + for + @13,15,17⦊_⦉@13,15,17 in - @7,8⦊0..2⦉@7,8 + @9,10,11⦊0..2⦉@9,10,11 { let z ; match - @13,15,17⦊countdown - { - x - if - x - @13,15,17⦊countdown⦉@13,15,17 + { + @18⦊x⦉@18 + if + @13,15,17⦊x + < - 1⦉@13,15,17 + 1⦉@13,15,17@19⦊‸⦉@19 => => @16⦊{}⦉@16 } - } + }@7,8⦊‸⦉@7,8@20⦊‸⦉@20 }@12⦊‸⦉@12 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..db08315baa65e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,70 @@ + + + +tight_infinite_loop.main - Coverage Spans + + + +
fn main() { + if @0⦊false⦉@0 { + @4,5⦊loop {}⦉@4,5@1,3⦊‸⦉@1,3@4,5⦊‸⦉@4,5 + } +}@2⦊‸⦉@2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 9f9933423406e..8a0b1ae8dab11 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -67,7 +67,7 @@ } else { @2⦊Ok(())⦉@2 - } -}@4⦊‸⦉@4 + }@1,3⦊‸⦉@1,3 +}@4⦊‸⦉@4 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index 660c3031f3592..428c6fadc2741 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -65,37 +65,51 @@ countdown = 10⦉@0,1
; - @2,3,4⦊for - _⦉@2,3,4 + for + @6,8⦊_⦉@6,8 in - @0,1⦊0..10⦉@0,1 + @2,3,4⦊0..10⦉@2,3,4 { - @6,8⦊countdown - -= 1⦉@6,8 - ; - if - @9⦊countdown < 5⦉@9 +25:13-25:26: @9[6]: FakeRead(ForMatchedPlace, _18)">@9⦊countdown + -= 1 + ; + if + countdown < 5⦉@9
{ - @10,12,13,14⦊call(/*return_error=*/ true)?⦉@10,12,13,14; + @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; } else { - @11,21,22⦊call(/*return_error=*/ false)?⦉@11,21,22; - } - } - @11,21,22⦊call(/*return_error=*/ false)⦉@11,21,22@24,26,27,28⦊?⦉@24,26,27,28; + }@15⦊‸⦉@15@23⦊‸⦉@23 + }@0,1⦊‸⦉@0,1@29⦊‸⦉@29 + @5⦊Ok(())⦉@5 -}@31⦊‸⦉@31 +}@30⦊‸⦉@30@31⦊‸⦉@31 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html index 28f1d013c835f..b9f6f4d7832b6 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html @@ -64,32 +64,42 @@ 4:9-4:22: @0[2]: FakeRead(ForLet, _1)">@0⦊mut countdown = 0⦉@0;
if @0⦊true⦉@0 @1,3⦊{ +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4"> }⦉@1,3@2⦊‸⦉@2 const B: u32 = 100; - let @25⦊x⦉@25 = if let @25⦊x⦉@25 = if @4⦊countdown > 7⦉@4 { - @5,7⦊countdown -= 4⦉@5,7; - @8⦊B⦉@8 + @8⦊countdown -= 4; + B⦉@8 } else if @6⦊countdown > 2⦉@6 { if @9,11⦊countdown < 1⦉@9,11 || @18⦊countdown > 5⦉@18 || @14⦊countdown != 9⦉@14 @20,22⦊{ +14:29-14:42: @18[3]: _15 = Gt(move _16, const 5_u32)">@18⦊countdown > 5⦉@18@16⦊‸⦉@16@17⦊‸⦉@17 || @14⦊countdown != 9⦉@14@12⦊‸⦉@12@13⦊‸⦉@13 @20,22⦊{ countdown = 0; +14:61-16:10: @22[1]: _10 = const () +16:10-16:10: @22.Goto: goto -> bb23"> countdown = 0; }⦉@20,22 - @23⦊countdown -= 5⦉@23; - @24⦊countdown⦉@24 +14:61-16:10: @22[1]: _10 = const () +16:10-16:10: @22.Goto: goto -> bb23"> }⦉@20,22@21⦊‸⦉@21 + @24⦊countdown -= 5; + countdown⦉@24 } else { @10⦊return⦉@10; }; @@ -98,29 +108,35 @@ 23:9-23:22: @25[4]: FakeRead(ForLet, _21)">@25⦊mut countdown = 0⦉@25; if @25⦊true⦉@25 @26,28⦊{ +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29">@26,28⦊{ countdown = 10; +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29"> countdown = 10; }⦉@26,28 +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29"> }⦉@26,28@27⦊‸⦉@27 - if if @29⦊countdown > 7⦉@29 { - @30,32⦊countdown -= 4⦉@30,32; - } else if @33⦊countdown -= 4⦉@33; + } else if @31⦊countdown > 2⦉@31 { - if @34,36⦊countdown < 1⦉@34,36 || @43⦊countdown > 5⦉@43 || @39⦊countdown != 9⦉@39 @45,47⦊{ - countdown = 0; - }⦉@45,47 - @48⦊countdown -= 5⦉@48; + if @34,36⦊countdown < 1⦉@34,36 || @43⦊countdown > 5⦉@43@41⦊‸⦉@41@42⦊‸⦉@42 || @39⦊countdown != 9⦉@39@37⦊‸⦉@37@38⦊‸⦉@38 @45,47⦊{ + countdown = 0; + }⦉@45,47@46⦊‸⦉@46 + @49⦊countdown -= 5⦉@49; } else { @35⦊return⦉@35; } @@ -129,29 +145,35 @@ 39:9-39:22: @50[4]: FakeRead(ForLet, _41)">@50⦊mut countdown = 0⦉@50; if @50⦊true⦉@50 @51,53⦊{ +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54">@51,53⦊{ countdown = 1; +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54"> countdown = 1; }⦉@51,53 +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54"> }⦉@51,53@52⦊‸⦉@52 - let @77⦊z⦉@77 = if let @77⦊z⦉@77 = if @54⦊countdown > 7⦉@54 { - @55,57⦊countdown -= 4⦉@55,57; - } else if @58⦊countdown -= 4⦉@58; + } else if @56⦊countdown > 2⦉@56 { - if @59,61⦊countdown < 1⦉@59,61 || @68⦊countdown > 5⦉@68 || @64⦊countdown != 9⦉@64 @70,72⦊{ - countdown = 0; - }⦉@70,72 - @73⦊countdown -= 5⦉@73; + if @59,61⦊countdown < 1⦉@59,61 || @68⦊countdown > 5⦉@68@66⦊‸⦉@66@67⦊‸⦉@67 || @64⦊countdown != 9⦉@64@62⦊‸⦉@62@63⦊‸⦉@63 @70,72⦊{ + countdown = 0; + }⦉@70,72@71⦊‸⦉@71 + @74⦊countdown -= 5⦉@74; } else { let let @98⦊w⦉@98 = if @77⦊countdown > 7⦉@77 { - @78,80⦊countdown -= 4⦉@78,80; + @81⦊countdown -= 4⦉@81; } else if @79⦊countdown > 2⦉@79 { if @82,84⦊countdown < 1⦉@82,84 || @91⦊countdown > 5⦉@91 || @87⦊countdown != 9⦉@87 @93,95⦊{ +60:29-60:42: @91[3]: _85 = Gt(move _86, const 5_i32)">@91⦊countdown > 5⦉@91@89⦊‸⦉@89@90⦊‸⦉@90 || @87⦊countdown != 9⦉@87@85⦊‸⦉@85@86⦊‸⦉@86 @93,95⦊{ countdown = 0; +60:61-62:10: @95[1]: _80 = const () +62:10-62:10: @95.Goto: goto -> bb96"> countdown = 0; }⦉@93,95 - @96⦊countdown -= 5⦉@96; +60:61-62:10: @95[1]: _80 = const () +62:10-62:10: @95.Goto: goto -> bb96"> }⦉@93,95@94⦊‸⦉@94 + @97⦊countdown -= 5⦉@97; } else { - @83⦊return⦉@83; + @83⦊return⦉@83; }; -}@102⦊‸⦉@102 +}@101⦊‸⦉@101@102⦊‸⦉@102 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..5c49ec1970756 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,71 @@ + + + +while.main - Coverage Spans + + + +
fn main() { + let @0⦊num = 9⦉@0; + while @1,2⦊num >= 10⦉@1,2 @3,5⦊{ + }⦉@3,5@3,5⦊‸⦉@3,5 +}@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index b96789a92194d..be674dc7d38c7 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -62,12 +62,10 @@
fn main() -> Result<(),u8> { let @0⦊mut countdown = 10⦉@0; - while + @1,2⦊while - countdown +7:9-9:10: @2[5]: FakeRead(ForMatchedPlace, _4)">@1,2⦊countdown > @@ -104,16 +102,16 @@ else { @10⦊Err(1)⦉@10 - } + }@9,11⦊‸⦉@9,11 ; } - @7⦊countdown - -= - 1⦉@7 + @12⦊countdown + -= + 1⦉@12 ; } - @4⦊Ok(())⦉@4 -}@14⦊‸⦉@14
+}@13⦊‸⦉@13@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html index 43f75c574d0ee..0f076a93c0977 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 35:13-35:26: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +36:21-38:10: @3[1]: _3 = const () +38:10-38:10: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +36:21-38:10: @3[1]: _3 = const () +38:10-38:10: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 2".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html index 8f07ec5fcde66..bc78a604e311e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 77:13-77:26: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +78:21-80:10: @3[1]: _3 = const () +80:10-80:10: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +78:21-80:10: @3[1]: _3 = const () +80:10-80:10: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 4".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html index ca9031a1094a4..b0db2311730b0 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 20:21-20:34: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +21:29-23:18: @3[1]: _3 = const () +23:18-23:18: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +21:29-23:18: @3[1]: _3 = const () +23:18-23:18: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 1".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html index 820f8d9c6cf8f..ca07a8d3ce5b8 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html @@ -65,16 +65,19 @@ 62:21-62:34: @0[2]: FakeRead(ForLet, _2)">@0⦊mut countdown = 0⦉@0; if @0⦊is_false⦉@0 @1,3⦊{ +63:29-65:18: @3[1]: _3 = const () +65:18-65:18: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +63:29-65:18: @3[1]: _3 = const () +65:18-65:18: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 - }⦉@1,3@2⦊‸⦉@2 + @4,5⦊"alt string 3".to_owned() - }⦉@4,5 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 494e6f20ea763..325b6c64345a4 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -114,6 +114,6 @@ Ok(())⦉@2,6,7,8 -}@11⦊‸⦉@11 +}@1,3,4,5,9,10⦊‸⦉@1,3,4,5,9,10@2,6,7,8⦊‸⦉@2,6,7,8@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 6dc893d28ff52..55d7e8bfbae18 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -162,6 +162,6 @@ Ok(())⦉@5,9,10,11 -}@14⦊‸⦉@14 +}@4,6,7,8,12,13⦊‸⦉@4,6,7,8,12,13@5,9,10,11⦊‸⦉@5,9,10,11@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html index 0379d900e9409..0d4b940214e39 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html @@ -146,17 +146,23 @@ @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> countdown = +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> = 10 +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> 10 ; +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> ; }⦉@4,6 -}@7⦊‸⦉@7 +22:5-27:6: @6[1]: _0 = const () +27:6-27:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 +}@7⦊‸⦉@7 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index b51c5c84c0d6e..094dacde9868d 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -128,36 +128,36 @@ 20:9-22:16: @5[1]: _6 = const ()"> = 100⦉@5 - } + }@4,6⦊‸⦉@4,6 if - @7⦊is_true⦉@7 - @8,10⦊{ - countdown - = - 10 - ; - }⦉@8,10 else - @9⦊{ - countdown - = - 100 - ; - }⦉@9 + }⦉@9@8,10⦊‸⦉@8,10 }@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html index 49639cc6884ba..7f1262a6abf0a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html @@ -63,8 +63,7 @@ let @0⦊b = 1⦉@0; let @1,2,3,4⦊c⦉@1,2,3,4 = @0⦊a + b⦉@0; +20:21-20:22: @0[7]: _5 = _2">@0⦊a + b⦉@0; fn trait_func(&mut self, incr: u32) { - @0⦊self.in_struct_field += incr⦉@0; + self.in_struct_field += @0⦊incr⦉@0; @1,2⦊in_func(self.in_struct_field); diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html index 56557b8ef955e..ec3517ec9eddd 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html @@ -86,11 +86,14 @@ 9:9-9:22: @3[3]: FakeRead(ForLet, _5)"> let mut countdown = 0⦉@0,1,2,3; if @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown = 10; +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> countdown = 10; }⦉@4,6 +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 mod in_mod { const IN_MOD_CONST: u32 = 1000; @@ -126,16 +129,19 @@ type InType = String; - if @7⦊is_true⦉@7 if @7⦊is_true⦉@7 @8,10,11⦊{ -@8,10,11⦊{ + in_func(countdown); - in_func(countdown); + }⦉@8,10,11 +48:16-50:6: @11[2]: _8 = const () +50:6-50:6: @11.Goto: goto -> bb12"> }⦉@8,10,11@9⦊‸⦉@9 let // Initialize test constants in a way that cannot be determined at compile time, to ensure // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from // dependent conditions. - let let @0,1,2,3⦊is_true = std::env::args().len() == 1; - -@0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7">@4,6⦊{ a = 1; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> a = 1; b = 10; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> b = 10; c = 100; +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> c = 100; }⦉@4,6 +10:16-14:6: @6[3]: _9 = const () +14:6-14:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 let - @11⦊somebool⦉@11 + @11⦊somebool⦉@11 = - @7⦊a < b⦉@7 || - @10⦊b < c⦉@10 +20:13-20:18: @10[5]: _15 = Lt(move _16, move _17)">@10⦊b < c⦉@10@8⦊‸⦉@8@9⦊‸⦉@9 ; let - @15⦊somebool⦉@15 + @15⦊somebool⦉@15 = - @11⦊b < a⦉@11 || - @14⦊b < c⦉@14 +27:13-27:18: @14[5]: _22 = Lt(move _23, move _24)">@14⦊b < c⦉@14@12⦊‸⦉@12@13⦊‸⦉@13 ; - let - @19⦊somebool⦉@19 - = - @15⦊a < b⦉@15 - && - @18⦊b < c⦉@18 - ; - let - @23⦊somebool⦉@23 - = - @19⦊b < a⦉@19 - && - @22⦊b < c⦉@22 - ; -}@23⦊‸⦉@23 + let @19⦊somebool⦉@19 = @15⦊a < b⦉@15 && @18⦊b < c⦉@18@16⦊‸⦉@16@17⦊‸⦉@17; + let @23⦊somebool⦉@23 = @19⦊b < a⦉@19 && @22⦊b < c⦉@22@20⦊‸⦉@20@21⦊‸⦉@21; + + if + @23⦊! + is_true⦉@23 + @24,26⦊{ + a = 2 + ; + }⦉@24,26@25⦊‸⦉@25 + + if + @27⦊is_true⦉@27 + @28,30⦊{ + b = 30 + ; + }⦉@28,30 + else + @29⦊{ + c = 400 + ; + }⦉@29@28,30⦊‸⦉@28,30 + + if @31⦊!is_true⦉@31 @32,34⦊{ + a = 2; + }⦉@32,34@33⦊‸⦉@33 + + if @35⦊is_true⦉@35 @36,38⦊{ + b = 30; + }⦉@36,38 else @37⦊{ + c = 400; + }⦉@37@36,38⦊‸⦉@36,38 +}@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a876c85822f32 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,151 @@ + + + +loops_and_branches.main - Coverage Spans + + + +
fn main() @0,1,2,3⦊{ + let debug_test = DebugTest; + println!("{:?}", debug_test); +}⦉@0,1,2,3
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..1b9767506f26a --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -0,0 +1,94 @@ + + + +loops_and_branches.{impl#0}-fmt - Coverage Spans + + + +
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if @0⦊true⦉@0 { + if @1,3⦊false⦉@1,3 { + while @6,7⦊true⦉@6,7 @8,10⦊{ + }⦉@8,10 + }@9⦊‸⦉@9@5⦊‸⦉@5 + @11,12,13,14⦊write!(f, "error")⦉@11,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; + } else @2⦊{ + }⦉@2@15⦊‸⦉@15 + @21⦊Ok(())⦉@21 + }@16,18,19,20⦊‸⦉@16,18,19,20@22⦊‸⦉@22
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..042845b70cc30 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,125 @@ + + + +nested_loops.main - Coverage Spans + + + +
fn main() { + let @0,1,2,3⦊is_true = std::env::args().len() == 1; + let mut countdown = 10⦉@0,1,2,3; + + 'outer: while @4,5⦊countdown > 0⦉@4,5 { + let @6,8,9⦊mut a = 100; + let mut b = 100⦉@6,8,9; + for @14,16⦊_⦉@14,16 in @10,11,12⦊0..50⦉@10,11,12 { + if @14,16⦊a < 30⦉@14,16 { + @17,19⦊break⦉@17,19; + } + @20⦊a -= 5⦉@20; + @21⦊b -= 5⦉@21; + if @21⦊b < 90⦉@21 { + @25⦊a -= 10; + if is_true⦉@25 { + @26,28⦊break 'outer⦉@26,28; + } else { + @29⦊a -= 2; + } + }⦉@29@23⦊‸⦉@23 + }@6,8,9⦊‸⦉@6,8,9@30⦊‸⦉@30 + @32⦊countdown -= 1⦉@32; + }@0,1,2,3⦊‸⦉@0,1,2,3@7⦊‸⦉@7 +}@33⦊‸⦉@33
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..3ebe51bc7ec36 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,285 @@ + + + +partial_eq_counter_without_region.main - Coverage Spans + + + +
fn main() @0,1,2,3,4,5,6,7,8⦊{ + let version_3_2_1 = Version::new(3, 2, 1); + let version_3_3_0 = Version::new(3, 3, 0); + + println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); +}⦉@0,1,2,3,4,5,6,7,8
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ee6a5489f267b --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html @@ -0,0 +1,94 @@ + + + +partial_eq_counter_without_region.{impl#0}-new - Coverage Spans + + + +
pub fn new(major: usize, minor: usize, patch: usize) -> Self { + @0⦊Self { + major, + minor, + patch, + } + }⦉@0
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a39772288a3e7 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -0,0 +1,70 @@ + + + +partial_eq_counter_without_region.{impl#1}-cmp - Coverage Spans + + + +
@14⦊@11,12⦊@10⦊@13⦊Ord⦉@13⦉@10⦉@11,12⦉@14@15⦊‸⦉@15
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..671cbea0ff305 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..6da79c4b130cb --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..5f5c31ce77591 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-ge - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..fbdd0f7db42b4 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..736f203433333 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..0fec7c9932f22 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-gt - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ff4eba107892b --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..ccc86a7f92fea --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-le-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..682b9112c4cf8 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-le - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..e018c96c24f22 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0} - Coverage Spans + + + +
minor: usize, + @0,1,2⦊patch: usize⦉@0,1,2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..a10032059b59e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html @@ -0,0 +1,73 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt-{closure#0} - Coverage Spans + + + +
major: usize, + @0,1,2,3⦊‸⦉@0,1,2,3minor: usize
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..89dad0f90698c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html @@ -0,0 +1,82 @@ + + + +partial_eq_counter_without_region.{impl#2}-lt - Coverage Spans + + + +
@0,1,2,3,4⦊‸⦉@0,1,2,3,4PartialOrd@0,1,2,3,4⦊‸⦉@0,1,2,3,4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..2c03e967eeb92 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -0,0 +1,72 @@ + + + +partial_eq_counter_without_region.{impl#2}-partial_cmp - Coverage Spans + + + +
@17⦊@14,15⦊@12⦊@16⦊PartialOrd⦉@16⦉@12⦉@14,15⦉@17@18⦊‸⦉@18
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..49d73b3457b7c --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html @@ -0,0 +1,65 @@ + + + +partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq - Coverage Spans + + + +
@0⦊Eq⦉@0
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..bc34080f10974 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html @@ -0,0 +1,67 @@ + + + +partial_eq_counter_without_region.{impl#6}-eq - Coverage Spans + + + +
@2⦊@1⦊PartialEq⦉@1⦉@2@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..376c8dd80d096 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html @@ -0,0 +1,71 @@ + + + +partial_eq_counter_without_region.{impl#6}-ne - Coverage Spans + + + +
@2⦊@5⦊@6⦊@1⦊PartialEq⦉@1⦉@6⦉@5⦉@2@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..c3fed16a3b4ee --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html @@ -0,0 +1,99 @@ + + + +partial_eq_counter_without_region.{impl#7}-fmt - Coverage Spans + + + +
@0,1,2,3,4,5⦊Debug⦉@0,1,2,3,4,5
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..6a4f11e075446 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html @@ -0,0 +1,78 @@ + + + +partial_eq_counter_without_region.{impl#8}-clone - Coverage Spans + + + +
@0,1,2,3⦊Clone⦉@0,1,2,3
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html index 4b21d3fc263a3..618f84513e908 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html @@ -89,39 +89,45 @@ @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7">@4,6⦊{
countdown +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> countdown
= +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> = 10 +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> 10 ; +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> ; }⦉@4,6 +13:5-18:6: @6[1]: _6 = const () +18:6-18:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 loop { if - @8,9⦊countdown - == - 0⦉@8,9 { - @10,12⦊break⦉@10,12 + @10,12⦊break⦉@10,12 ; } - @11⦊countdown - -= - 1⦉@11 + @13⦊countdown + -= + 1⦉@13 ; - } + }@7⦊‸⦉@7 }@10,12⦊‸⦉@10,12 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html index 5ba770ef6078e..66885d0612bfc 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html @@ -86,51 +86,39 @@ 9:9-9:22: @3[3]: FakeRead(ForLet, _5)"> let mut countdown = 1⦉@0,1,2,3; if @0,1,2,3⦊is_true⦉@0,1,2,3 @4,6⦊{ +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7">@4,6⦊{ countdown = 0; +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> countdown = 0; }⦉@4,6 +10:16-12:6: @6[1]: _6 = const () +12:6-12:6: @6.Goto: goto -> bb7"> }⦉@4,6@5⦊‸⦉@5 - @9,10,11⦊for - _⦉@9,10,11 + for + @13,15,17⦊_⦉@13,15,17 in - @7,8⦊0..2⦉@7,8 + @9,10,11⦊0..2⦉@9,10,11 { let z ; match - @13,15,17⦊countdown - { - x - if - x - @13,15,17⦊countdown⦉@13,15,17 + { + @18⦊x⦉@18 + if + @13,15,17⦊x + < - 1⦉@13,15,17 + 1⦉@13,15,17@19⦊‸⦉@19 => => @16⦊{}⦉@16 } - } + }@7,8⦊‸⦉@7,8@20⦊‸⦉@20 }@12⦊‸⦉@12 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..db08315baa65e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,70 @@ + + + +tight_infinite_loop.main - Coverage Spans + + + +
fn main() { + if @0⦊false⦉@0 { + @4,5⦊loop {}⦉@4,5@1,3⦊‸⦉@1,3@4,5⦊‸⦉@4,5 + } +}@2⦊‸⦉@2
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 9f9933423406e..8a0b1ae8dab11 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -67,7 +67,7 @@ } else { @2⦊Ok(())⦉@2 - } -}@4⦊‸⦉@4 + }@1,3⦊‸⦉@1,3 +}@4⦊‸⦉@4 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index 660c3031f3592..428c6fadc2741 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -65,37 +65,51 @@ countdown = 10⦉@0,1
; - @2,3,4⦊for - _⦉@2,3,4 + for + @6,8⦊_⦉@6,8 in - @0,1⦊0..10⦉@0,1 + @2,3,4⦊0..10⦉@2,3,4 { - @6,8⦊countdown - -= 1⦉@6,8 - ; - if - @9⦊countdown < 5⦉@9 +25:13-25:26: @9[6]: FakeRead(ForMatchedPlace, _18)">@9⦊countdown + -= 1 + ; + if + countdown < 5⦉@9
{ - @10,12,13,14⦊call(/*return_error=*/ true)?⦉@10,12,13,14; + @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; } else { - @11,21,22⦊call(/*return_error=*/ false)?⦉@11,21,22; - } - } - @11,21,22⦊call(/*return_error=*/ false)⦉@11,21,22@24,26,27,28⦊?⦉@24,26,27,28; + }@15⦊‸⦉@15@23⦊‸⦉@23 + }@0,1⦊‸⦉@0,1@29⦊‸⦉@29 + @5⦊Ok(())⦉@5 -}@31⦊‸⦉@31 +}@30⦊‸⦉@30@31⦊‸⦉@31 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html index 28f1d013c835f..b9f6f4d7832b6 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html @@ -64,32 +64,42 @@ 4:9-4:22: @0[2]: FakeRead(ForLet, _1)">@0⦊mut countdown = 0⦉@0;
if @0⦊true⦉@0 @1,3⦊{ +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4">@1,3⦊{ countdown = 10; +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4"> countdown = 10; }⦉@1,3 +5:13-7:6: @3[1]: _2 = const () +7:6-7:6: @3.Goto: goto -> bb4"> }⦉@1,3@2⦊‸⦉@2 const B: u32 = 100; - let @25⦊x⦉@25 = if let @25⦊x⦉@25 = if @4⦊countdown > 7⦉@4 { - @5,7⦊countdown -= 4⦉@5,7; - @8⦊B⦉@8 + @8⦊countdown -= 4; + B⦉@8 } else if @6⦊countdown > 2⦉@6 { if @9,11⦊countdown < 1⦉@9,11 || @18⦊countdown > 5⦉@18 || @14⦊countdown != 9⦉@14 @20,22⦊{ +14:29-14:42: @18[3]: _15 = Gt(move _16, const 5_u32)">@18⦊countdown > 5⦉@18@16⦊‸⦉@16@17⦊‸⦉@17 || @14⦊countdown != 9⦉@14@12⦊‸⦉@12@13⦊‸⦉@13 @20,22⦊{ countdown = 0; +14:61-16:10: @22[1]: _10 = const () +16:10-16:10: @22.Goto: goto -> bb23"> countdown = 0; }⦉@20,22 - @23⦊countdown -= 5⦉@23; - @24⦊countdown⦉@24 +14:61-16:10: @22[1]: _10 = const () +16:10-16:10: @22.Goto: goto -> bb23"> }⦉@20,22@21⦊‸⦉@21 + @24⦊countdown -= 5; + countdown⦉@24 } else { @10⦊return⦉@10; }; @@ -98,29 +108,35 @@ 23:9-23:22: @25[4]: FakeRead(ForLet, _21)">@25⦊mut countdown = 0⦉@25; if @25⦊true⦉@25 @26,28⦊{ +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29">@26,28⦊{ countdown = 10; +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29"> countdown = 10; }⦉@26,28 +24:13-26:6: @28[1]: _22 = const () +26:6-26:6: @28.Goto: goto -> bb29"> }⦉@26,28@27⦊‸⦉@27 - if if @29⦊countdown > 7⦉@29 { - @30,32⦊countdown -= 4⦉@30,32; - } else if @33⦊countdown -= 4⦉@33; + } else if @31⦊countdown > 2⦉@31 { - if @34,36⦊countdown < 1⦉@34,36 || @43⦊countdown > 5⦉@43 || @39⦊countdown != 9⦉@39 @45,47⦊{ - countdown = 0; - }⦉@45,47 - @48⦊countdown -= 5⦉@48; + if @34,36⦊countdown < 1⦉@34,36 || @43⦊countdown > 5⦉@43@41⦊‸⦉@41@42⦊‸⦉@42 || @39⦊countdown != 9⦉@39@37⦊‸⦉@37@38⦊‸⦉@38 @45,47⦊{ + countdown = 0; + }⦉@45,47@46⦊‸⦉@46 + @49⦊countdown -= 5⦉@49; } else { @35⦊return⦉@35; } @@ -129,29 +145,35 @@ 39:9-39:22: @50[4]: FakeRead(ForLet, _41)">@50⦊mut countdown = 0⦉@50; if @50⦊true⦉@50 @51,53⦊{ +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54">@51,53⦊{ countdown = 1; +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54"> countdown = 1; }⦉@51,53 +40:13-42:6: @53[1]: _42 = const () +42:6-42:6: @53.Goto: goto -> bb54"> }⦉@51,53@52⦊‸⦉@52 - let @77⦊z⦉@77 = if let @77⦊z⦉@77 = if @54⦊countdown > 7⦉@54 { - @55,57⦊countdown -= 4⦉@55,57; - } else if @58⦊countdown -= 4⦉@58; + } else if @56⦊countdown > 2⦉@56 { - if @59,61⦊countdown < 1⦉@59,61 || @68⦊countdown > 5⦉@68 || @64⦊countdown != 9⦉@64 @70,72⦊{ - countdown = 0; - }⦉@70,72 - @73⦊countdown -= 5⦉@73; + if @59,61⦊countdown < 1⦉@59,61 || @68⦊countdown > 5⦉@68@66⦊‸⦉@66@67⦊‸⦉@67 || @64⦊countdown != 9⦉@64@62⦊‸⦉@62@63⦊‸⦉@63 @70,72⦊{ + countdown = 0; + }⦉@70,72@71⦊‸⦉@71 + @74⦊countdown -= 5⦉@74; } else { let let @98⦊w⦉@98 = if @77⦊countdown > 7⦉@77 { - @78,80⦊countdown -= 4⦉@78,80; + @81⦊countdown -= 4⦉@81; } else if @79⦊countdown > 2⦉@79 { if @82,84⦊countdown < 1⦉@82,84 || @91⦊countdown > 5⦉@91 || @87⦊countdown != 9⦉@87 @93,95⦊{ +60:29-60:42: @91[3]: _85 = Gt(move _86, const 5_i32)">@91⦊countdown > 5⦉@91@89⦊‸⦉@89@90⦊‸⦉@90 || @87⦊countdown != 9⦉@87@85⦊‸⦉@85@86⦊‸⦉@86 @93,95⦊{ countdown = 0; +60:61-62:10: @95[1]: _80 = const () +62:10-62:10: @95.Goto: goto -> bb96"> countdown = 0; }⦉@93,95 - @96⦊countdown -= 5⦉@96; +60:61-62:10: @95[1]: _80 = const () +62:10-62:10: @95.Goto: goto -> bb96"> }⦉@93,95@94⦊‸⦉@94 + @97⦊countdown -= 5⦉@97; } else { - @83⦊return⦉@83; + @83⦊return⦉@83; }; -}@102⦊‸⦉@102 +}@101⦊‸⦉@101@102⦊‸⦉@102 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html new file mode 100644 index 0000000000000..5c49ec1970756 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -0,0 +1,71 @@ + + + +while.main - Coverage Spans + + + +
fn main() { + let @0⦊num = 9⦉@0; + while @1,2⦊num >= 10⦉@1,2 @3,5⦊{ + }⦉@3,5@3,5⦊‸⦉@3,5 +}@4⦊‸⦉@4
+ + diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index b96789a92194d..be674dc7d38c7 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -62,12 +62,10 @@
fn main() -> Result<(),u8> { let @0⦊mut countdown = 10⦉@0; - while + @1,2⦊while - countdown +7:9-9:10: @2[5]: FakeRead(ForMatchedPlace, _4)">@1,2⦊countdown > @@ -104,16 +102,16 @@ else { @10⦊Err(1)⦉@10 - } + }@9,11⦊‸⦉@9,11 ; } - @7⦊countdown - -= - 1⦉@7 + @12⦊countdown + -= + 1⦉@12 ; } - @4⦊Ok(())⦉@4 -}@14⦊‸⦉@14
+}@13⦊‸⦉@13@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage/lazy_boolean.rs b/src/test/run-make-fulldeps/coverage/lazy_boolean.rs index 1d83eb30dea24..bb6219e851c8a 100644 --- a/src/test/run-make-fulldeps/coverage/lazy_boolean.rs +++ b/src/test/run-make-fulldeps/coverage/lazy_boolean.rs @@ -26,18 +26,36 @@ fn main() { || b < c ; - let - somebool - = - a < b - && - b < c - ; - let - somebool - = - b < a - && - b < c - ; + let somebool = a < b && b < c; + let somebool = b < a && b < c; + + if + ! + is_true + { + a = 2 + ; + } + + if + is_true + { + b = 30 + ; + } + else + { + c = 400 + ; + } + + if !is_true { + a = 2; + } + + if is_true { + b = 30; + } else { + c = 400; + } } diff --git a/src/test/run-make-fulldeps/coverage/loops_and_branches.rs b/src/test/run-make-fulldeps/coverage/loops_and_branches.rs new file mode 100644 index 0000000000000..a9df7e0fab75f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/loops_and_branches.rs @@ -0,0 +1,36 @@ +#![allow(unused_assignments)] + +// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the +// structure of this `fmt` function. + +struct DebugTest; + +impl std::fmt::Debug for DebugTest { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if true { + if false { + while true { + } + } + write!(f, "error")?; + } else { + } + Ok(()) + } +} + +fn main() { + let debug_test = DebugTest; + println!("{:?}", debug_test); +} + +/* + +This is the error message generated, before the issue was fixed: + +error: internal compiler error: compiler/rustc_mir/src/transform/coverage/mod.rs:374:42: +Error processing: DefId(0:6 ~ bug_incomplete_cov_graph_traversal_simplified[317d]::{impl#0}::fmt): +Error { message: "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: +[bcb6, bcb7, bcb9]" } + +*/ diff --git a/src/test/run-make-fulldeps/coverage/nested_loops.rs b/src/test/run-make-fulldeps/coverage/nested_loops.rs new file mode 100644 index 0000000000000..4c7c784279650 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/nested_loops.rs @@ -0,0 +1,25 @@ +fn main() { + let is_true = std::env::args().len() == 1; + let mut countdown = 10; + + 'outer: while countdown > 0 { + let mut a = 100; + let mut b = 100; + for _ in 0..50 { + if a < 30 { + break; + } + a -= 5; + b -= 5; + if b < 90 { + a -= 10; + if is_true { + break 'outer; + } else { + a -= 2; + } + } + } + countdown -= 1; + } +} diff --git a/src/test/run-make-fulldeps/coverage/partial_eq_counter_without_region.rs b/src/test/run-make-fulldeps/coverage/partial_eq_counter_without_region.rs new file mode 100644 index 0000000000000..334fb3364ccc4 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/partial_eq_counter_without_region.rs @@ -0,0 +1,99 @@ +// This test confirms an earlier problem was resolved, supporting the MIR graph generated by the +// structure of this test. + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct Version { + major: usize, + minor: usize, + patch: usize, +} + +impl Version { + pub fn new(major: usize, minor: usize, patch: usize) -> Self { + Self { + major, + minor, + patch, + } + } +} + +fn main() { + let version_3_2_1 = Version::new(3, 2, 1); + let version_3_3_0 = Version::new(3, 3, 0); + + println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version_3_3_0); +} + +/* + +This test verifies a bug was fixed that otherwise generated this error: + +thread 'rustc' panicked at 'No counters provided the source_hash for function: + Instance { + def: Item(WithOptConstParam { + did: DefId(0:101 ~ autocfg[c44a]::version::{impl#2}::partial_cmp), + const_param_did: None + }), + substs: [] + }' +The `PartialOrd` derived by `Version` happened to generate a MIR that generated coverage +without a code region associated with any `Counter`. Code regions were associated with at least +one expression, which is allowed, but the `function_source_hash` was only passed to the codegen +(coverage mapgen) phase from a `Counter`s code region. A new method was added to pass the +`function_source_hash` without a code region, if necessary. + +*/ + +// FIXME(richkadel): It may be worth investigating why the coverage report for this test produces +// the following results: + +/* + +1. Why are their two counts below different characters (first and last) of `PartialOrd`, on line 17? + +2. Line 17 is counted twice, but the `::lt` instance shows a line count of 1? Is there a missing + line count with a different instance? Or was it really only called once? + +3. Line 20 shows another line count (of 1) for a line within a `struct` declaration (on only one of + its 3 fields). I doubt the specific field (`minor`) is relevant, but rather I suspect there's a + problem computing the file position here, for some reason. + + + 16| | + 17| 2|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + ^1 ^1 +------------------ +|Unexecuted instantiation: ::gt +------------------ +|Unexecuted instantiation: ::le +------------------ +|Unexecuted instantiation: ::ge +------------------ +|::lt: +| 17| 1|#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +------------------ + 18| |pub struct Version { + 19| | major: usize, + 20| 1| minor: usize, + 21| | patch: usize, + 22| |} + 23| | + 24| |impl Version { + 25| | pub fn new(major: usize, minor: usize, patch: usize) -> Self { + 26| 2| Version { + 27| 2| major, + 28| 2| minor, + 29| 2| patch, + 30| 2| } + 31| 2| } + 32| |} + 33| | + 34| 1|fn main() { + 35| 1| let version_3_2_1 = Version::new(3, 2, 1); + 36| 1| let version_3_3_0 = Version::new(3, 3, 0); + 37| 1| + 38| 1| println!("{:?} < {:?} = {}", version_3_2_1, version_3_3_0, version_3_2_1 < version +_3_3_0); + 39| 1|} +*/ diff --git a/src/test/run-make-fulldeps/coverage/tight_infinite_loop.rs b/src/test/run-make-fulldeps/coverage/tight_infinite_loop.rs new file mode 100644 index 0000000000000..cef99027aaa4f --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/tight_infinite_loop.rs @@ -0,0 +1,5 @@ +fn main() { + if false { + loop {} + } +} diff --git a/src/test/run-make-fulldeps/coverage/while.rs b/src/test/run-make-fulldeps/coverage/while.rs new file mode 100644 index 0000000000000..781b90b35663e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/while.rs @@ -0,0 +1,5 @@ +fn main() { + let num = 9; + while num >= 10 { + } +} From 0bb09c114e48e7f1af5679a79ff26746f3b4bd64 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Fri, 23 Oct 2020 00:45:07 -0700 Subject: [PATCH 14/27] Splitting transform/instrument_coverage.rs into transform/coverage/... --- .../src/transform/coverage/counters.rs | 54 ++ .../rustc_mir/src/transform/coverage/debug.rs | 70 ++ .../rustc_mir/src/transform/coverage/graph.rs | 274 +++++++ .../rustc_mir/src/transform/coverage/mod.rs | 241 ++++++ .../rustc_mir/src/transform/coverage/query.rs | 113 +++ .../spans.rs} | 738 +----------------- compiler/rustc_mir/src/transform/mod.rs | 6 +- 7 files changed, 766 insertions(+), 730 deletions(-) create mode 100644 compiler/rustc_mir/src/transform/coverage/counters.rs create mode 100644 compiler/rustc_mir/src/transform/coverage/debug.rs create mode 100644 compiler/rustc_mir/src/transform/coverage/graph.rs create mode 100644 compiler/rustc_mir/src/transform/coverage/mod.rs create mode 100644 compiler/rustc_mir/src/transform/coverage/query.rs rename compiler/rustc_mir/src/transform/{instrument_coverage.rs => coverage/spans.rs} (52%) diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs new file mode 100644 index 0000000000000..511ad937c248f --- /dev/null +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -0,0 +1,54 @@ +use rustc_middle::mir::coverage::*; + +/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR +/// `Coverage` statements. +pub(crate) struct CoverageCounters { + function_source_hash: u64, + next_counter_id: u32, + num_expressions: u32, +} + +impl CoverageCounters { + pub fn new(function_source_hash: u64) -> Self { + Self { + function_source_hash, + next_counter_id: CounterValueReference::START.as_u32(), + num_expressions: 0, + } + } + + pub fn make_counter(&mut self) -> CoverageKind { + CoverageKind::Counter { + function_source_hash: self.function_source_hash, + id: self.next_counter(), + } + } + + pub fn make_expression( + &mut self, + lhs: ExpressionOperandId, + op: Op, + rhs: ExpressionOperandId, + ) -> CoverageKind { + let id = self.next_expression(); + CoverageKind::Expression { id, lhs, op, rhs } + } + + /// Counter IDs start from one and go up. + fn next_counter(&mut self) -> CounterValueReference { + assert!(self.next_counter_id < u32::MAX - self.num_expressions); + let next = self.next_counter_id; + self.next_counter_id += 1; + CounterValueReference::from(next) + } + + /// Expression IDs start from u32::MAX and go down because a Expression can reference + /// (add or subtract counts) of both Counter regions and Expression regions. The counter + /// expression operand IDs must be unique across both types. + fn next_expression(&mut self) -> InjectedExpressionId { + assert!(self.next_counter_id < u32::MAX - self.num_expressions); + let next = u32::MAX - self.num_expressions; + self.num_expressions += 1; + InjectedExpressionId::from(next) + } +} diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs new file mode 100644 index 0000000000000..0cd2e413da944 --- /dev/null +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -0,0 +1,70 @@ +use super::graph::BasicCoverageBlocks; +use super::spans::CoverageSpan; + +use crate::util::pretty; +use crate::util::spanview::{self, SpanViewable}; + +use rustc_middle::mir::{self, TerminatorKind}; +use rustc_middle::ty::TyCtxt; + +/// Generates the MIR pass `CoverageSpan`-specific spanview dump file. +pub(crate) fn dump_coverage_spanview( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + basic_coverage_blocks: &BasicCoverageBlocks, + pass_name: &str, + coverage_spans: &Vec, +) { + let mir_source = mir_body.source; + let def_id = mir_source.def_id(); + + let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans); + let mut file = pretty::create_dump_file(tcx, "html", None, pass_name, &0, mir_source) + .expect("Unexpected error creating MIR spanview HTML file"); + let crate_name = tcx.crate_name(def_id.krate); + let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate(); + let title = format!("{}.{} - Coverage Spans", crate_name, item_name); + spanview::write_document(tcx, def_id, span_viewables, &title, &mut file) + .expect("Unexpected IO error dumping coverage spans as HTML"); +} + +/// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s. +fn span_viewables( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + basic_coverage_blocks: &BasicCoverageBlocks, + coverage_spans: &Vec, +) -> Vec { + let mut span_viewables = Vec::new(); + for coverage_span in coverage_spans { + let tooltip = coverage_span.format_coverage_statements(tcx, mir_body); + let CoverageSpan { span, bcb_leader_bb: bb, .. } = coverage_span; + let bcb = &basic_coverage_blocks[*bb]; + let id = bcb.id(); + let leader_bb = bcb.leader_bb(); + span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip }); + } + span_viewables +} + +/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any +/// values it might hold. +pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { + match kind { + TerminatorKind::Goto { .. } => "Goto", + TerminatorKind::SwitchInt { .. } => "SwitchInt", + TerminatorKind::Resume => "Resume", + TerminatorKind::Abort => "Abort", + TerminatorKind::Return => "Return", + TerminatorKind::Unreachable => "Unreachable", + TerminatorKind::Drop { .. } => "Drop", + TerminatorKind::DropAndReplace { .. } => "DropAndReplace", + TerminatorKind::Call { .. } => "Call", + TerminatorKind::Assert { .. } => "Assert", + TerminatorKind::Yield { .. } => "Yield", + TerminatorKind::GeneratorDrop => "GeneratorDrop", + TerminatorKind::FalseEdge { .. } => "FalseEdge", + TerminatorKind::FalseUnwind { .. } => "FalseUnwind", + TerminatorKind::InlineAsm { .. } => "InlineAsm", + } +} diff --git a/compiler/rustc_mir/src/transform/coverage/graph.rs b/compiler/rustc_mir/src/transform/coverage/graph.rs new file mode 100644 index 0000000000000..c0a698833a1fe --- /dev/null +++ b/compiler/rustc_mir/src/transform/coverage/graph.rs @@ -0,0 +1,274 @@ +use rustc_index::bit_set::BitSet; +use rustc_index::vec::IndexVec; +use rustc_middle::mir::{self, BasicBlock, BasicBlockData, TerminatorKind}; + +const ID_SEPARATOR: &str = ","; + +/// A BasicCoverageBlock (BCB) represents the maximal-length sequence of CFG (MIR) BasicBlocks +/// without conditional branches. +/// +/// The BCB allows coverage analysis to be performed on a simplified projection of the underlying +/// MIR CFG, without altering the original CFG. Note that running the MIR `SimplifyCfg` transform, +/// is not sufficient, and therefore not necessary, since the BCB-based CFG projection is a more +/// aggressive simplification. For example: +/// +/// * The BCB CFG projection ignores (trims) branches not relevant to coverage, such as unwind- +/// related code that is injected by the Rust compiler but has no physical source code to +/// count. This also means a BasicBlock with a `Call` terminator can be merged into its +/// primary successor target block, in the same BCB. +/// * Some BasicBlock terminators support Rust-specific concerns--like borrow-checking--that are +/// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as +/// a `Goto`, and merged with its successor into the same BCB. +/// +/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`. +/// In some cases, a BCB's execution count can be computed by `CounterExpression`. Additional +/// disjoint `CoverageSpan`s in a BCB can also be counted by `CounterExpression` (by adding `ZERO` +/// to the BCB's primary counter or expression). +/// +/// Dominator/dominated relationships (which are fundamental to the coverage analysis algorithm) +/// between two BCBs can be computed using the `mir::Body` `dominators()` with any `BasicBlock` +/// member of each BCB. (For consistency, BCB's use the first `BasicBlock`, also referred to as the +/// `bcb_leader_bb`.) +/// +/// The BCB CFG projection is critical to simplifying the coverage analysis by ensuring graph +/// path-based queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch +/// (control flow) significance. +#[derive(Debug, Clone)] +pub(crate) struct BasicCoverageBlock { + pub blocks: Vec, +} + +impl BasicCoverageBlock { + pub fn leader_bb(&self) -> BasicBlock { + self.blocks[0] + } + + pub fn id(&self) -> String { + format!( + "@{}", + self.blocks + .iter() + .map(|bb| bb.index().to_string()) + .collect::>() + .join(ID_SEPARATOR) + ) + } +} + +pub(crate) struct BasicCoverageBlocks { + vec: IndexVec>, +} + +impl BasicCoverageBlocks { + pub fn from_mir(mir_body: &mir::Body<'tcx>) -> Self { + let mut basic_coverage_blocks = + BasicCoverageBlocks { vec: IndexVec::from_elem_n(None, mir_body.basic_blocks().len()) }; + basic_coverage_blocks.extract_from_mir(mir_body); + basic_coverage_blocks + } + + pub fn iter(&self) -> impl Iterator { + self.vec.iter().filter_map(|bcb| bcb.as_ref()) + } + + pub fn num_nodes(&self) -> usize { + self.vec.len() + } + + pub fn extract_from_mir(&mut self, mir_body: &mir::Body<'tcx>) { + // Traverse the CFG but ignore anything following an `unwind` + let cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, |term_kind| { + let mut successors = term_kind.successors(); + match &term_kind { + // SwitchInt successors are never unwind, and all of them should be traversed. + + // NOTE: TerminatorKind::FalseEdge targets from SwitchInt don't appear to be + // helpful in identifying unreachable code. I did test the theory, but the following + // changes were not beneficial. (I assumed that replacing some constants with + // non-deterministic variables might effect which blocks were targeted by a + // `FalseEdge` `imaginary_target`. It did not.) + // + // Also note that, if there is a way to identify BasicBlocks that are part of the + // MIR CFG, but not actually reachable, here are some other things to consider: + // + // Injecting unreachable code regions will probably require computing the set + // difference between the basic blocks found without filtering out unreachable + // blocks, and the basic blocks found with the filter; then computing the + // `CoverageSpans` without the filter; and then injecting `Counter`s or + // `CounterExpression`s for blocks that are not unreachable, or injecting + // `Unreachable` code regions otherwise. This seems straightforward, but not + // trivial. + // + // Alternatively, we might instead want to leave the unreachable blocks in + // (bypass the filter here), and inject the counters. This will result in counter + // values of zero (0) for unreachable code (and, notably, the code will be displayed + // with a red background by `llvm-cov show`). + // + // TerminatorKind::SwitchInt { .. } => { + // let some_imaginary_target = successors.clone().find_map(|&successor| { + // let term = mir_body.basic_blocks()[successor].terminator(); + // if let TerminatorKind::FalseEdge { imaginary_target, .. } = term.kind { + // if mir_body.predecessors()[imaginary_target].len() == 1 { + // return Some(imaginary_target); + // } + // } + // None + // }); + // if let Some(imaginary_target) = some_imaginary_target { + // box successors.filter(move |&&successor| successor != imaginary_target) + // } else { + // box successors + // } + // } + // + // Note this also required changing the closure signature for the + // `ShortCurcuitPreorder` to: + // + // F: Fn(&'tcx TerminatorKind<'tcx>) -> Box + 'a>, + TerminatorKind::SwitchInt { .. } => successors, + + // For all other kinds, return only the first successor, if any, and ignore unwinds + _ => successors.next().into_iter().chain(&[]), + } + }); + + // Walk the CFG using a Preorder traversal, which starts from `START_BLOCK` and follows + // each block terminator's `successors()`. Coverage spans must map to actual source code, + // so compiler generated blocks and paths can be ignored. To that end the CFG traversal + // intentionally omits unwind paths. + let mut blocks = Vec::new(); + for (bb, data) in cfg_without_unwind { + if let Some(last) = blocks.last() { + let predecessors = &mir_body.predecessors()[bb]; + if predecessors.len() > 1 || !predecessors.contains(last) { + // The `bb` has more than one _incoming_ edge, and should start its own + // `BasicCoverageBlock`. (Note, the `blocks` vector does not yet include `bb`; + // it contains a sequence of one or more sequential blocks with no intermediate + // branches in or out. Save these as a new `BasicCoverageBlock` before starting + // the new one.) + self.add_basic_coverage_block(blocks.split_off(0)); + debug!( + " because {}", + if predecessors.len() > 1 { + "predecessors.len() > 1".to_owned() + } else { + format!("bb {} is not in precessors: {:?}", bb.index(), predecessors) + } + ); + } + } + blocks.push(bb); + + let term = data.terminator(); + + match term.kind { + TerminatorKind::Return { .. } + | TerminatorKind::Abort + | TerminatorKind::Assert { .. } + | TerminatorKind::Yield { .. } + | TerminatorKind::SwitchInt { .. } => { + // The `bb` has more than one _outgoing_ edge, or exits the function. Save the + // current sequence of `blocks` gathered to this point, as a new + // `BasicCoverageBlock`. + self.add_basic_coverage_block(blocks.split_off(0)); + debug!(" because term.kind = {:?}", term.kind); + // Note that this condition is based on `TerminatorKind`, even though it + // theoretically boils down to `successors().len() != 1`; that is, either zero + // (e.g., `Return`, `Abort`) or multiple successors (e.g., `SwitchInt`), but + // since the Coverage graph (the BCB CFG projection) ignores things like unwind + // branches (which exist in the `Terminator`s `successors()` list) checking the + // number of successors won't work. + } + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Unreachable + | TerminatorKind::Drop { .. } + | TerminatorKind::DropAndReplace { .. } + | TerminatorKind::Call { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::InlineAsm { .. } => {} + } + } + + if !blocks.is_empty() { + // process any remaining blocks into a final `BasicCoverageBlock` + self.add_basic_coverage_block(blocks.split_off(0)); + debug!(" because the end of the CFG was reached while traversing"); + } + } + + fn add_basic_coverage_block(&mut self, blocks: Vec) { + let leader_bb = blocks[0]; + let bcb = BasicCoverageBlock { blocks }; + debug!("adding BCB: {:?}", bcb); + self.vec[leader_bb] = Some(bcb); + } +} + +impl std::ops::Index for BasicCoverageBlocks { + type Output = BasicCoverageBlock; + + fn index(&self, index: BasicBlock) -> &Self::Output { + self.vec[index].as_ref().expect("is_some if BasicBlock is a BasicCoverageBlock leader") + } +} + +pub struct ShortCircuitPreorder< + 'a, + 'tcx, + F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>, +> { + body: &'a mir::Body<'tcx>, + visited: BitSet, + worklist: Vec, + filtered_successors: F, +} + +impl<'a, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> + ShortCircuitPreorder<'a, 'tcx, F> +{ + pub fn new( + body: &'a mir::Body<'tcx>, + filtered_successors: F, + ) -> ShortCircuitPreorder<'a, 'tcx, F> { + let worklist = vec![mir::START_BLOCK]; + + ShortCircuitPreorder { + body, + visited: BitSet::new_empty(body.basic_blocks().len()), + worklist, + filtered_successors, + } + } +} + +impl<'a: 'tcx, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> Iterator + for ShortCircuitPreorder<'a, 'tcx, F> +{ + type Item = (BasicBlock, &'a BasicBlockData<'tcx>); + + fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { + while let Some(idx) = self.worklist.pop() { + if !self.visited.insert(idx) { + continue; + } + + let data = &self.body[idx]; + + if let Some(ref term) = data.terminator { + self.worklist.extend((self.filtered_successors)(&term.kind)); + } + + return Some((idx, data)); + } + + None + } + + fn size_hint(&self) -> (usize, Option) { + let size = self.body.basic_blocks().len() - self.visited.count(); + (size, Some(size)) + } +} diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs new file mode 100644 index 0000000000000..9961afba8e7c4 --- /dev/null +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -0,0 +1,241 @@ +pub mod query; + +mod counters; +mod debug; +mod graph; +mod spans; + +use counters::CoverageCounters; +use graph::BasicCoverageBlocks; +use spans::{CoverageSpan, CoverageSpans}; + +use crate::transform::MirPass; +use crate::util::pretty; + +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::Lrc; +use rustc_index::vec::IndexVec; +use rustc_middle::hir; +use rustc_middle::hir::map::blocks::FnLikeNode; +use rustc_middle::ich::StableHashingContext; +use rustc_middle::mir::coverage::*; +use rustc_middle::mir::{self, BasicBlock, Coverage, Statement, StatementKind}; +use rustc_middle::ty::TyCtxt; +use rustc_span::def_id::DefId; +use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol}; + +/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected +/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen +/// to construct the coverage map. +pub struct InstrumentCoverage; + +impl<'tcx> MirPass<'tcx> for InstrumentCoverage { + fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) { + let mir_source = mir_body.source; + + // If the InstrumentCoverage pass is called on promoted MIRs, skip them. + // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 + if mir_source.promoted.is_some() { + trace!( + "InstrumentCoverage skipped for {:?} (already promoted for Miri evaluation)", + mir_source.def_id() + ); + return; + } + + let hir_id = tcx.hir().local_def_id_to_hir_id(mir_source.def_id().expect_local()); + let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some(); + + // Only instrument functions, methods, and closures (not constants since they are evaluated + // at compile time by Miri). + // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const + // expressions get coverage spans, we will probably have to "carve out" space for const + // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might + // be tricky if const expressions have no corresponding statements in the enclosing MIR. + // Closures are carved out by their initial `Assign` statement.) + if !is_fn_like { + trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id()); + return; + } + // FIXME(richkadel): By comparison, the MIR pass `ConstProp` includes associated constants, + // with functions, methods, and closures. I assume Miri is used for associated constants as + // well. If not, we may need to include them here too. + + trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); + Instrumentor::new(&self.name(), tcx, mir_body).inject_counters(); + trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); + } +} + +struct Instrumentor<'a, 'tcx> { + pass_name: &'a str, + tcx: TyCtxt<'tcx>, + mir_body: &'a mut mir::Body<'tcx>, + body_span: Span, + basic_coverage_blocks: BasicCoverageBlocks, + coverage_counters: CoverageCounters, +} + +impl<'a, 'tcx> Instrumentor<'a, 'tcx> { + fn new(pass_name: &'a str, tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self { + let hir_body = hir_body(tcx, mir_body.source.def_id()); + let body_span = hir_body.value.span; + let function_source_hash = hash_mir_source(tcx, hir_body); + let basic_coverage_blocks = BasicCoverageBlocks::from_mir(mir_body); + Self { + pass_name, + tcx, + mir_body, + body_span, + basic_coverage_blocks, + coverage_counters: CoverageCounters::new(function_source_hash), + } + } + + fn inject_counters(&'a mut self) { + let tcx = self.tcx; + let source_map = tcx.sess.source_map(); + let mir_source = self.mir_body.source; + let def_id = mir_source.def_id(); + let body_span = self.body_span; + + debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); + + //////////////////////////////////////////////////// + // Compute `CoverageSpan`s from the `BasicCoverageBlocks`. + let coverage_spans = CoverageSpans::generate_coverage_spans( + &self.mir_body, + body_span, + &self.basic_coverage_blocks, + ); + + if pretty::dump_enabled(tcx, self.pass_name, def_id) { + debug::dump_coverage_spanview( + tcx, + self.mir_body, + &self.basic_coverage_blocks, + self.pass_name, + &coverage_spans, + ); + } + + self.inject_coverage_span_counters(coverage_spans); + } + + /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given + /// BCB, but only one actual counter needs to be incremented per BCB. `bcb_counters` maps each + /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has + /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to + /// the BCB `Counter` value. + fn inject_coverage_span_counters(&mut self, coverage_spans: Vec) { + let tcx = self.tcx; + let source_map = tcx.sess.source_map(); + let body_span = self.body_span; + let source_file = source_map.lookup_source_file(body_span.lo()); + let file_name = Symbol::intern(&source_file.name.to_string()); + + let mut bb_counters = IndexVec::from_elem_n(None, self.mir_body.basic_blocks().len()); + for CoverageSpan { span, bcb_leader_bb: bb, .. } in coverage_spans { + if let Some(&counter_operand) = bb_counters[bb].as_ref() { + let expression = self.coverage_counters.make_expression( + counter_operand, + Op::Add, + ExpressionOperandId::ZERO, + ); + debug!( + "Injecting counter expression {:?} at: {:?}:\n{}\n==========", + expression, + span, + source_map.span_to_snippet(span).expect("Error getting source for span"), + ); + let code_region = make_code_region(file_name, &source_file, span, body_span); + inject_statement(self.mir_body, expression, bb, Some(code_region)); + } else { + let counter = self.coverage_counters.make_counter(); + debug!( + "Injecting counter {:?} at: {:?}:\n{}\n==========", + counter, + span, + source_map.span_to_snippet(span).expect("Error getting source for span"), + ); + let counter_operand = counter.as_operand_id(); + bb_counters[bb] = Some(counter_operand); + let code_region = make_code_region(file_name, &source_file, span, body_span); + inject_statement(self.mir_body, counter, bb, Some(code_region)); + } + } + } +} + +fn inject_statement( + mir_body: &mut mir::Body<'tcx>, + counter_kind: CoverageKind, + bb: BasicBlock, + some_code_region: Option, +) { + debug!( + " injecting statement {:?} for {:?} at code region: {:?}", + counter_kind, bb, some_code_region + ); + let data = &mut mir_body[bb]; + let source_info = data.terminator().source_info; + let statement = Statement { + source_info, + kind: StatementKind::Coverage(box Coverage { + kind: counter_kind, + code_region: some_code_region, + }), + }; + data.statements.push(statement); +} + +/// Convert the Span into its file name, start line and column, and end line and column +fn make_code_region( + file_name: Symbol, + source_file: &Lrc, + span: Span, + body_span: Span, +) -> CodeRegion { + let (start_line, mut start_col) = source_file.lookup_file_pos(span.lo()); + let (end_line, end_col) = if span.hi() == span.lo() { + let (end_line, mut end_col) = (start_line, start_col); + // Extend an empty span by one character so the region will be counted. + let CharPos(char_pos) = start_col; + if span.hi() == body_span.hi() { + start_col = CharPos(char_pos - 1); + } else { + end_col = CharPos(char_pos + 1); + } + (end_line, end_col) + } else { + source_file.lookup_file_pos(span.hi()) + }; + CodeRegion { + file_name, + start_line: start_line as u32, + start_col: start_col.to_u32() + 1, + end_line: end_line as u32, + end_col: end_col.to_u32() + 1, + } +} + +fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> { + let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local"); + let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body"); + tcx.hir().body(fn_body_id) +} + +fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 { + let mut hcx = tcx.create_no_span_stable_hashing_context(); + hash(&mut hcx, &hir_body.value).to_smaller_hash() +} + +fn hash( + hcx: &mut StableHashingContext<'tcx>, + node: &impl HashStable>, +) -> Fingerprint { + let mut stable_hasher = StableHasher::new(); + node.hash_stable(hcx, &mut stable_hasher); + stable_hasher.finish() +} diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs new file mode 100644 index 0000000000000..c17221b78ddd4 --- /dev/null +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -0,0 +1,113 @@ +use rustc_middle::mir::coverage::*; +use rustc_middle::mir::visit::Visitor; +use rustc_middle::mir::{Coverage, CoverageInfo, Location}; +use rustc_middle::ty::query::Providers; +use rustc_middle::ty::TyCtxt; +use rustc_span::def_id::DefId; + +/// The `query` provider for `CoverageInfo`, requested by `codegen_coverage()` (to inject each +/// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR). +pub(crate) fn provide(providers: &mut Providers) { + providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id); +} + +/// The `num_counters` argument to `llvm.instrprof.increment` is the max counter_id + 1, or in +/// other words, the number of counter value references injected into the MIR (plus 1 for the +/// reserved `ZERO` counter, which uses counter ID `0` when included in an expression). Injected +/// counters have a counter ID from `1..num_counters-1`. +/// +/// `num_expressions` is the number of counter expressions added to the MIR body. +/// +/// Both `num_counters` and `num_expressions` are used to initialize new vectors, during backend +/// code generate, to lookup counters and expressions by simple u32 indexes. +/// +/// MIR optimization may split and duplicate some BasicBlock sequences, or optimize out some code +/// including injected counters. (It is OK if some counters are optimized out, but those counters +/// are still included in the total `num_counters` or `num_expressions`.) Simply counting the +/// calls may not work; but computing the number of counters or expressions by adding `1` to the +/// highest ID (for a given instrumented function) is valid. +/// +/// This visitor runs twice, first with `add_missing_operands` set to `false`, to find the maximum +/// counter ID and maximum expression ID based on their enum variant `id` fields; then, as a +/// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression +/// IDs referenced by expression operands, if not already seen. +/// +/// Ideally, every expression operand in the MIR will have a corresponding Counter or Expression, +/// but since current or future MIR optimizations can theoretically optimize out segments of a +/// MIR, it may not be possible to guarantee this, so the second pass ensures the `CoverageInfo` +/// counts include all referenced IDs. +struct CoverageVisitor { + info: CoverageInfo, + add_missing_operands: bool, +} + +impl CoverageVisitor { + // If an expression operand is encountered with an ID outside the range of known counters and + // expressions, the only way to determine if the ID is a counter ID or an expression ID is to + // assume a maximum possible counter ID value. + const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; + + #[inline(always)] + fn update_num_counters(&mut self, counter_id: u32) { + self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); + } + + #[inline(always)] + fn update_num_expressions(&mut self, expression_id: u32) { + let expression_index = u32::MAX - expression_id; + self.info.num_expressions = std::cmp::max(self.info.num_expressions, expression_index + 1); + } + + fn update_from_expression_operand(&mut self, operand_id: u32) { + if operand_id >= self.info.num_counters { + let operand_as_expression_index = u32::MAX - operand_id; + if operand_as_expression_index >= self.info.num_expressions { + if operand_id <= Self::MAX_COUNTER_GUARD { + self.update_num_counters(operand_id) + } else { + self.update_num_expressions(operand_id) + } + } + } + } +} + +impl Visitor<'_> for CoverageVisitor { + fn visit_coverage(&mut self, coverage: &Coverage, _location: Location) { + if self.add_missing_operands { + match coverage.kind { + CoverageKind::Expression { lhs, rhs, .. } => { + self.update_from_expression_operand(u32::from(lhs)); + self.update_from_expression_operand(u32::from(rhs)); + } + _ => {} + } + } else { + match coverage.kind { + CoverageKind::Counter { id, .. } => { + self.update_num_counters(u32::from(id)); + } + CoverageKind::Expression { id, .. } => { + self.update_num_expressions(u32::from(id)); + } + _ => {} + } + } + } +} + +fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo { + let mir_body = tcx.optimized_mir(def_id); + + let mut coverage_visitor = CoverageVisitor { + info: CoverageInfo { num_counters: 0, num_expressions: 0 }, + add_missing_operands: false, + }; + + coverage_visitor.visit_body(mir_body); + + coverage_visitor.add_missing_operands = true; + coverage_visitor.visit_body(mir_body); + + coverage_visitor.info +} diff --git a/compiler/rustc_mir/src/transform/instrument_coverage.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs similarity index 52% rename from compiler/rustc_mir/src/transform/instrument_coverage.rs rename to compiler/rustc_mir/src/transform/coverage/spans.rs index cb6798f2ee75e..7957b6f3ff592 100644 --- a/compiler/rustc_mir/src/transform/instrument_coverage.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -1,396 +1,24 @@ -use crate::transform::MirPass; -use crate::util::pretty; -use crate::util::spanview::{self, source_range_no_file, SpanViewable}; +use super::debug::term_type; +use super::graph::{BasicCoverageBlock, BasicCoverageBlocks}; + +use crate::util::spanview::source_range_no_file; -use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::WithNumNodes; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::Lrc; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; -use rustc_middle::hir; -use rustc_middle::hir::map::blocks::FnLikeNode; -use rustc_middle::ich::StableHashingContext; -use rustc_middle::mir; -use rustc_middle::mir::coverage::*; -use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{ - AggregateKind, BasicBlock, BasicBlockData, Coverage, CoverageInfo, FakeReadCause, Location, - Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, + TerminatorKind, }; -use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::DefId; + use rustc_span::source_map::original_sp; -use rustc_span::{BytePos, CharPos, Pos, SourceFile, Span, Symbol, SyntaxContext}; +use rustc_span::{BytePos, Span, SyntaxContext}; use std::cmp::Ordering; -const ID_SEPARATOR: &str = ","; - -/// The `query` provider for `CoverageInfo`, requested by `codegen_coverage()` (to inject each -/// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR). -pub(crate) fn provide(providers: &mut Providers) { - providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id); -} - -/// The `num_counters` argument to `llvm.instrprof.increment` is the max counter_id + 1, or in -/// other words, the number of counter value references injected into the MIR (plus 1 for the -/// reserved `ZERO` counter, which uses counter ID `0` when included in an expression). Injected -/// counters have a counter ID from `1..num_counters-1`. -/// -/// `num_expressions` is the number of counter expressions added to the MIR body. -/// -/// Both `num_counters` and `num_expressions` are used to initialize new vectors, during backend -/// code generate, to lookup counters and expressions by simple u32 indexes. -/// -/// MIR optimization may split and duplicate some BasicBlock sequences, or optimize out some code -/// including injected counters. (It is OK if some counters are optimized out, but those counters -/// are still included in the total `num_counters` or `num_expressions`.) Simply counting the -/// calls may not work; but computing the number of counters or expressions by adding `1` to the -/// highest ID (for a given instrumented function) is valid. -/// -/// This visitor runs twice, first with `add_missing_operands` set to `false`, to find the maximum -/// counter ID and maximum expression ID based on their enum variant `id` fields; then, as a -/// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression -/// IDs referenced by expression operands, if not already seen. -/// -/// Ideally, every expression operand in the MIR will have a corresponding Counter or Expression, -/// but since current or future MIR optimizations can theoretically optimize out segments of a -/// MIR, it may not be possible to guarantee this, so the second pass ensures the `CoverageInfo` -/// counts include all referenced IDs. -struct CoverageVisitor { - info: CoverageInfo, - add_missing_operands: bool, -} - -impl CoverageVisitor { - // If an expression operand is encountered with an ID outside the range of known counters and - // expressions, the only way to determine if the ID is a counter ID or an expression ID is to - // assume a maximum possible counter ID value. - const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; - - #[inline(always)] - fn update_num_counters(&mut self, counter_id: u32) { - self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); - } - - #[inline(always)] - fn update_num_expressions(&mut self, expression_id: u32) { - let expression_index = u32::MAX - expression_id; - self.info.num_expressions = std::cmp::max(self.info.num_expressions, expression_index + 1); - } - - fn update_from_expression_operand(&mut self, operand_id: u32) { - if operand_id >= self.info.num_counters { - let operand_as_expression_index = u32::MAX - operand_id; - if operand_as_expression_index >= self.info.num_expressions { - if operand_id <= Self::MAX_COUNTER_GUARD { - self.update_num_counters(operand_id) - } else { - self.update_num_expressions(operand_id) - } - } - } - } -} - -impl Visitor<'_> for CoverageVisitor { - fn visit_coverage(&mut self, coverage: &Coverage, _location: Location) { - if self.add_missing_operands { - match coverage.kind { - CoverageKind::Expression { lhs, rhs, .. } => { - self.update_from_expression_operand(u32::from(lhs)); - self.update_from_expression_operand(u32::from(rhs)); - } - _ => {} - } - } else { - match coverage.kind { - CoverageKind::Counter { id, .. } => { - self.update_num_counters(u32::from(id)); - } - CoverageKind::Expression { id, .. } => { - self.update_num_expressions(u32::from(id)); - } - _ => {} - } - } - } -} - -fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo { - let mir_body = tcx.optimized_mir(def_id); - - let mut coverage_visitor = CoverageVisitor { - info: CoverageInfo { num_counters: 0, num_expressions: 0 }, - add_missing_operands: false, - }; - - coverage_visitor.visit_body(mir_body); - - coverage_visitor.add_missing_operands = true; - coverage_visitor.visit_body(mir_body); - - coverage_visitor.info -} -/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected -/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen -/// to construct the coverage map. -pub struct InstrumentCoverage; - -impl<'tcx> MirPass<'tcx> for InstrumentCoverage { - fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) { - let mir_source = mir_body.source; - - // If the InstrumentCoverage pass is called on promoted MIRs, skip them. - // See: https://github.com/rust-lang/rust/pull/73011#discussion_r438317601 - if mir_source.promoted.is_some() { - trace!( - "InstrumentCoverage skipped for {:?} (already promoted for Miri evaluation)", - mir_source.def_id() - ); - return; - } - - let hir_id = tcx.hir().local_def_id_to_hir_id(mir_source.def_id().expect_local()); - let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some(); - - // Only instrument functions, methods, and closures (not constants since they are evaluated - // at compile time by Miri). - // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const - // expressions get coverage spans, we will probably have to "carve out" space for const - // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might - // be tricky if const expressions have no corresponding statements in the enclosing MIR. - // Closures are carved out by their initial `Assign` statement.) - if !is_fn_like { - trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id()); - return; - } - // FIXME(richkadel): By comparison, the MIR pass `ConstProp` includes associated constants, - // with functions, methods, and closures. I assume Miri is used for associated constants as - // well. If not, we may need to include them here too. - - trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); - Instrumentor::new(&self.name(), tcx, mir_body).inject_counters(); - trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); - } -} - -/// A BasicCoverageBlock (BCB) represents the maximal-length sequence of CFG (MIR) BasicBlocks -/// without conditional branches. -/// -/// The BCB allows coverage analysis to be performed on a simplified projection of the underlying -/// MIR CFG, without altering the original CFG. Note that running the MIR `SimplifyCfg` transform, -/// is not sufficient, and therefore not necessary, since the BCB-based CFG projection is a more -/// aggressive simplification. For example: -/// -/// * The BCB CFG projection ignores (trims) branches not relevant to coverage, such as unwind- -/// related code that is injected by the Rust compiler but has no physical source code to -/// count. This also means a BasicBlock with a `Call` terminator can be merged into its -/// primary successor target block, in the same BCB. -/// * Some BasicBlock terminators support Rust-specific concerns--like borrow-checking--that are -/// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as -/// a `Goto`, and merged with its successor into the same BCB. -/// -/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`. -/// In some cases, a BCB's execution count can be computed by `CounterExpression`. Additional -/// disjoint `CoverageSpan`s in a BCB can also be counted by `CounterExpression` (by adding `ZERO` -/// to the BCB's primary counter or expression). -/// -/// Dominator/dominated relationships (which are fundamental to the coverage analysis algorithm) -/// between two BCBs can be computed using the `mir::Body` `dominators()` with any `BasicBlock` -/// member of each BCB. (For consistency, BCB's use the first `BasicBlock`, also referred to as the -/// `bcb_leader_bb`.) -/// -/// The BCB CFG projection is critical to simplifying the coverage analysis by ensuring graph -/// path-based queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch -/// (control flow) significance. -#[derive(Debug, Clone)] -struct BasicCoverageBlock { - pub blocks: Vec, -} - -impl BasicCoverageBlock { - pub fn leader_bb(&self) -> BasicBlock { - self.blocks[0] - } - - pub fn id(&self) -> String { - format!( - "@{}", - self.blocks - .iter() - .map(|bb| bb.index().to_string()) - .collect::>() - .join(ID_SEPARATOR) - ) - } -} - -struct BasicCoverageBlocks { - vec: IndexVec>, -} - -impl BasicCoverageBlocks { - pub fn from_mir(mir_body: &mir::Body<'tcx>) -> Self { - let mut basic_coverage_blocks = - BasicCoverageBlocks { vec: IndexVec::from_elem_n(None, mir_body.basic_blocks().len()) }; - basic_coverage_blocks.extract_from_mir(mir_body); - basic_coverage_blocks - } - - pub fn iter(&self) -> impl Iterator { - self.vec.iter().filter_map(|bcb| bcb.as_ref()) - } - - pub fn num_nodes(&self) -> usize { - self.vec.len() - } - - pub fn extract_from_mir(&mut self, mir_body: &mir::Body<'tcx>) { - // Traverse the CFG but ignore anything following an `unwind` - let cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, |term_kind| { - let mut successors = term_kind.successors(); - match &term_kind { - // SwitchInt successors are never unwind, and all of them should be traversed. - - // NOTE: TerminatorKind::FalseEdge targets from SwitchInt don't appear to be - // helpful in identifying unreachable code. I did test the theory, but the following - // changes were not beneficial. (I assumed that replacing some constants with - // non-deterministic variables might effect which blocks were targeted by a - // `FalseEdge` `imaginary_target`. It did not.) - // - // Also note that, if there is a way to identify BasicBlocks that are part of the - // MIR CFG, but not actually reachable, here are some other things to consider: - // - // Injecting unreachable code regions will probably require computing the set - // difference between the basic blocks found without filtering out unreachable - // blocks, and the basic blocks found with the filter; then computing the - // `CoverageSpans` without the filter; and then injecting `Counter`s or - // `CounterExpression`s for blocks that are not unreachable, or injecting - // `Unreachable` code regions otherwise. This seems straightforward, but not - // trivial. - // - // Alternatively, we might instead want to leave the unreachable blocks in - // (bypass the filter here), and inject the counters. This will result in counter - // values of zero (0) for unreachable code (and, notably, the code will be displayed - // with a red background by `llvm-cov show`). - // - // TerminatorKind::SwitchInt { .. } => { - // let some_imaginary_target = successors.clone().find_map(|&successor| { - // let term = mir_body.basic_blocks()[successor].terminator(); - // if let TerminatorKind::FalseEdge { imaginary_target, .. } = term.kind { - // if mir_body.predecessors()[imaginary_target].len() == 1 { - // return Some(imaginary_target); - // } - // } - // None - // }); - // if let Some(imaginary_target) = some_imaginary_target { - // box successors.filter(move |&&successor| successor != imaginary_target) - // } else { - // box successors - // } - // } - // - // Note this also required changing the closure signature for the - // `ShortCurcuitPreorder` to: - // - // F: Fn(&'tcx TerminatorKind<'tcx>) -> Box + 'a>, - TerminatorKind::SwitchInt { .. } => successors, - - // For all other kinds, return only the first successor, if any, and ignore unwinds - _ => successors.next().into_iter().chain(&[]), - } - }); - - // Walk the CFG using a Preorder traversal, which starts from `START_BLOCK` and follows - // each block terminator's `successors()`. Coverage spans must map to actual source code, - // so compiler generated blocks and paths can be ignored. To that end the CFG traversal - // intentionally omits unwind paths. - let mut blocks = Vec::new(); - for (bb, data) in cfg_without_unwind { - if let Some(last) = blocks.last() { - let predecessors = &mir_body.predecessors()[bb]; - if predecessors.len() > 1 || !predecessors.contains(last) { - // The `bb` has more than one _incoming_ edge, and should start its own - // `BasicCoverageBlock`. (Note, the `blocks` vector does not yet include `bb`; - // it contains a sequence of one or more sequential blocks with no intermediate - // branches in or out. Save these as a new `BasicCoverageBlock` before starting - // the new one.) - self.add_basic_coverage_block(blocks.split_off(0)); - debug!( - " because {}", - if predecessors.len() > 1 { - "predecessors.len() > 1".to_owned() - } else { - format!("bb {} is not in precessors: {:?}", bb.index(), predecessors) - } - ); - } - } - blocks.push(bb); - - let term = data.terminator(); - - match term.kind { - TerminatorKind::Return { .. } - | TerminatorKind::Abort - | TerminatorKind::Assert { .. } - | TerminatorKind::Yield { .. } - | TerminatorKind::SwitchInt { .. } => { - // The `bb` has more than one _outgoing_ edge, or exits the function. Save the - // current sequence of `blocks` gathered to this point, as a new - // `BasicCoverageBlock`. - self.add_basic_coverage_block(blocks.split_off(0)); - debug!(" because term.kind = {:?}", term.kind); - // Note that this condition is based on `TerminatorKind`, even though it - // theoretically boils down to `successors().len() != 1`; that is, either zero - // (e.g., `Return`, `Abort`) or multiple successors (e.g., `SwitchInt`), but - // since the Coverage graph (the BCB CFG projection) ignores things like unwind - // branches (which exist in the `Terminator`s `successors()` list) checking the - // number of successors won't work. - } - TerminatorKind::Goto { .. } - | TerminatorKind::Resume - | TerminatorKind::Unreachable - | TerminatorKind::Drop { .. } - | TerminatorKind::DropAndReplace { .. } - | TerminatorKind::Call { .. } - | TerminatorKind::GeneratorDrop - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::InlineAsm { .. } => {} - } - } - - if !blocks.is_empty() { - // process any remaining blocks into a final `BasicCoverageBlock` - self.add_basic_coverage_block(blocks.split_off(0)); - debug!(" because the end of the CFG was reached while traversing"); - } - } - - fn add_basic_coverage_block(&mut self, blocks: Vec) { - let leader_bb = blocks[0]; - let bcb = BasicCoverageBlock { blocks }; - debug!("adding BCB: {:?}", bcb); - self.vec[leader_bb] = Some(bcb); - } -} - -impl std::ops::Index for BasicCoverageBlocks { - type Output = BasicCoverageBlock; - - fn index(&self, index: BasicBlock) -> &Self::Output { - self.vec[index].as_ref().expect("is_some if BasicBlock is a BasicCoverageBlock leader") - } -} - #[derive(Debug, Copy, Clone)] -enum CoverageStatement { +pub(crate) enum CoverageStatement { Statement(BasicBlock, Span, usize), Terminator(BasicBlock, Span), } @@ -428,28 +56,6 @@ impl CoverageStatement { } } -/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any -/// values it might hold. -fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { - match kind { - TerminatorKind::Goto { .. } => "Goto", - TerminatorKind::SwitchInt { .. } => "SwitchInt", - TerminatorKind::Resume => "Resume", - TerminatorKind::Abort => "Abort", - TerminatorKind::Return => "Return", - TerminatorKind::Unreachable => "Unreachable", - TerminatorKind::Drop { .. } => "Drop", - TerminatorKind::DropAndReplace { .. } => "DropAndReplace", - TerminatorKind::Call { .. } => "Call", - TerminatorKind::Assert { .. } => "Assert", - TerminatorKind::Yield { .. } => "Yield", - TerminatorKind::GeneratorDrop => "GeneratorDrop", - TerminatorKind::FalseEdge { .. } => "FalseEdge", - TerminatorKind::FalseUnwind { .. } => "FalseUnwind", - TerminatorKind::InlineAsm { .. } => "InlineAsm", - } -} - /// A BCB is deconstructed into one or more `Span`s. Each `Span` maps to a `CoverageSpan` that /// references the originating BCB and one or more MIR `Statement`s and/or `Terminator`s. /// Initially, the `Span`s come from the `Statement`s and `Terminator`s, but subsequent @@ -461,7 +67,7 @@ fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { /// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock` /// `is_dominated_by()` the `BasicBlock`s in this `CoverageSpan`. #[derive(Debug, Clone)] -struct CoverageSpan { +pub(crate) struct CoverageSpan { pub span: Span, pub bcb_leader_bb: BasicBlock, pub coverage_statements: Vec, @@ -547,220 +153,6 @@ impl CoverageSpan { } } -struct Instrumentor<'a, 'tcx> { - pass_name: &'a str, - tcx: TyCtxt<'tcx>, - mir_body: &'a mut mir::Body<'tcx>, - body_span: Span, - basic_coverage_blocks: BasicCoverageBlocks, - coverage_counters: CoverageCounters, -} - -impl<'a, 'tcx> Instrumentor<'a, 'tcx> { - fn new(pass_name: &'a str, tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self { - let hir_body = hir_body(tcx, mir_body.source.def_id()); - let body_span = hir_body.value.span; - let function_source_hash = hash_mir_source(tcx, hir_body); - let basic_coverage_blocks = BasicCoverageBlocks::from_mir(mir_body); - Self { - pass_name, - tcx, - mir_body, - body_span, - basic_coverage_blocks, - coverage_counters: CoverageCounters::new(function_source_hash), - } - } - - fn inject_counters(&'a mut self) { - let tcx = self.tcx; - let source_map = tcx.sess.source_map(); - let mir_source = self.mir_body.source; - let def_id = mir_source.def_id(); - let body_span = self.body_span; - - debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); - - //////////////////////////////////////////////////// - // Compute `CoverageSpan`s from the `BasicCoverageBlocks`. - let coverage_spans = CoverageSpans::generate_coverage_spans( - &self.mir_body, - body_span, - &self.basic_coverage_blocks, - ); - - if pretty::dump_enabled(tcx, self.pass_name, def_id) { - dump_coverage_spanview( - tcx, - self.mir_body, - &self.basic_coverage_blocks, - self.pass_name, - &coverage_spans, - ); - } - - self.inject_coverage_span_counters(coverage_spans); - } - - /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given - /// BCB, but only one actual counter needs to be incremented per BCB. `bcb_counters` maps each - /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has - /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to - /// the BCB `Counter` value. - fn inject_coverage_span_counters(&mut self, coverage_spans: Vec) { - let tcx = self.tcx; - let source_map = tcx.sess.source_map(); - let body_span = self.body_span; - let source_file = source_map.lookup_source_file(body_span.lo()); - let file_name = Symbol::intern(&source_file.name.to_string()); - - let mut bb_counters = IndexVec::from_elem_n(None, self.mir_body.basic_blocks().len()); - for CoverageSpan { span, bcb_leader_bb: bb, .. } in coverage_spans { - if let Some(&counter_operand) = bb_counters[bb].as_ref() { - let expression = self.coverage_counters.make_expression( - counter_operand, - Op::Add, - ExpressionOperandId::ZERO, - ); - debug!( - "Injecting counter expression {:?} at: {:?}:\n{}\n==========", - expression, - span, - source_map.span_to_snippet(span).expect("Error getting source for span"), - ); - let code_region = make_code_region(file_name, &source_file, span, body_span); - inject_statement(self.mir_body, expression, bb, Some(code_region)); - } else { - let counter = self.coverage_counters.make_counter(); - debug!( - "Injecting counter {:?} at: {:?}:\n{}\n==========", - counter, - span, - source_map.span_to_snippet(span).expect("Error getting source for span"), - ); - let counter_operand = counter.as_operand_id(); - bb_counters[bb] = Some(counter_operand); - let code_region = make_code_region(file_name, &source_file, span, body_span); - inject_statement(self.mir_body, counter, bb, Some(code_region)); - } - } - } -} - -/// Generates the MIR pass `CoverageSpan`-specific spanview dump file. -fn dump_coverage_spanview( - tcx: TyCtxt<'tcx>, - mir_body: &mir::Body<'tcx>, - basic_coverage_blocks: &BasicCoverageBlocks, - pass_name: &str, - coverage_spans: &Vec, -) { - let mir_source = mir_body.source; - let def_id = mir_source.def_id(); - - let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans); - let mut file = pretty::create_dump_file(tcx, "html", None, pass_name, &0, mir_source) - .expect("Unexpected error creating MIR spanview HTML file"); - let crate_name = tcx.crate_name(def_id.krate); - let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate(); - let title = format!("{}.{} - Coverage Spans", crate_name, item_name); - spanview::write_document(tcx, def_id, span_viewables, &title, &mut file) - .expect("Unexpected IO error dumping coverage spans as HTML"); -} - -/// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s. -fn span_viewables( - tcx: TyCtxt<'tcx>, - mir_body: &mir::Body<'tcx>, - basic_coverage_blocks: &BasicCoverageBlocks, - coverage_spans: &Vec, -) -> Vec { - let mut span_viewables = Vec::new(); - for coverage_span in coverage_spans { - let tooltip = coverage_span.format_coverage_statements(tcx, mir_body); - let CoverageSpan { span, bcb_leader_bb: bb, .. } = coverage_span; - let bcb = &basic_coverage_blocks[*bb]; - let id = bcb.id(); - let leader_bb = bcb.leader_bb(); - span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip }); - } - span_viewables -} - -/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR -/// `Coverage` statements. -struct CoverageCounters { - function_source_hash: u64, - next_counter_id: u32, - num_expressions: u32, -} - -impl CoverageCounters { - pub fn new(function_source_hash: u64) -> Self { - Self { - function_source_hash, - next_counter_id: CounterValueReference::START.as_u32(), - num_expressions: 0, - } - } - - pub fn make_counter(&mut self) -> CoverageKind { - CoverageKind::Counter { - function_source_hash: self.function_source_hash, - id: self.next_counter(), - } - } - - pub fn make_expression( - &mut self, - lhs: ExpressionOperandId, - op: Op, - rhs: ExpressionOperandId, - ) -> CoverageKind { - let id = self.next_expression(); - CoverageKind::Expression { id, lhs, op, rhs } - } - - /// Counter IDs start from one and go up. - fn next_counter(&mut self) -> CounterValueReference { - assert!(self.next_counter_id < u32::MAX - self.num_expressions); - let next = self.next_counter_id; - self.next_counter_id += 1; - CounterValueReference::from(next) - } - - /// Expression IDs start from u32::MAX and go down because a Expression can reference - /// (add or subtract counts) of both Counter regions and Expression regions. The counter - /// expression operand IDs must be unique across both types. - fn next_expression(&mut self) -> InjectedExpressionId { - assert!(self.next_counter_id < u32::MAX - self.num_expressions); - let next = u32::MAX - self.num_expressions; - self.num_expressions += 1; - InjectedExpressionId::from(next) - } -} -fn inject_statement( - mir_body: &mut mir::Body<'tcx>, - counter_kind: CoverageKind, - bb: BasicBlock, - some_code_region: Option, -) { - debug!( - " injecting statement {:?} for {:?} at code region: {:?}", - counter_kind, bb, some_code_region - ); - let data = &mut mir_body[bb]; - let source_info = data.terminator().source_info; - let statement = Statement { - source_info, - kind: StatementKind::Coverage(box Coverage { - kind: counter_kind, - code_region: some_code_region, - }), - }; - data.statements.push(statement); -} - /// Converts the initial set of `CoverageSpan`s (one per MIR `Statement` or `Terminator`) into a /// minimal set of `CoverageSpan`s, using the BCB CFG to determine where it is safe and useful to: /// @@ -818,7 +210,7 @@ pub struct CoverageSpans<'a, 'tcx> { } impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { - fn generate_coverage_spans( + pub(crate) fn generate_coverage_spans( mir_body: &'a mir::Body<'tcx>, body_span: Span, basic_coverage_blocks: &'a BasicCoverageBlocks, @@ -1366,111 +758,3 @@ fn is_goto(term_kind: &TerminatorKind<'tcx>) -> bool { _ => false, } } - -/// Convert the Span into its file name, start line and column, and end line and column -fn make_code_region( - file_name: Symbol, - source_file: &Lrc, - span: Span, - body_span: Span, -) -> CodeRegion { - let (start_line, mut start_col) = source_file.lookup_file_pos(span.lo()); - let (end_line, end_col) = if span.hi() == span.lo() { - let (end_line, mut end_col) = (start_line, start_col); - // Extend an empty span by one character so the region will be counted. - let CharPos(char_pos) = start_col; - if span.hi() == body_span.hi() { - start_col = CharPos(char_pos - 1); - } else { - end_col = CharPos(char_pos + 1); - } - (end_line, end_col) - } else { - source_file.lookup_file_pos(span.hi()) - }; - CodeRegion { - file_name, - start_line: start_line as u32, - start_col: start_col.to_u32() + 1, - end_line: end_line as u32, - end_col: end_col.to_u32() + 1, - } -} - -fn hir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx rustc_hir::Body<'tcx> { - let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local"); - let fn_body_id = hir::map::associated_body(hir_node).expect("HIR node is a function with body"); - tcx.hir().body(fn_body_id) -} - -fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 { - let mut hcx = tcx.create_no_span_stable_hashing_context(); - hash(&mut hcx, &hir_body.value).to_smaller_hash() -} - -fn hash( - hcx: &mut StableHashingContext<'tcx>, - node: &impl HashStable>, -) -> Fingerprint { - let mut stable_hasher = StableHasher::new(); - node.hash_stable(hcx, &mut stable_hasher); - stable_hasher.finish() -} - -pub struct ShortCircuitPreorder< - 'a, - 'tcx, - F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>, -> { - body: &'a mir::Body<'tcx>, - visited: BitSet, - worklist: Vec, - filtered_successors: F, -} - -impl<'a, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> - ShortCircuitPreorder<'a, 'tcx, F> -{ - pub fn new( - body: &'a mir::Body<'tcx>, - filtered_successors: F, - ) -> ShortCircuitPreorder<'a, 'tcx, F> { - let worklist = vec![mir::START_BLOCK]; - - ShortCircuitPreorder { - body, - visited: BitSet::new_empty(body.basic_blocks().len()), - worklist, - filtered_successors, - } - } -} - -impl<'a: 'tcx, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> Iterator - for ShortCircuitPreorder<'a, 'tcx, F> -{ - type Item = (BasicBlock, &'a BasicBlockData<'tcx>); - - fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - while let Some(idx) = self.worklist.pop() { - if !self.visited.insert(idx) { - continue; - } - - let data = &self.body[idx]; - - if let Some(ref term) = data.terminator { - self.worklist.extend((self.filtered_successors)(&term.kind)); - } - - return Some((idx, data)); - } - - None - } - - fn size_hint(&self) -> (usize, Option) { - let size = self.body.basic_blocks().len() - self.visited.count(); - (size, Some(size)) - } -} diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 89db6bb13cad3..e3fea2d2701e5 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -22,6 +22,7 @@ pub mod check_packed_ref; pub mod check_unsafety; pub mod cleanup_post_borrowck; pub mod const_prop; +pub mod coverage; pub mod deaggregator; pub mod dest_prop; pub mod dump_mir; @@ -31,7 +32,6 @@ pub mod function_item_references; pub mod generator; pub mod inline; pub mod instcombine; -pub mod instrument_coverage; pub mod match_branches; pub mod multiple_return_terminators; pub mod no_landing_pads; @@ -85,7 +85,7 @@ pub(crate) fn provide(providers: &mut Providers) { }, ..*providers }; - instrument_coverage::provide(providers); + coverage::query::provide(providers); } fn is_mir_available(tcx: TyCtxt<'_>, def_id: DefId) -> bool { @@ -306,7 +306,7 @@ fn mir_promoted( ]; let opt_coverage: &[&dyn MirPass<'tcx>] = if tcx.sess.opts.debugging_opts.instrument_coverage { - &[&instrument_coverage::InstrumentCoverage] + &[&coverage::InstrumentCoverage] } else { &[] }; From 7b87ae4d8794d4f4181e5b4933b7de7bb501edf5 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 22 Oct 2020 23:11:38 -0700 Subject: [PATCH 15/27] Implemented CoverageGraph of BasicCoverageBlocks --- .../rustc_mir/src/transform/coverage/debug.rs | 16 +- .../rustc_mir/src/transform/coverage/graph.rs | 458 ++++++++++++------ .../rustc_mir/src/transform/coverage/mod.rs | 21 +- .../rustc_mir/src/transform/coverage/spans.rs | 51 +- ...expected_export_coverage.lazy_boolean.json | 20 +- ...ed_export_coverage.loops_and_branches.json | 12 +- ...expected_export_coverage.nested_loops.json | 20 +- ...cted_export_coverage.try_error_result.json | 24 +- .../expected_export_coverage.while.json | 12 +- ...ed_export_coverage.while_early_return.json | 20 +- .../expected_show_coverage.lazy_boolean.txt | 4 +- .../expected_show_coverage.nested_loops.txt | 4 +- ...xpected_show_coverage.try_error_result.txt | 4 +- ...ected_show_coverage.while_early_return.txt | 2 +- ...cted_show_coverage_counters.drop_trait.txt | 5 +- ...pected_show_coverage_counters.generics.txt | 5 +- ...xpected_show_coverage_counters.if_else.txt | 9 +- ...ed_show_coverage_counters.lazy_boolean.txt | 10 +- ...w_coverage_counters.loops_and_branches.txt | 1 - ...ed_show_coverage_counters.nested_loops.txt | 10 +- ...how_coverage_counters.try_error_result.txt | 9 +- .../expected_show_coverage_counters.while.txt | 5 +- ...w_coverage_counters.while_early_return.txt | 4 - ...expected_export_coverage.lazy_boolean.json | 20 +- ...ed_export_coverage.loops_and_branches.json | 12 +- ...expected_export_coverage.nested_loops.json | 20 +- ...cted_export_coverage.try_error_result.json | 24 +- .../expected_export_coverage.while.json | 12 +- ...ed_export_coverage.while_early_return.json | 20 +- .../expected_show_coverage.lazy_boolean.txt | 4 +- .../expected_show_coverage.nested_loops.txt | 4 +- ...xpected_show_coverage.try_error_result.txt | 4 +- ...ected_show_coverage.while_early_return.txt | 2 +- ...cted_show_coverage_counters.drop_trait.txt | 5 +- ...pected_show_coverage_counters.generics.txt | 5 +- ...xpected_show_coverage_counters.if_else.txt | 9 +- ...ed_show_coverage_counters.lazy_boolean.txt | 10 +- ...w_coverage_counters.loops_and_branches.txt | 1 - ...ed_show_coverage_counters.nested_loops.txt | 10 +- ...ters.partial_eq_counter_without_region.txt | 6 +- ...how_coverage_counters.try_error_result.txt | 9 +- .../expected_show_coverage_counters.while.txt | 5 +- ...w_coverage_counters.while_early_return.txt | 4 - ...ean.main.-------.InstrumentCoverage.0.html | 28 +- ...l#0}-fmt.-------.InstrumentCoverage.0.html | 2 +- ...ops.main.-------.InstrumentCoverage.0.html | 6 +- ...l#1}-cmp.-------.InstrumentCoverage.0.html | 6 +- ...tial_cmp.-------.InstrumentCoverage.0.html | 6 +- ...oop.main.-------.InstrumentCoverage.0.html | 4 +- ...ult.main.-------.InstrumentCoverage.0.html | 6 +- ...ile.main.-------.InstrumentCoverage.0.html | 2 +- ...urn.main.-------.InstrumentCoverage.0.html | 12 +- ...ean.main.-------.InstrumentCoverage.0.html | 28 +- ...l#0}-fmt.-------.InstrumentCoverage.0.html | 2 +- ...ops.main.-------.InstrumentCoverage.0.html | 6 +- ...l#1}-cmp.-------.InstrumentCoverage.0.html | 6 +- ...tial_cmp.-------.InstrumentCoverage.0.html | 6 +- ...oop.main.-------.InstrumentCoverage.0.html | 4 +- ...ult.main.-------.InstrumentCoverage.0.html | 6 +- ...ile.main.-------.InstrumentCoverage.0.html | 2 +- ...urn.main.-------.InstrumentCoverage.0.html | 12 +- 61 files changed, 563 insertions(+), 493 deletions(-) diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 0cd2e413da944..7eb2d33453c3e 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -1,4 +1,4 @@ -use super::graph::BasicCoverageBlocks; +use super::graph::CoverageGraph; use super::spans::CoverageSpan; use crate::util::pretty; @@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt; pub(crate) fn dump_coverage_spanview( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, - basic_coverage_blocks: &BasicCoverageBlocks, + basic_coverage_blocks: &CoverageGraph, pass_name: &str, coverage_spans: &Vec, ) { @@ -28,20 +28,20 @@ pub(crate) fn dump_coverage_spanview( .expect("Unexpected IO error dumping coverage spans as HTML"); } -/// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s. +/// Converts the computed `BasicCoverageBlockData`s into `SpanViewable`s. fn span_viewables( tcx: TyCtxt<'tcx>, mir_body: &mir::Body<'tcx>, - basic_coverage_blocks: &BasicCoverageBlocks, + basic_coverage_blocks: &CoverageGraph, coverage_spans: &Vec, ) -> Vec { let mut span_viewables = Vec::new(); for coverage_span in coverage_spans { let tooltip = coverage_span.format_coverage_statements(tcx, mir_body); - let CoverageSpan { span, bcb_leader_bb: bb, .. } = coverage_span; - let bcb = &basic_coverage_blocks[*bb]; - let id = bcb.id(); - let leader_bb = bcb.leader_bb(); + let CoverageSpan { span, bcb, .. } = coverage_span; + let bcb_data = &basic_coverage_blocks[*bcb]; + let id = bcb_data.id(); + let leader_bb = bcb_data.leader_bb(); span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip }); } span_viewables diff --git a/compiler/rustc_mir/src/transform/coverage/graph.rs b/compiler/rustc_mir/src/transform/coverage/graph.rs index c0a698833a1fe..3d3e76f907b64 100644 --- a/compiler/rustc_mir/src/transform/coverage/graph.rs +++ b/compiler/rustc_mir/src/transform/coverage/graph.rs @@ -1,152 +1,100 @@ +use rustc_data_structures::graph::dominators::{self, Dominators}; +use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes}; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; -use rustc_middle::mir::{self, BasicBlock, BasicBlockData, TerminatorKind}; +use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind}; + +use std::ops::{Index, IndexMut}; const ID_SEPARATOR: &str = ","; -/// A BasicCoverageBlock (BCB) represents the maximal-length sequence of CFG (MIR) BasicBlocks -/// without conditional branches. -/// -/// The BCB allows coverage analysis to be performed on a simplified projection of the underlying -/// MIR CFG, without altering the original CFG. Note that running the MIR `SimplifyCfg` transform, -/// is not sufficient, and therefore not necessary, since the BCB-based CFG projection is a more -/// aggressive simplification. For example: -/// -/// * The BCB CFG projection ignores (trims) branches not relevant to coverage, such as unwind- -/// related code that is injected by the Rust compiler but has no physical source code to -/// count. This also means a BasicBlock with a `Call` terminator can be merged into its -/// primary successor target block, in the same BCB. -/// * Some BasicBlock terminators support Rust-specific concerns--like borrow-checking--that are -/// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as -/// a `Goto`, and merged with its successor into the same BCB. -/// -/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`. -/// In some cases, a BCB's execution count can be computed by `CounterExpression`. Additional -/// disjoint `CoverageSpan`s in a BCB can also be counted by `CounterExpression` (by adding `ZERO` -/// to the BCB's primary counter or expression). -/// -/// Dominator/dominated relationships (which are fundamental to the coverage analysis algorithm) -/// between two BCBs can be computed using the `mir::Body` `dominators()` with any `BasicBlock` -/// member of each BCB. (For consistency, BCB's use the first `BasicBlock`, also referred to as the -/// `bcb_leader_bb`.) -/// -/// The BCB CFG projection is critical to simplifying the coverage analysis by ensuring graph -/// path-based queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch -/// (control flow) significance. -#[derive(Debug, Clone)] -pub(crate) struct BasicCoverageBlock { - pub blocks: Vec, +/// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s +/// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s, plus a +/// `CoverageKind` counter (to be added by `CoverageCounters::make_bcb_counters`), and an optional +/// set of additional counters--if needed--to count incoming edges, if there are more than one. +/// (These "edge counters" are eventually converted into new MIR `BasicBlock`s.) +pub(crate) struct CoverageGraph { + bcbs: IndexVec, + bb_to_bcb: IndexVec>, + pub successors: IndexVec>, + pub predecessors: IndexVec>, + dominators: Option>, } -impl BasicCoverageBlock { - pub fn leader_bb(&self) -> BasicBlock { - self.blocks[0] - } +impl CoverageGraph { + pub fn from_mir(mir_body: &mir::Body<'tcx>) -> Self { + let (bcbs, bb_to_bcb) = Self::compute_basic_coverage_blocks(mir_body); - pub fn id(&self) -> String { - format!( - "@{}", - self.blocks - .iter() - .map(|bb| bb.index().to_string()) - .collect::>() - .join(ID_SEPARATOR) - ) - } -} + // Pre-transform MIR `BasicBlock` successors and predecessors into the BasicCoverageBlock + // equivalents. Note that since the BasicCoverageBlock graph has been fully simplified, the + // each predecessor of a BCB leader_bb should be in a unique BCB, and each successor of a + // BCB last_bb should bin in its own unique BCB. Therefore, collecting the BCBs using + // `bb_to_bcb` should work without requiring a deduplication step. -pub(crate) struct BasicCoverageBlocks { - vec: IndexVec>, -} + let successors = IndexVec::from_fn_n( + |bcb| { + let bcb_data = &bcbs[bcb]; + let bcb_successors = + bcb_filtered_successors(&mir_body, &bcb_data.terminator(mir_body).kind) + .filter_map(|&successor_bb| bb_to_bcb[successor_bb]) + .collect::>(); + debug_assert!({ + let mut sorted = bcb_successors.clone(); + sorted.sort_unstable(); + let initial_len = sorted.len(); + sorted.dedup(); + sorted.len() == initial_len + }); + bcb_successors + }, + bcbs.len(), + ); + + let mut predecessors = IndexVec::from_elem_n(Vec::new(), bcbs.len()); + for (bcb, bcb_successors) in successors.iter_enumerated() { + for &successor in bcb_successors { + predecessors[successor].push(bcb); + } + } -impl BasicCoverageBlocks { - pub fn from_mir(mir_body: &mir::Body<'tcx>) -> Self { let mut basic_coverage_blocks = - BasicCoverageBlocks { vec: IndexVec::from_elem_n(None, mir_body.basic_blocks().len()) }; - basic_coverage_blocks.extract_from_mir(mir_body); + Self { bcbs, bb_to_bcb, successors, predecessors, dominators: None }; + let dominators = dominators::dominators(&basic_coverage_blocks); + basic_coverage_blocks.dominators = Some(dominators); basic_coverage_blocks } - pub fn iter(&self) -> impl Iterator { - self.vec.iter().filter_map(|bcb| bcb.as_ref()) - } - - pub fn num_nodes(&self) -> usize { - self.vec.len() - } - - pub fn extract_from_mir(&mut self, mir_body: &mir::Body<'tcx>) { - // Traverse the CFG but ignore anything following an `unwind` - let cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, |term_kind| { - let mut successors = term_kind.successors(); - match &term_kind { - // SwitchInt successors are never unwind, and all of them should be traversed. - - // NOTE: TerminatorKind::FalseEdge targets from SwitchInt don't appear to be - // helpful in identifying unreachable code. I did test the theory, but the following - // changes were not beneficial. (I assumed that replacing some constants with - // non-deterministic variables might effect which blocks were targeted by a - // `FalseEdge` `imaginary_target`. It did not.) - // - // Also note that, if there is a way to identify BasicBlocks that are part of the - // MIR CFG, but not actually reachable, here are some other things to consider: - // - // Injecting unreachable code regions will probably require computing the set - // difference between the basic blocks found without filtering out unreachable - // blocks, and the basic blocks found with the filter; then computing the - // `CoverageSpans` without the filter; and then injecting `Counter`s or - // `CounterExpression`s for blocks that are not unreachable, or injecting - // `Unreachable` code regions otherwise. This seems straightforward, but not - // trivial. - // - // Alternatively, we might instead want to leave the unreachable blocks in - // (bypass the filter here), and inject the counters. This will result in counter - // values of zero (0) for unreachable code (and, notably, the code will be displayed - // with a red background by `llvm-cov show`). - // - // TerminatorKind::SwitchInt { .. } => { - // let some_imaginary_target = successors.clone().find_map(|&successor| { - // let term = mir_body.basic_blocks()[successor].terminator(); - // if let TerminatorKind::FalseEdge { imaginary_target, .. } = term.kind { - // if mir_body.predecessors()[imaginary_target].len() == 1 { - // return Some(imaginary_target); - // } - // } - // None - // }); - // if let Some(imaginary_target) = some_imaginary_target { - // box successors.filter(move |&&successor| successor != imaginary_target) - // } else { - // box successors - // } - // } - // - // Note this also required changing the closure signature for the - // `ShortCurcuitPreorder` to: - // - // F: Fn(&'tcx TerminatorKind<'tcx>) -> Box + 'a>, - TerminatorKind::SwitchInt { .. } => successors, - - // For all other kinds, return only the first successor, if any, and ignore unwinds - _ => successors.next().into_iter().chain(&[]), - } - }); + fn compute_basic_coverage_blocks( + mir_body: &mir::Body<'tcx>, + ) -> ( + IndexVec, + IndexVec>, + ) { + let num_basic_blocks = mir_body.num_nodes(); + let mut bcbs = IndexVec::with_capacity(num_basic_blocks); + let mut bb_to_bcb = IndexVec::from_elem_n(None, num_basic_blocks); - // Walk the CFG using a Preorder traversal, which starts from `START_BLOCK` and follows + // Walk the MIR CFG using a Preorder traversal, which starts from `START_BLOCK` and follows // each block terminator's `successors()`. Coverage spans must map to actual source code, - // so compiler generated blocks and paths can be ignored. To that end the CFG traversal + // so compiler generated blocks and paths can be ignored. To that end, the CFG traversal // intentionally omits unwind paths. - let mut blocks = Vec::new(); - for (bb, data) in cfg_without_unwind { - if let Some(last) = blocks.last() { + let mir_cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, bcb_filtered_successors); + + let mut basic_blocks = Vec::new(); + for (bb, data) in mir_cfg_without_unwind { + if let Some(last) = basic_blocks.last() { let predecessors = &mir_body.predecessors()[bb]; if predecessors.len() > 1 || !predecessors.contains(last) { // The `bb` has more than one _incoming_ edge, and should start its own - // `BasicCoverageBlock`. (Note, the `blocks` vector does not yet include `bb`; - // it contains a sequence of one or more sequential blocks with no intermediate - // branches in or out. Save these as a new `BasicCoverageBlock` before starting - // the new one.) - self.add_basic_coverage_block(blocks.split_off(0)); + // `BasicCoverageBlockData`. (Note, the `basic_blocks` vector does not yet + // include `bb`; it contains a sequence of one or more sequential basic_blocks + // with no intermediate branches in or out. Save these as a new + // `BasicCoverageBlockData` before starting the new one.) + Self::add_basic_coverage_block( + &mut bcbs, + &mut bb_to_bcb, + basic_blocks.split_off(0), + ); debug!( " because {}", if predecessors.len() > 1 { @@ -157,27 +105,40 @@ impl BasicCoverageBlocks { ); } } - blocks.push(bb); + basic_blocks.push(bb); let term = data.terminator(); match term.kind { TerminatorKind::Return { .. } + // FIXME(richkadel): Add test(s) for `Abort` coverage. | TerminatorKind::Abort + // FIXME(richkadel): Add test(s) for `Assert` coverage. + // Should `Assert` be handled like `FalseUnwind` instead? Since we filter out unwind + // branches when creating the BCB CFG, aren't `Assert`s (without unwinds) just like + // `FalseUnwinds` (which are kind of like `Goto`s)? | TerminatorKind::Assert { .. } + // FIXME(richkadel): Add test(s) for `Yield` coverage, and confirm coverage is + // sensible for code using the `yield` keyword. | TerminatorKind::Yield { .. } + // FIXME(richkadel): Also add coverage tests using async/await, and threading. + | TerminatorKind::SwitchInt { .. } => { // The `bb` has more than one _outgoing_ edge, or exits the function. Save the - // current sequence of `blocks` gathered to this point, as a new - // `BasicCoverageBlock`. - self.add_basic_coverage_block(blocks.split_off(0)); + // current sequence of `basic_blocks` gathered to this point, as a new + // `BasicCoverageBlockData`. + Self::add_basic_coverage_block( + &mut bcbs, + &mut bb_to_bcb, + basic_blocks.split_off(0), + ); debug!(" because term.kind = {:?}", term.kind); // Note that this condition is based on `TerminatorKind`, even though it // theoretically boils down to `successors().len() != 1`; that is, either zero // (e.g., `Return`, `Abort`) or multiple successors (e.g., `SwitchInt`), but - // since the Coverage graph (the BCB CFG projection) ignores things like unwind - // branches (which exist in the `Terminator`s `successors()` list) checking the - // number of successors won't work. + // since the BCB CFG ignores things like unwind branches (which exist in the + // `Terminator`s `successors()` list) checking the number of successors won't + // work. } TerminatorKind::Goto { .. } | TerminatorKind::Resume @@ -192,45 +153,222 @@ impl BasicCoverageBlocks { } } - if !blocks.is_empty() { - // process any remaining blocks into a final `BasicCoverageBlock` - self.add_basic_coverage_block(blocks.split_off(0)); - debug!(" because the end of the CFG was reached while traversing"); + if !basic_blocks.is_empty() { + // process any remaining basic_blocks into a final `BasicCoverageBlockData` + Self::add_basic_coverage_block(&mut bcbs, &mut bb_to_bcb, basic_blocks.split_off(0)); + debug!(" because the end of the MIR CFG was reached while traversing"); + } + + (bcbs, bb_to_bcb) + } + + fn add_basic_coverage_block( + bcbs: &mut IndexVec, + bb_to_bcb: &mut IndexVec>, + basic_blocks: Vec, + ) { + let bcb = BasicCoverageBlock::from_usize(bcbs.len()); + for &bb in basic_blocks.iter() { + bb_to_bcb[bb] = Some(bcb); } + let bcb_data = BasicCoverageBlockData::from(basic_blocks); + debug!("adding bcb{}: {:?}", bcb.index(), bcb_data); + bcbs.push(bcb_data); + } + + #[inline(always)] + pub fn iter_enumerated( + &self, + ) -> impl Iterator { + self.bcbs.iter_enumerated() + } + + #[inline(always)] + pub fn bcb_from_bb(&self, bb: BasicBlock) -> Option { + if bb.index() < self.bb_to_bcb.len() { self.bb_to_bcb[bb] } else { None } + } + + #[inline(always)] + pub fn is_dominated_by(&self, node: BasicCoverageBlock, dom: BasicCoverageBlock) -> bool { + self.dominators.as_ref().unwrap().is_dominated_by(node, dom) + } + + #[inline(always)] + pub fn dominators(&self) -> &Dominators { + self.dominators.as_ref().unwrap() + } +} + +impl Index for CoverageGraph { + type Output = BasicCoverageBlockData; + + #[inline] + fn index(&self, index: BasicCoverageBlock) -> &BasicCoverageBlockData { + &self.bcbs[index] + } +} + +impl IndexMut for CoverageGraph { + #[inline] + fn index_mut(&mut self, index: BasicCoverageBlock) -> &mut BasicCoverageBlockData { + &mut self.bcbs[index] + } +} + +impl graph::DirectedGraph for CoverageGraph { + type Node = BasicCoverageBlock; +} + +impl graph::WithNumNodes for CoverageGraph { + #[inline] + fn num_nodes(&self) -> usize { + self.bcbs.len() + } +} + +impl graph::WithStartNode for CoverageGraph { + #[inline] + fn start_node(&self) -> Self::Node { + self.bcb_from_bb(mir::START_BLOCK) + .expect("mir::START_BLOCK should be in a BasicCoverageBlock") + } +} + +type BcbSuccessors<'graph> = std::slice::Iter<'graph, BasicCoverageBlock>; + +impl<'graph> graph::GraphSuccessors<'graph> for CoverageGraph { + type Item = BasicCoverageBlock; + type Iter = std::iter::Cloned>; +} + +impl graph::WithSuccessors for CoverageGraph { + #[inline] + fn successors(&self, node: Self::Node) -> >::Iter { + self.successors[node].iter().cloned() + } +} + +impl graph::GraphPredecessors<'graph> for CoverageGraph { + type Item = BasicCoverageBlock; + type Iter = std::vec::IntoIter; +} + +impl graph::WithPredecessors for CoverageGraph { + #[inline] + fn predecessors(&self, node: Self::Node) -> >::Iter { + self.predecessors[node].clone().into_iter() } +} - fn add_basic_coverage_block(&mut self, blocks: Vec) { - let leader_bb = blocks[0]; - let bcb = BasicCoverageBlock { blocks }; - debug!("adding BCB: {:?}", bcb); - self.vec[leader_bb] = Some(bcb); +rustc_index::newtype_index! { + /// A node in the [control-flow graph][CFG] of CoverageGraph. + pub(crate) struct BasicCoverageBlock { + DEBUG_FORMAT = "bcb{}", } } -impl std::ops::Index for BasicCoverageBlocks { - type Output = BasicCoverageBlock; +/// A BasicCoverageBlockData (BCB) represents the maximal-length sequence of MIR BasicBlocks without +/// conditional branches, and form a new, simplified, coverage-specific Control Flow Graph, without +/// altering the original MIR CFG. +/// +/// Note that running the MIR `SimplifyCfg` transform is not sufficient (and therefore not +/// necessary). The BCB-based CFG is a more aggressive simplification. For example: +/// +/// * The BCB CFG ignores (trims) branches not relevant to coverage, such as unwind-related code, +/// that is injected by the Rust compiler but has no physical source code to count. This also +/// means a BasicBlock with a `Call` terminator can be merged into its primary successor target +/// block, in the same BCB. +/// * Some BasicBlock terminators support Rust-specific concerns--like borrow-checking--that are +/// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as +/// a `Goto`, and merged with its successor into the same BCB. +/// +/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`. +/// In some cases, a BCB's execution count can be computed by `Expression`. Additional +/// disjoint `CoverageSpan`s in a BCB can also be counted by `Expression` (by adding `ZERO` +/// to the BCB's primary counter or expression). +/// +/// The BCB CFG is critical to simplifying the coverage analysis by ensuring graph path-based +/// queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch (control flow) +/// significance. +#[derive(Debug, Clone)] +pub(crate) struct BasicCoverageBlockData { + pub basic_blocks: Vec, +} + +impl BasicCoverageBlockData { + pub fn from(basic_blocks: Vec) -> Self { + assert!(basic_blocks.len() > 0); + Self { basic_blocks } + } + + #[inline(always)] + pub fn leader_bb(&self) -> BasicBlock { + self.basic_blocks[0] + } + + #[inline(always)] + pub fn last_bb(&self) -> BasicBlock { + *self.basic_blocks.last().unwrap() + } + + #[inline(always)] + pub fn terminator<'a, 'tcx>(&self, mir_body: &'a mir::Body<'tcx>) -> &'a Terminator<'tcx> { + &mir_body[self.last_bb()].terminator() + } + + pub fn id(&self) -> String { + format!( + "@{}", + self.basic_blocks + .iter() + .map(|bb| bb.index().to_string()) + .collect::>() + .join(ID_SEPARATOR) + ) + } +} - fn index(&self, index: BasicBlock) -> &Self::Output { - self.vec[index].as_ref().expect("is_some if BasicBlock is a BasicCoverageBlock leader") +fn bcb_filtered_successors<'a, 'tcx>( + body: &'tcx &'a mir::Body<'tcx>, + term_kind: &'tcx TerminatorKind<'tcx>, +) -> Box + 'a> { + let mut successors = term_kind.successors(); + box match &term_kind { + // SwitchInt successors are never unwind, and all of them should be traversed. + TerminatorKind::SwitchInt { .. } => successors, + // For all other kinds, return only the first successor, if any, and ignore unwinds. + // NOTE: `chain(&[])` is required to coerce the `option::iter` (from + // `next().into_iter()`) into the `mir::Successors` aliased type. + _ => successors.next().into_iter().chain(&[]), } + .filter(move |&&successor| body[successor].terminator().kind != TerminatorKind::Unreachable) } pub struct ShortCircuitPreorder< 'a, 'tcx, - F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>, + F: Fn( + &'tcx &'a mir::Body<'tcx>, + &'tcx TerminatorKind<'tcx>, + ) -> Box + 'a>, > { - body: &'a mir::Body<'tcx>, + body: &'tcx &'a mir::Body<'tcx>, visited: BitSet, worklist: Vec, filtered_successors: F, } -impl<'a, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> - ShortCircuitPreorder<'a, 'tcx, F> +impl< + 'a, + 'tcx, + F: Fn( + &'tcx &'a mir::Body<'tcx>, + &'tcx TerminatorKind<'tcx>, + ) -> Box + 'a>, +> ShortCircuitPreorder<'a, 'tcx, F> { pub fn new( - body: &'a mir::Body<'tcx>, + body: &'tcx &'a mir::Body<'tcx>, filtered_successors: F, ) -> ShortCircuitPreorder<'a, 'tcx, F> { let worklist = vec![mir::START_BLOCK]; @@ -244,8 +382,14 @@ impl<'a, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> } } -impl<'a: 'tcx, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> Iterator - for ShortCircuitPreorder<'a, 'tcx, F> +impl< + 'a: 'tcx, + 'tcx, + F: Fn( + &'tcx &'a mir::Body<'tcx>, + &'tcx TerminatorKind<'tcx>, + ) -> Box + 'a>, +> Iterator for ShortCircuitPreorder<'a, 'tcx, F> { type Item = (BasicBlock, &'a BasicBlockData<'tcx>); @@ -258,7 +402,7 @@ impl<'a: 'tcx, 'tcx, F: Fn(&'tcx TerminatorKind<'tcx>) -> mir::Successors<'tcx>> let data = &self.body[idx]; if let Some(ref term) = data.terminator { - self.worklist.extend((self.filtered_successors)(&term.kind)); + self.worklist.extend((self.filtered_successors)(&self.body, &term.kind)); } return Some((idx, data)); diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index 9961afba8e7c4..aa5771cfad4e2 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -6,13 +6,14 @@ mod graph; mod spans; use counters::CoverageCounters; -use graph::BasicCoverageBlocks; +use graph::CoverageGraph; use spans::{CoverageSpan, CoverageSpans}; use crate::transform::MirPass; use crate::util::pretty; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::graph::WithNumNodes; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; use rustc_index::vec::IndexVec; @@ -73,7 +74,7 @@ struct Instrumentor<'a, 'tcx> { tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>, body_span: Span, - basic_coverage_blocks: BasicCoverageBlocks, + basic_coverage_blocks: CoverageGraph, coverage_counters: CoverageCounters, } @@ -82,7 +83,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let hir_body = hir_body(tcx, mir_body.source.def_id()); let body_span = hir_body.value.span; let function_source_hash = hash_mir_source(tcx, hir_body); - let basic_coverage_blocks = BasicCoverageBlocks::from_mir(mir_body); + let basic_coverage_blocks = CoverageGraph::from_mir(mir_body); Self { pass_name, tcx, @@ -103,7 +104,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); //////////////////////////////////////////////////// - // Compute `CoverageSpan`s from the `BasicCoverageBlocks`. + // Compute `CoverageSpan`s from the `CoverageGraph`. let coverage_spans = CoverageSpans::generate_coverage_spans( &self.mir_body, body_span, @@ -135,9 +136,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let source_file = source_map.lookup_source_file(body_span.lo()); let file_name = Symbol::intern(&source_file.name.to_string()); - let mut bb_counters = IndexVec::from_elem_n(None, self.mir_body.basic_blocks().len()); - for CoverageSpan { span, bcb_leader_bb: bb, .. } in coverage_spans { - if let Some(&counter_operand) = bb_counters[bb].as_ref() { + let mut bcb_counters = IndexVec::from_elem_n(None, self.basic_coverage_blocks.num_nodes()); + for covspan in coverage_spans { + let bcb = covspan.bcb; + let span = covspan.span; + if let Some(&counter_operand) = bcb_counters[bcb].as_ref() { let expression = self.coverage_counters.make_expression( counter_operand, Op::Add, @@ -149,6 +152,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { span, source_map.span_to_snippet(span).expect("Error getting source for span"), ); + let bb = self.basic_coverage_blocks[bcb].leader_bb(); let code_region = make_code_region(file_name, &source_file, span, body_span); inject_statement(self.mir_body, expression, bb, Some(code_region)); } else { @@ -160,7 +164,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { source_map.span_to_snippet(span).expect("Error getting source for span"), ); let counter_operand = counter.as_operand_id(); - bb_counters[bb] = Some(counter_operand); + bcb_counters[bcb] = Some(counter_operand); + let bb = self.basic_coverage_blocks[bcb].leader_bb(); let code_region = make_code_region(file_name, &source_file, span, body_span); inject_statement(self.mir_body, counter, bb, Some(code_region)); } diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index 7957b6f3ff592..23531ecf22931 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -1,9 +1,8 @@ use super::debug::term_type; -use super::graph::{BasicCoverageBlock, BasicCoverageBlocks}; +use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph}; use crate::util::spanview::source_range_no_file; -use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::WithNumNodes; use rustc_index::bit_set::BitSet; use rustc_middle::mir::{ @@ -69,7 +68,7 @@ impl CoverageStatement { #[derive(Debug, Clone)] pub(crate) struct CoverageSpan { pub span: Span, - pub bcb_leader_bb: BasicBlock, + pub bcb: BasicCoverageBlock, pub coverage_statements: Vec, pub is_closure: bool, } @@ -78,7 +77,7 @@ impl CoverageSpan { pub fn for_statement( statement: &Statement<'tcx>, span: Span, - bcb: &BasicCoverageBlock, + bcb: BasicCoverageBlock, bb: BasicBlock, stmt_index: usize, ) -> Self { @@ -92,16 +91,16 @@ impl CoverageSpan { Self { span, - bcb_leader_bb: bcb.leader_bb(), + bcb, coverage_statements: vec![CoverageStatement::Statement(bb, span, stmt_index)], is_closure, } } - pub fn for_terminator(span: Span, bcb: &BasicCoverageBlock, bb: BasicBlock) -> Self { + pub fn for_terminator(span: Span, bcb: BasicCoverageBlock, bb: BasicBlock) -> Self { Self { span, - bcb_leader_bb: bcb.leader_bb(), + bcb, coverage_statements: vec![CoverageStatement::Terminator(bb, span)], is_closure: false, } @@ -132,7 +131,7 @@ impl CoverageSpan { #[inline] pub fn is_in_same_bcb(&self, other: &Self) -> bool { - self.bcb_leader_bb == other.bcb_leader_bb + self.bcb == other.bcb } pub fn format_coverage_statements( @@ -164,15 +163,12 @@ pub struct CoverageSpans<'a, 'tcx> { /// The MIR, used to look up `BasicBlockData`. mir_body: &'a mir::Body<'tcx>, - /// A snapshot of the MIR CFG dominators before injecting any coverage statements. - dominators: Dominators, - /// A `Span` covering the function body of the MIR (typically from left curly brace to right /// curly brace). body_span: Span, /// The BasicCoverageBlock Control Flow Graph (BCB CFG). - basic_coverage_blocks: &'a BasicCoverageBlocks, + basic_coverage_blocks: &'a CoverageGraph, /// The initial set of `CoverageSpan`s, sorted by `Span` (`lo` and `hi`) and by relative /// dominance between the `BasicCoverageBlock`s of equal `Span`s. @@ -213,12 +209,10 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { pub(crate) fn generate_coverage_spans( mir_body: &'a mir::Body<'tcx>, body_span: Span, - basic_coverage_blocks: &'a BasicCoverageBlocks, + basic_coverage_blocks: &'a CoverageGraph, ) -> Vec { - let dominators = mir_body.dominators(); let mut coverage_spans = CoverageSpans { mir_body, - dominators, body_span, basic_coverage_blocks, sorted_spans_iter: None, @@ -246,7 +240,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { /// The basic steps are: /// /// 1. Extract an initial set of spans from the `Statement`s and `Terminator`s of each - /// `BasicCoverageBlock`. + /// `BasicCoverageBlockData`. /// 2. Sort the spans by span.lo() (starting position). Spans that start at the same position /// are sorted with longer spans before shorter spans; and equal spans are sorted /// (deterministically) based on "dominator" relationship (if any). @@ -263,8 +257,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { /// to be). fn mir_to_initial_sorted_coverage_spans(&self) -> Vec { let mut initial_spans = Vec::::with_capacity(self.mir_body.num_nodes() * 2); - for bcb in self.basic_coverage_blocks.iter() { - for coverage_span in self.bcb_to_initial_coverage_spans(bcb) { + for (bcb, bcb_data) in self.basic_coverage_blocks.iter_enumerated() { + for coverage_span in self.bcb_to_initial_coverage_spans(bcb, bcb_data) { initial_spans.push(coverage_span); } } @@ -285,7 +279,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { // dominators always come after the dominated equal spans). When later // comparing two spans in order, the first will either dominate the second, // or they will have no dominator relationship. - self.dominators.rank_partial_cmp(b.bcb_leader_bb, a.bcb_leader_bb) + self.basic_coverage_blocks.dominators().rank_partial_cmp(b.bcb, a.bcb) } } else { // Sort hi() in reverse order so shorter spans are attempted after longer spans. @@ -357,13 +351,13 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { let mut has_coverage = BitSet::new_empty(basic_coverage_blocks.num_nodes()); for covspan in &refined_spans { if !covspan.span.is_empty() { - has_coverage.insert(covspan.bcb_leader_bb); + has_coverage.insert(covspan.bcb); } } refined_spans.retain(|covspan| { !(covspan.span.is_empty() - && is_goto(&mir_body[covspan.bcb_leader_bb].terminator().kind) - && has_coverage.contains(covspan.bcb_leader_bb)) + && is_goto(&basic_coverage_blocks[covspan.bcb].terminator(mir_body).kind) + && has_coverage.contains(covspan.bcb)) }); // Remove `CoverageSpan`s derived from closures, originally added to ensure the coverage @@ -374,12 +368,17 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { } // Generate a set of `CoverageSpan`s from the filtered set of `Statement`s and `Terminator`s of - // the `BasicBlock`(s) in the given `BasicCoverageBlock`. One `CoverageSpan` is generated + // the `BasicBlock`(s) in the given `BasicCoverageBlockData`. One `CoverageSpan` is generated // for each `Statement` and `Terminator`. (Note that subsequent stages of coverage analysis will // merge some `CoverageSpan`s, at which point a `CoverageSpan` may represent multiple // `Statement`s and/or `Terminator`s.) - fn bcb_to_initial_coverage_spans(&self, bcb: &BasicCoverageBlock) -> Vec { - bcb.blocks + fn bcb_to_initial_coverage_spans( + &self, + bcb: BasicCoverageBlock, + bcb_data: &'a BasicCoverageBlockData, + ) -> Vec { + bcb_data + .basic_blocks .iter() .map(|bbref| { let bb = *bbref; @@ -636,7 +635,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { } fn span_bcb_is_dominated_by(&self, covspan: &CoverageSpan, dom_covspan: &CoverageSpan) -> bool { - self.dominators.is_dominated_by(covspan.bcb_leader_bb, dom_covspan.bcb_leader_bb) + self.basic_coverage_blocks.is_dominated_by(covspan.bcb, dom_covspan.bcb) } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json index 95a1dcd3b8eee..5a953b90b423f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.lazy_boolean.json @@ -17,14 +17,14 @@ }, "lines": { "count": 40, - "covered": 32, - "percent": 80 + "covered": 30, + "percent": 75 }, "regions": { - "count": 39, - "covered": 28, + "count": 37, + "covered": 26, "notcovered": 11, - "percent": 71.7948717948718 + "percent": 70.27027027027027 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 40, - "covered": 32, - "percent": 80 + "covered": 30, + "percent": 75 }, "regions": { - "count": 39, - "covered": 28, + "count": 37, + "covered": 26, "notcovered": 11, - "percent": 71.7948717948718 + "percent": 70.27027027027027 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json index aec85cd0329cb..cb74a1b7e2716 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.loops_and_branches.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 10, + "count": 9, "covered": 8, - "notcovered": 2, - "percent": 80 + "notcovered": 1, + "percent": 88.88888888888889 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 10, + "count": 9, "covered": 8, - "notcovered": 2, - "percent": 80 + "notcovered": 1, + "percent": 88.88888888888889 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json index dbe4f9ca6fd17..68163eb763619 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.nested_loops.json @@ -17,14 +17,14 @@ }, "lines": { "count": 21, - "covered": 17, - "percent": 80.95238095238095 + "covered": 16, + "percent": 76.19047619047619 }, "regions": { - "count": 20, - "covered": 16, + "count": 18, + "covered": 14, "notcovered": 4, - "percent": 80 + "percent": 77.77777777777779 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 21, - "covered": 17, - "percent": 80.95238095238095 + "covered": 16, + "percent": 76.19047619047619 }, "regions": { - "count": 20, - "covered": 16, + "count": 18, + "covered": 14, "notcovered": 4, - "percent": 80 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json index e845ee29fa452..39e17359eee76 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 20, - "covered": 19, - "percent": 95 + "count": 19, + "covered": 18, + "percent": 94.73684210526315 }, "regions": { - "count": 20, - "covered": 17, + "count": 18, + "covered": 15, "notcovered": 3, - "percent": 85 + "percent": 83.33333333333334 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 20, - "covered": 19, - "percent": 95 + "count": 19, + "covered": 18, + "percent": 94.73684210526315 }, "regions": { - "count": 20, - "covered": 17, + "count": 18, + "covered": 15, "notcovered": 3, - "percent": 85 + "percent": 83.33333333333334 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json index 27862087ed567..339c65556682a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while.json @@ -21,10 +21,10 @@ "percent": 75 }, "regions": { - "count": 5, + "count": 4, "covered": 3, - "notcovered": 2, - "percent": 60 + "notcovered": 1, + "percent": 75 } } } @@ -46,10 +46,10 @@ "percent": 75 }, "regions": { - "count": 5, + "count": 4, "covered": 3, - "notcovered": 2, - "percent": 60 + "notcovered": 1, + "percent": 75 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json index 555ac745d5371..a116a91a60aae 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 18, + "count": 17, "covered": 15, - "percent": 83.33333333333334 + "percent": 88.23529411764706 }, "regions": { - "count": 11, + "count": 10, "covered": 8, - "notcovered": 3, - "percent": 72.72727272727273 + "notcovered": 2, + "percent": 80 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 18, + "count": 17, "covered": 15, - "percent": 83.33333333333334 + "percent": 88.23529411764706 }, "regions": { - "count": 11, + "count": 10, "covered": 8, - "notcovered": 3, - "percent": 72.72727272727273 + "notcovered": 2, + "percent": 80 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt index f01f69f2496ee..1b503033911c5 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.lazy_boolean.txt @@ -50,7 +50,7 @@ 47| 0| { 48| 0| c = 400 49| 0| ; - 50| 1| } + 50| 0| } 51| | 52| 1| if !is_true { 53| 0| a = 2; @@ -60,6 +60,6 @@ 57| 1| b = 30; 58| 1| } else { 59| 0| c = 400; - 60| 1| } + 60| 0| } 61| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt index e0545c76f780f..c9f373bf6a7c0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.nested_loops.txt @@ -19,8 +19,8 @@ 19| 0| a -= 2; 20| 0| } 21| 2| } - 22| 3| } + 22| 2| } 23| 0| countdown -= 1; - 24| 1| } + 24| 0| } 25| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt index 05d72d0de46e6..c43b492db6057 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt @@ -6,7 +6,7 @@ 6| 1| Err(()) 7| | } else { 8| 5| Ok(()) - 9| 1| } + 9| | } 10| 6|} 11| | 12| |fn main() -> Result<(),()> { @@ -31,7 +31,7 @@ 31| 5| call(/*return_error=*/ false)?; ^0 32| 5| } - 33| 6| } + 33| 5| } 34| 0| Ok(()) 35| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt index 2e0c4022bedb8..e5c5b05a6fc80 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt @@ -24,7 +24,7 @@ 24| | else 25| | { 26| 1| Err(1) - 27| 0| } + 27| | } 28| | ; 29| | } 30| 6| countdown diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt index 447c3c8956230..2bafe7d88e24c 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt @@ -4,14 +4,13 @@ Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) Counter in file 0 20:9 -> 21:22, #2 Counter in file 0 27:1 -> 27:2, #4 -Counter in file 0 27:1 -> 27:2, (#2 + 0) Emitting segments for file: ../coverage/drop_trait.rs Combined regions: 9:24 -> 11:6 (count=2) 15:9 -> 17:42 (count=1) 19:8 -> 19:12 (count=1) 20:9 -> 21:22 (count=1) - 27:1 -> 27:2 (count=2) + 27:1 -> 27:2 (count=1) Segment at 9:24 (count = 2), RegionEntry Segment at 11:6 (count = 0), Skipped Segment at 15:9 (count = 1), RegionEntry @@ -20,5 +19,5 @@ Segment at 19:8 (count = 1), RegionEntry Segment at 19:12 (count = 0), Skipped Segment at 20:9 (count = 1), RegionEntry Segment at 21:22 (count = 0), Skipped -Segment at 27:1 (count = 2), RegionEntry +Segment at 27:1 (count = 1), RegionEntry Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt index 5843b9175883f..a13b1f3d78614 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt @@ -5,7 +5,6 @@ Counter in file 0 23:9 -> 28:28, #1 Counter in file 0 30:8 -> 30:12, (#1 + 0) Counter in file 0 31:9 -> 32:22, #2 Counter in file 0 38:1 -> 38:2, #4 -Counter in file 0 38:1 -> 38:2, (#2 + 0) Counter in file 0 10:49 -> 12:6, #1 Counter in file 0 10:49 -> 12:6, #1 Emitting segments for file: ../coverage/generics.rs @@ -15,7 +14,7 @@ Combined regions: 23:9 -> 28:28 (count=1) 30:8 -> 30:12 (count=1) 31:9 -> 32:22 (count=1) - 38:1 -> 38:2 (count=2) + 38:1 -> 38:2 (count=1) Segment at 10:49 (count = 3), RegionEntry Segment at 12:6 (count = 0), Skipped Segment at 17:24 (count = 2), RegionEntry @@ -26,7 +25,7 @@ Segment at 30:8 (count = 1), RegionEntry Segment at 30:12 (count = 0), Skipped Segment at 31:9 (count = 1), RegionEntry Segment at 32:22 (count = 0), Skipped -Segment at 38:1 (count = 2), RegionEntry +Segment at 38:1 (count = 1), RegionEntry Segment at 38:2 (count = 0), Skipped Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_ Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt index 660e85f91f52b..270a6f2b14a34 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt @@ -2,22 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 Counter in file 0 20:9 -> 22:16, #3 -Counter in file 0 23:6 -> 23:7, (#2 + 0) Counter in file 0 26:9 -> 26:16, #4 Counter in file 0 27:5 -> 32:6, #5 Counter in file 0 34:5 -> 39:6, #6 -Counter in file 0 39:6 -> 39:7, (#5 + 0) Counter in file 0 40:1 -> 40:2, #7 Emitting segments for file: ../coverage/if_else.rs Combined regions: 7:9 -> 11:16 (count=1) 12:5 -> 17:6 (count=1) 20:9 -> 22:16 (count=0) - 23:6 -> 23:7 (count=1) 26:9 -> 26:16 (count=1) 27:5 -> 32:6 (count=1) 34:5 -> 39:6 (count=0) - 39:6 -> 39:7 (count=1) 40:1 -> 40:2 (count=1) Segment at 7:9 (count = 1), RegionEntry Segment at 11:16 (count = 0), Skipped @@ -25,14 +21,11 @@ Segment at 12:5 (count = 1), RegionEntry Segment at 17:6 (count = 0), Skipped Segment at 20:9 (count = 0), RegionEntry Segment at 22:16 (count = 0), Skipped -Segment at 23:6 (count = 1), RegionEntry -Segment at 23:7 (count = 0), Skipped Segment at 26:9 (count = 1), RegionEntry Segment at 26:16 (count = 0), Skipped Segment at 27:5 (count = 1), RegionEntry Segment at 32:6 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry -Segment at 39:6 (count = 1), RegionEntry -Segment at 39:7 (count = 0), Skipped +Segment at 39:6 (count = 0), Skipped Segment at 40:1 (count = 1), RegionEntry Segment at 40:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt index dd93c3a9392c9..4561fcc5b36a5 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt @@ -29,14 +29,12 @@ Counter in file 0 38:6 -> 38:7, #22 Counter in file 0 41:9 -> 41:16, #23 Counter in file 0 42:5 -> 45:6, #24 Counter in file 0 47:5 -> 50:6, #25 -Counter in file 0 50:6 -> 50:7, (#24 + 0) Counter in file 0 52:8 -> 52:16, #26 Counter in file 0 52:17 -> 54:6, #27 Counter in file 0 54:6 -> 54:7, #28 Counter in file 0 56:8 -> 56:15, #29 Counter in file 0 56:16 -> 58:6, #30 Counter in file 0 58:12 -> 60:6, #31 -Counter in file 0 60:6 -> 60:7, (#30 + 0) Counter in file 0 61:1 -> 61:2, #32 Emitting segments for file: ../coverage/lazy_boolean.rs Combined regions: @@ -66,14 +64,12 @@ Combined regions: 41:9 -> 41:16 (count=1) 42:5 -> 45:6 (count=1) 47:5 -> 50:6 (count=0) - 50:6 -> 50:7 (count=1) 52:8 -> 52:16 (count=1) 52:17 -> 54:6 (count=0) 54:6 -> 54:7 (count=1) 56:8 -> 56:15 (count=1) 56:16 -> 58:6 (count=1) 58:12 -> 60:6 (count=0) - 60:6 -> 60:7 (count=1) 61:1 -> 61:2 (count=1) Segment at 7:9 (count = 1), RegionEntry Segment at 9:42 (count = 0), Skipped @@ -120,8 +116,7 @@ Segment at 41:16 (count = 0), Skipped Segment at 42:5 (count = 1), RegionEntry Segment at 45:6 (count = 0), Skipped Segment at 47:5 (count = 0), RegionEntry -Segment at 50:6 (count = 1), RegionEntry -Segment at 50:7 (count = 0), Skipped +Segment at 50:6 (count = 0), Skipped Segment at 52:8 (count = 1), RegionEntry Segment at 52:16 (count = 0), Skipped Segment at 52:17 (count = 0), RegionEntry @@ -132,7 +127,6 @@ Segment at 56:15 (count = 0), Skipped Segment at 56:16 (count = 1), RegionEntry Segment at 58:6 (count = 0), Skipped Segment at 58:12 (count = 0), RegionEntry -Segment at 60:6 (count = 1), RegionEntry -Segment at 60:7 (count = 0), Skipped +Segment at 60:6 (count = 0), Skipped Segment at 61:1 (count = 1), RegionEntry Segment at 61:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt index d6e4403268a1d..7cde2205cbfd4 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt @@ -7,7 +7,6 @@ Counter in file 0 15:31 -> 15:32, #8 Counter in file 0 17:10 -> 17:11, #10 Counter in file 0 18:9 -> 18:15, #11 Counter in file 0 19:5 -> 19:6, #12 -Counter in file 0 19:5 -> 19:6, (#8 + 0) Counter in file 0 22:11 -> 25:2, #1 Emitting segments for file: ../coverage/loops_and_branches.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt index eec4aec79e6b5..59fb5c366f2cb 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt @@ -14,10 +14,8 @@ Counter in file 0 17:21 -> 17:33, #10 Counter in file 0 19:21 -> 21:14, #11 Counter in file 0 21:14 -> 21:15, #12 Counter in file 0 22:10 -> 22:11, #13 -Counter in file 0 22:10 -> 22:11, (#3 + 0) Counter in file 0 23:9 -> 23:23, #14 Counter in file 0 24:6 -> 24:7, #15 -Counter in file 0 24:6 -> 24:7, (#1 + 0) Counter in file 0 25:1 -> 25:2, #16 Emitting segments for file: ../coverage/nested_loops.rs Combined regions: @@ -35,9 +33,9 @@ Combined regions: 17:21 -> 17:33 (count=1) 19:21 -> 21:14 (count=0) 21:14 -> 21:15 (count=2) - 22:10 -> 22:11 (count=3) + 22:10 -> 22:11 (count=2) 23:9 -> 23:23 (count=0) - 24:6 -> 24:7 (count=1) + 24:6 -> 24:7 (count=0) 25:1 -> 25:2 (count=1) Segment at 2:9 (count = 1), RegionEntry Segment at 3:27 (count = 0), Skipped @@ -66,11 +64,11 @@ Segment at 17:33 (count = 0), Skipped Segment at 19:21 (count = 0), RegionEntry Segment at 21:14 (count = 2), RegionEntry Segment at 21:15 (count = 0), Skipped -Segment at 22:10 (count = 3), RegionEntry +Segment at 22:10 (count = 2), RegionEntry Segment at 22:11 (count = 0), Skipped Segment at 23:9 (count = 0), RegionEntry Segment at 23:23 (count = 0), Skipped -Segment at 24:6 (count = 1), RegionEntry +Segment at 24:6 (count = 0), RegionEntry Segment at 24:7 (count = 0), Skipped Segment at 25:1 (count = 1), RegionEntry Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt index d510223417aac..7dea637551db4 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt @@ -10,21 +10,18 @@ Counter in file 0 31:42 -> 31:43, #8 Counter in file 0 32:10 -> 32:11, #9 Counter in file 0 32:10 -> 32:11, #10 Counter in file 0 33:6 -> 33:7, #11 -Counter in file 0 33:6 -> 33:7, (#1 + 0) Counter in file 0 34:5 -> 34:11, #12 Counter in file 0 35:1 -> 35:2, #13 Counter in file 0 35:1 -> 35:2, #14 Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 Counter in file 0 8:9 -> 8:15, #3 -Counter in file 0 9:6 -> 9:7, (#2 + 0) Counter in file 0 10:1 -> 10:2, #4 Emitting segments for file: ../coverage/try_error_result.rs Combined regions: 5:8 -> 5:20 (count=6) 6:9 -> 6:16 (count=1) 8:9 -> 8:15 (count=5) - 9:6 -> 9:7 (count=1) 10:1 -> 10:2 (count=6) 13:9 -> 14:23 (count=1) 17:9 -> 17:10 (count=6) @@ -35,7 +32,7 @@ Combined regions: 31:13 -> 31:42 (count=5) 31:42 -> 31:43 (count=0) 32:10 -> 32:11 (count=5) - 33:6 -> 33:7 (count=6) + 33:6 -> 33:7 (count=5) 34:5 -> 34:11 (count=0) 35:1 -> 35:2 (count=2) Segment at 5:8 (count = 6), RegionEntry @@ -44,8 +41,6 @@ Segment at 6:9 (count = 1), RegionEntry Segment at 6:16 (count = 0), Skipped Segment at 8:9 (count = 5), RegionEntry Segment at 8:15 (count = 0), Skipped -Segment at 9:6 (count = 1), RegionEntry -Segment at 9:7 (count = 0), Skipped Segment at 10:1 (count = 6), RegionEntry Segment at 10:2 (count = 0), Skipped Segment at 13:9 (count = 1), RegionEntry @@ -64,7 +59,7 @@ Segment at 31:42 (count = 0), RegionEntry Segment at 31:43 (count = 0), Skipped Segment at 32:10 (count = 5), RegionEntry Segment at 32:11 (count = 0), Skipped -Segment at 33:6 (count = 6), RegionEntry +Segment at 33:6 (count = 5), RegionEntry Segment at 33:7 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry Segment at 34:11 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt index 52c809b53255c..a2be958660eda 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt @@ -2,21 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 2:9 -> 2:16, #1 Counter in file 0 3:11 -> 3:20, #2 Counter in file 0 3:21 -> 4:6, #3 -Counter in file 0 4:6 -> 4:7, (#3 + 0) Counter in file 0 5:1 -> 5:2, #4 Emitting segments for file: ../coverage/while.rs Combined regions: 2:9 -> 2:16 (count=1) 3:11 -> 3:20 (count=1) 3:21 -> 4:6 (count=0) - 4:6 -> 4:7 (count=0) 5:1 -> 5:2 (count=1) Segment at 2:9 (count = 1), RegionEntry Segment at 2:16 (count = 0), Skipped Segment at 3:11 (count = 1), RegionEntry Segment at 3:20 (count = 0), Skipped Segment at 3:21 (count = 0), RegionEntry -Segment at 4:6 (count = 0), RegionEntry -Segment at 4:7 (count = 0), Skipped +Segment at 4:6 (count = 0), Skipped Segment at 5:1 (count = 1), RegionEntry Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt index 30d14f4f987f7..02ab24050bad5 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt @@ -5,7 +5,6 @@ Counter in file 0 12:13 -> 14:14, #3 Counter in file 0 18:21 -> 20:22, #4 Counter in file 0 22:21 -> 22:27, #5 Counter in file 0 26:21 -> 26:27, #6 -Counter in file 0 27:18 -> 27:19, (#5 + 0) Counter in file 0 30:9 -> 32:10, #7 Counter in file 0 35:5 -> 35:11, #8 Counter in file 0 36:1 -> 36:2, #9 @@ -18,7 +17,6 @@ Combined regions: 18:21 -> 20:22 (count=1) 22:21 -> 22:27 (count=0) 26:21 -> 26:27 (count=1) - 27:18 -> 27:19 (count=0) 30:9 -> 32:10 (count=6) 35:5 -> 35:11 (count=0) 36:1 -> 36:2 (count=2) @@ -34,8 +32,6 @@ Segment at 22:21 (count = 0), RegionEntry Segment at 22:27 (count = 0), Skipped Segment at 26:21 (count = 1), RegionEntry Segment at 26:27 (count = 0), Skipped -Segment at 27:18 (count = 0), RegionEntry -Segment at 27:19 (count = 0), Skipped Segment at 30:9 (count = 6), RegionEntry Segment at 32:10 (count = 0), Skipped Segment at 35:5 (count = 0), RegionEntry diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json index 95a1dcd3b8eee..5a953b90b423f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.lazy_boolean.json @@ -17,14 +17,14 @@ }, "lines": { "count": 40, - "covered": 32, - "percent": 80 + "covered": 30, + "percent": 75 }, "regions": { - "count": 39, - "covered": 28, + "count": 37, + "covered": 26, "notcovered": 11, - "percent": 71.7948717948718 + "percent": 70.27027027027027 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 40, - "covered": 32, - "percent": 80 + "covered": 30, + "percent": 75 }, "regions": { - "count": 39, - "covered": 28, + "count": 37, + "covered": 26, "notcovered": 11, - "percent": 71.7948717948718 + "percent": 70.27027027027027 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json index aec85cd0329cb..cb74a1b7e2716 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.loops_and_branches.json @@ -21,10 +21,10 @@ "percent": 100 }, "regions": { - "count": 10, + "count": 9, "covered": 8, - "notcovered": 2, - "percent": 80 + "notcovered": 1, + "percent": 88.88888888888889 } } } @@ -46,10 +46,10 @@ "percent": 100 }, "regions": { - "count": 10, + "count": 9, "covered": 8, - "notcovered": 2, - "percent": 80 + "notcovered": 1, + "percent": 88.88888888888889 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json index dbe4f9ca6fd17..68163eb763619 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.nested_loops.json @@ -17,14 +17,14 @@ }, "lines": { "count": 21, - "covered": 17, - "percent": 80.95238095238095 + "covered": 16, + "percent": 76.19047619047619 }, "regions": { - "count": 20, - "covered": 16, + "count": 18, + "covered": 14, "notcovered": 4, - "percent": 80 + "percent": 77.77777777777779 } } } @@ -42,14 +42,14 @@ }, "lines": { "count": 21, - "covered": 17, - "percent": 80.95238095238095 + "covered": 16, + "percent": 76.19047619047619 }, "regions": { - "count": 20, - "covered": 16, + "count": 18, + "covered": 14, "notcovered": 4, - "percent": 80 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json index e845ee29fa452..39e17359eee76 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 20, - "covered": 19, - "percent": 95 + "count": 19, + "covered": 18, + "percent": 94.73684210526315 }, "regions": { - "count": 20, - "covered": 17, + "count": 18, + "covered": 15, "notcovered": 3, - "percent": 85 + "percent": 83.33333333333334 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 20, - "covered": 19, - "percent": 95 + "count": 19, + "covered": 18, + "percent": 94.73684210526315 }, "regions": { - "count": 20, - "covered": 17, + "count": 18, + "covered": 15, "notcovered": 3, - "percent": 85 + "percent": 83.33333333333334 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json index 27862087ed567..339c65556682a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while.json @@ -21,10 +21,10 @@ "percent": 75 }, "regions": { - "count": 5, + "count": 4, "covered": 3, - "notcovered": 2, - "percent": 60 + "notcovered": 1, + "percent": 75 } } } @@ -46,10 +46,10 @@ "percent": 75 }, "regions": { - "count": 5, + "count": 4, "covered": 3, - "notcovered": 2, - "percent": 60 + "notcovered": 1, + "percent": 75 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json index 555ac745d5371..a116a91a60aae 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 18, + "count": 17, "covered": 15, - "percent": 83.33333333333334 + "percent": 88.23529411764706 }, "regions": { - "count": 11, + "count": 10, "covered": 8, - "notcovered": 3, - "percent": 72.72727272727273 + "notcovered": 2, + "percent": 80 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 18, + "count": 17, "covered": 15, - "percent": 83.33333333333334 + "percent": 88.23529411764706 }, "regions": { - "count": 11, + "count": 10, "covered": 8, - "notcovered": 3, - "percent": 72.72727272727273 + "notcovered": 2, + "percent": 80 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt index f01f69f2496ee..1b503033911c5 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.lazy_boolean.txt @@ -50,7 +50,7 @@ 47| 0| { 48| 0| c = 400 49| 0| ; - 50| 1| } + 50| 0| } 51| | 52| 1| if !is_true { 53| 0| a = 2; @@ -60,6 +60,6 @@ 57| 1| b = 30; 58| 1| } else { 59| 0| c = 400; - 60| 1| } + 60| 0| } 61| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt index e0545c76f780f..c9f373bf6a7c0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.nested_loops.txt @@ -19,8 +19,8 @@ 19| 0| a -= 2; 20| 0| } 21| 2| } - 22| 3| } + 22| 2| } 23| 0| countdown -= 1; - 24| 1| } + 24| 0| } 25| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt index 05d72d0de46e6..c43b492db6057 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt @@ -6,7 +6,7 @@ 6| 1| Err(()) 7| | } else { 8| 5| Ok(()) - 9| 1| } + 9| | } 10| 6|} 11| | 12| |fn main() -> Result<(),()> { @@ -31,7 +31,7 @@ 31| 5| call(/*return_error=*/ false)?; ^0 32| 5| } - 33| 6| } + 33| 5| } 34| 0| Ok(()) 35| 2|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt index 2e0c4022bedb8..e5c5b05a6fc80 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt @@ -24,7 +24,7 @@ 24| | else 25| | { 26| 1| Err(1) - 27| 0| } + 27| | } 28| | ; 29| | } 30| 6| countdown diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt index e416a84820a30..124a01af34212 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt @@ -4,14 +4,13 @@ Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) Counter in file 0 20:9 -> 21:22, #2 Counter in file 0 27:1 -> 27:2, #4 -Counter in file 0 27:1 -> 27:2, (#2 + 0) Emitting segments for file: ../coverage/drop_trait.rs Combined regions: 9:24 -> 11:6 (count=2) 15:9 -> 17:42 (count=1) 19:8 -> 19:12 (count=1) 20:9 -> 21:22 (count=1) - 27:1 -> 27:2 (count=2) + 27:1 -> 27:2 (count=1) Segment at 9:24 (count = 2), RegionEntry Segment at 11:6 (count = 0), Skipped Segment at 15:9 (count = 1), RegionEntry @@ -20,5 +19,5 @@ Segment at 19:8 (count = 1), RegionEntry Segment at 19:12 (count = 0), Skipped Segment at 20:9 (count = 1), RegionEntry Segment at 21:22 (count = 0), Skipped -Segment at 27:1 (count = 2), RegionEntry +Segment at 27:1 (count = 1), RegionEntry Segment at 27:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt index 9e33b48fc29c0..a0e9146035eec 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt @@ -5,7 +5,6 @@ Counter in file 0 23:9 -> 28:28, #1 Counter in file 0 30:8 -> 30:12, (#1 + 0) Counter in file 0 31:9 -> 32:22, #2 Counter in file 0 38:1 -> 38:2, #4 -Counter in file 0 38:1 -> 38:2, (#2 + 0) Counter in file 0 10:49 -> 12:6, #1 Counter in file 0 10:49 -> 12:6, #1 Emitting segments for file: ../coverage/generics.rs @@ -15,7 +14,7 @@ Combined regions: 23:9 -> 28:28 (count=1) 30:8 -> 30:12 (count=1) 31:9 -> 32:22 (count=1) - 38:1 -> 38:2 (count=2) + 38:1 -> 38:2 (count=1) Segment at 10:49 (count = 3), RegionEntry Segment at 12:6 (count = 0), Skipped Segment at 17:24 (count = 2), RegionEntry @@ -26,7 +25,7 @@ Segment at 30:8 (count = 1), RegionEntry Segment at 30:12 (count = 0), Skipped Segment at 31:9 (count = 1), RegionEntry Segment at 32:22 (count = 0), Skipped -Segment at 38:1 (count = 2), RegionEntry +Segment at 38:1 (count = 1), RegionEntry Segment at 38:2 (count = 0), Skipped Emitting segments for function: _RNvMCs4fqI2P2rA04_8genericsINtB2_8FireworkdE12set_strengthB2_ Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt index a620bf8ae4a62..9406b6a269d4a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt @@ -2,22 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 Counter in file 0 20:9 -> 22:16, #3 -Counter in file 0 23:6 -> 23:7, (#2 + 0) Counter in file 0 26:9 -> 26:16, #4 Counter in file 0 27:5 -> 32:6, #5 Counter in file 0 34:5 -> 39:6, #6 -Counter in file 0 39:6 -> 39:7, (#5 + 0) Counter in file 0 40:1 -> 40:2, #7 Emitting segments for file: ../coverage/if_else.rs Combined regions: 7:9 -> 11:16 (count=1) 12:5 -> 17:6 (count=1) 20:9 -> 22:16 (count=0) - 23:6 -> 23:7 (count=1) 26:9 -> 26:16 (count=1) 27:5 -> 32:6 (count=1) 34:5 -> 39:6 (count=0) - 39:6 -> 39:7 (count=1) 40:1 -> 40:2 (count=1) Segment at 7:9 (count = 1), RegionEntry Segment at 11:16 (count = 0), Skipped @@ -25,14 +21,11 @@ Segment at 12:5 (count = 1), RegionEntry Segment at 17:6 (count = 0), Skipped Segment at 20:9 (count = 0), RegionEntry Segment at 22:16 (count = 0), Skipped -Segment at 23:6 (count = 1), RegionEntry -Segment at 23:7 (count = 0), Skipped Segment at 26:9 (count = 1), RegionEntry Segment at 26:16 (count = 0), Skipped Segment at 27:5 (count = 1), RegionEntry Segment at 32:6 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry -Segment at 39:6 (count = 1), RegionEntry -Segment at 39:7 (count = 0), Skipped +Segment at 39:6 (count = 0), Skipped Segment at 40:1 (count = 1), RegionEntry Segment at 40:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt index 0f54f4904b054..c95275c6223ba 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt @@ -29,14 +29,12 @@ Counter in file 0 38:6 -> 38:7, #22 Counter in file 0 41:9 -> 41:16, #23 Counter in file 0 42:5 -> 45:6, #24 Counter in file 0 47:5 -> 50:6, #25 -Counter in file 0 50:6 -> 50:7, (#24 + 0) Counter in file 0 52:8 -> 52:16, #26 Counter in file 0 52:17 -> 54:6, #27 Counter in file 0 54:6 -> 54:7, #28 Counter in file 0 56:8 -> 56:15, #29 Counter in file 0 56:16 -> 58:6, #30 Counter in file 0 58:12 -> 60:6, #31 -Counter in file 0 60:6 -> 60:7, (#30 + 0) Counter in file 0 61:1 -> 61:2, #32 Emitting segments for file: ../coverage/lazy_boolean.rs Combined regions: @@ -66,14 +64,12 @@ Combined regions: 41:9 -> 41:16 (count=1) 42:5 -> 45:6 (count=1) 47:5 -> 50:6 (count=0) - 50:6 -> 50:7 (count=1) 52:8 -> 52:16 (count=1) 52:17 -> 54:6 (count=0) 54:6 -> 54:7 (count=1) 56:8 -> 56:15 (count=1) 56:16 -> 58:6 (count=1) 58:12 -> 60:6 (count=0) - 60:6 -> 60:7 (count=1) 61:1 -> 61:2 (count=1) Segment at 7:9 (count = 1), RegionEntry Segment at 9:42 (count = 0), Skipped @@ -120,8 +116,7 @@ Segment at 41:16 (count = 0), Skipped Segment at 42:5 (count = 1), RegionEntry Segment at 45:6 (count = 0), Skipped Segment at 47:5 (count = 0), RegionEntry -Segment at 50:6 (count = 1), RegionEntry -Segment at 50:7 (count = 0), Skipped +Segment at 50:6 (count = 0), Skipped Segment at 52:8 (count = 1), RegionEntry Segment at 52:16 (count = 0), Skipped Segment at 52:17 (count = 0), RegionEntry @@ -132,7 +127,6 @@ Segment at 56:15 (count = 0), Skipped Segment at 56:16 (count = 1), RegionEntry Segment at 58:6 (count = 0), Skipped Segment at 58:12 (count = 0), RegionEntry -Segment at 60:6 (count = 1), RegionEntry -Segment at 60:7 (count = 0), Skipped +Segment at 60:6 (count = 0), Skipped Segment at 61:1 (count = 1), RegionEntry Segment at 61:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt index ca3b1d6134333..3e0bc6e495929 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt @@ -7,7 +7,6 @@ Counter in file 0 15:31 -> 15:32, #8 Counter in file 0 17:10 -> 17:11, #10 Counter in file 0 18:9 -> 18:15, #11 Counter in file 0 19:5 -> 19:6, #12 -Counter in file 0 19:5 -> 19:6, (#8 + 0) Counter in file 0 22:11 -> 25:2, #1 Emitting segments for file: ../coverage/loops_and_branches.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt index 9c9c46a083404..a19f625331655 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt @@ -14,10 +14,8 @@ Counter in file 0 17:21 -> 17:33, #10 Counter in file 0 19:21 -> 21:14, #11 Counter in file 0 21:14 -> 21:15, #12 Counter in file 0 22:10 -> 22:11, #13 -Counter in file 0 22:10 -> 22:11, (#3 + 0) Counter in file 0 23:9 -> 23:23, #14 Counter in file 0 24:6 -> 24:7, #15 -Counter in file 0 24:6 -> 24:7, (#1 + 0) Counter in file 0 25:1 -> 25:2, #16 Emitting segments for file: ../coverage/nested_loops.rs Combined regions: @@ -35,9 +33,9 @@ Combined regions: 17:21 -> 17:33 (count=1) 19:21 -> 21:14 (count=0) 21:14 -> 21:15 (count=2) - 22:10 -> 22:11 (count=3) + 22:10 -> 22:11 (count=2) 23:9 -> 23:23 (count=0) - 24:6 -> 24:7 (count=1) + 24:6 -> 24:7 (count=0) 25:1 -> 25:2 (count=1) Segment at 2:9 (count = 1), RegionEntry Segment at 3:27 (count = 0), Skipped @@ -66,11 +64,11 @@ Segment at 17:33 (count = 0), Skipped Segment at 19:21 (count = 0), RegionEntry Segment at 21:14 (count = 2), RegionEntry Segment at 21:15 (count = 0), Skipped -Segment at 22:10 (count = 3), RegionEntry +Segment at 22:10 (count = 2), RegionEntry Segment at 22:11 (count = 0), Skipped Segment at 23:9 (count = 0), RegionEntry Segment at 23:23 (count = 0), Skipped -Segment at 24:6 (count = 1), RegionEntry +Segment at 24:6 (count = 0), RegionEntry Segment at 24:7 (count = 0), Skipped Segment at 25:1 (count = 1), RegionEntry Segment at 25:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt index dbcaa57b4b296..a444ea4490175 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -2,8 +2,7 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 4:39 -> 4:49, #1 Counter in file 0 4:39 -> 4:49, #2 Counter in file 0 4:39 -> 4:49, #3 -Counter in file 0 4:39 -> 4:49, #4 -Counter in file 0 4:48 -> 4:49, #5 +Counter in file 0 4:48 -> 4:49, #4 Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 21:11 -> 26:2, #1 Counter in file 0 4:39 -> 4:40, #1 @@ -20,8 +19,7 @@ Counter in file 0 4:32 -> 4:33, #5 Counter in file 0 4:51 -> 4:54, #1 Counter in file 0 4:51 -> 4:54, #2 Counter in file 0 4:51 -> 4:54, #3 -Counter in file 0 4:51 -> 4:54, #4 -Counter in file 0 4:53 -> 4:54, #5 +Counter in file 0 4:53 -> 4:54, #4 Counter in file 0 13:9 -> 18:6, #1 Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 4:39 -> 4:40, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt index 10fc52354b9b5..25e1c8930bca8 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt @@ -10,21 +10,18 @@ Counter in file 0 31:42 -> 31:43, #8 Counter in file 0 32:10 -> 32:11, #9 Counter in file 0 32:10 -> 32:11, #10 Counter in file 0 33:6 -> 33:7, #11 -Counter in file 0 33:6 -> 33:7, (#1 + 0) Counter in file 0 34:5 -> 34:11, #12 Counter in file 0 35:1 -> 35:2, #13 Counter in file 0 35:1 -> 35:2, #14 Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 Counter in file 0 8:9 -> 8:15, #3 -Counter in file 0 9:6 -> 9:7, (#2 + 0) Counter in file 0 10:1 -> 10:2, #4 Emitting segments for file: ../coverage/try_error_result.rs Combined regions: 5:8 -> 5:20 (count=6) 6:9 -> 6:16 (count=1) 8:9 -> 8:15 (count=5) - 9:6 -> 9:7 (count=1) 10:1 -> 10:2 (count=6) 13:9 -> 14:23 (count=1) 17:9 -> 17:10 (count=6) @@ -35,7 +32,7 @@ Combined regions: 31:13 -> 31:42 (count=5) 31:42 -> 31:43 (count=0) 32:10 -> 32:11 (count=5) - 33:6 -> 33:7 (count=6) + 33:6 -> 33:7 (count=5) 34:5 -> 34:11 (count=0) 35:1 -> 35:2 (count=2) Segment at 5:8 (count = 6), RegionEntry @@ -44,8 +41,6 @@ Segment at 6:9 (count = 1), RegionEntry Segment at 6:16 (count = 0), Skipped Segment at 8:9 (count = 5), RegionEntry Segment at 8:15 (count = 0), Skipped -Segment at 9:6 (count = 1), RegionEntry -Segment at 9:7 (count = 0), Skipped Segment at 10:1 (count = 6), RegionEntry Segment at 10:2 (count = 0), Skipped Segment at 13:9 (count = 1), RegionEntry @@ -64,7 +59,7 @@ Segment at 31:42 (count = 0), RegionEntry Segment at 31:43 (count = 0), Skipped Segment at 32:10 (count = 5), RegionEntry Segment at 32:11 (count = 0), Skipped -Segment at 33:6 (count = 6), RegionEntry +Segment at 33:6 (count = 5), RegionEntry Segment at 33:7 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry Segment at 34:11 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt index 1aad1a3c83b85..b75a88b2e929e 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt @@ -2,21 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 2:9 -> 2:16, #1 Counter in file 0 3:11 -> 3:20, #2 Counter in file 0 3:21 -> 4:6, #3 -Counter in file 0 4:6 -> 4:7, (#3 + 0) Counter in file 0 5:1 -> 5:2, #4 Emitting segments for file: ../coverage/while.rs Combined regions: 2:9 -> 2:16 (count=1) 3:11 -> 3:20 (count=1) 3:21 -> 4:6 (count=0) - 4:6 -> 4:7 (count=0) 5:1 -> 5:2 (count=1) Segment at 2:9 (count = 1), RegionEntry Segment at 2:16 (count = 0), Skipped Segment at 3:11 (count = 1), RegionEntry Segment at 3:20 (count = 0), Skipped Segment at 3:21 (count = 0), RegionEntry -Segment at 4:6 (count = 0), RegionEntry -Segment at 4:7 (count = 0), Skipped +Segment at 4:6 (count = 0), Skipped Segment at 5:1 (count = 1), RegionEntry Segment at 5:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt index 7c24ea22d67e1..908613018a49a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt @@ -5,7 +5,6 @@ Counter in file 0 12:13 -> 14:14, #3 Counter in file 0 18:21 -> 20:22, #4 Counter in file 0 22:21 -> 22:27, #5 Counter in file 0 26:21 -> 26:27, #6 -Counter in file 0 27:18 -> 27:19, (#5 + 0) Counter in file 0 30:9 -> 32:10, #7 Counter in file 0 35:5 -> 35:11, #8 Counter in file 0 36:1 -> 36:2, #9 @@ -18,7 +17,6 @@ Combined regions: 18:21 -> 20:22 (count=1) 22:21 -> 22:27 (count=0) 26:21 -> 26:27 (count=1) - 27:18 -> 27:19 (count=0) 30:9 -> 32:10 (count=6) 35:5 -> 35:11 (count=0) 36:1 -> 36:2 (count=2) @@ -34,8 +32,6 @@ Segment at 22:21 (count = 0), RegionEntry Segment at 22:27 (count = 0), Skipped Segment at 26:21 (count = 1), RegionEntry Segment at 26:27 (count = 0), Skipped -Segment at 27:18 (count = 0), RegionEntry -Segment at 27:19 (count = 0), Skipped Segment at 30:9 (count = 6), RegionEntry Segment at 32:10 (count = 0), Skipped Segment at 35:5 (count = 0), RegionEntry diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html index 636341055dc08..cd23e4220cf17 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html @@ -188,32 +188,32 @@ ; }⦉@29@28,30⦊‸⦉@28,30 +47:5-50:6: @29[1]: _42 = const ()"> }⦉@29 - if if @31⦊!is_true⦉@31 @31⦊!is_true⦉@31 @32,34⦊{ - a = 2; - }⦉@32,34@33⦊‸⦉@33 +54:6-54:6: @34.Goto: goto -> bb35"> }⦉@32,34@33⦊‸⦉@33 - if @35⦊is_true⦉@35 if @35⦊is_true⦉@35 @36,38⦊{ - b = 30; - }⦉@36,38 else }⦉@36,38 else @37⦊{ - c = 400; - }⦉@37@36,38⦊‸⦉@36,38 + }⦉@37 }@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html index 1b9767506f26a..2164a565e22b7 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -89,6 +89,6 @@ }⦉@2@15⦊‸⦉@15 @21⦊Ok(())⦉@21 - }@16,18,19,20⦊‸⦉@16,18,19,20@22⦊‸⦉@22 + }@22⦊‸⦉@22 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html index 042845b70cc30..b30a5a9f81e1f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -117,9 +117,9 @@ 21:14-21:14: @29.Goto: goto -> bb30"> } }⦉@29@23⦊‸⦉@23 - }@6,8,9⦊‸⦉@6,8,9@30⦊‸⦉@30 - @32⦊countdown -= 1⦉@32; - }@0,1,2,3⦊‸⦉@0,1,2,3@7⦊‸⦉@7 + }@30⦊‸⦉@30 + @32⦊countdown -= 1⦉@32; + }@7⦊‸⦉@7 }@33⦊‸⦉@33 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html index a39772288a3e7..469a00f62060e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -60,11 +60,7 @@
@14⦊@11,12⦊@10⦊@13⦊Ord⦉@13⦉@10@11,12⦊@13⦊Ord⦉@13⦉@11,12⦉@14@15⦊‸⦉@15
diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html index 2c03e967eeb92..feae343bbbb8a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -61,11 +61,7 @@
@17⦊@14,15⦊@12⦊@16⦊PartialOrd⦉@16⦉@12@14,15⦊@16⦊PartialOrd⦉@16⦉@14,15⦉@17@18⦊‸⦉@18
diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html index db08315baa65e..cc5e54f87ce3a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -63,8 +63,8 @@ if @0⦊false⦉@0 { @4,5⦊loop {}⦉@4,5@1,3⦊‸⦉@1,3@4,5⦊‸⦉@4,5 +3:14-3:16: @5[0]: _3 = const ()">@4,5⦊loop {}⦉@4,5
@1,3⦊‸⦉@1,3 } -}@2⦊‸⦉@2 +}@2⦊‸⦉@2 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index 428c6fadc2741..c273c8c88e6f3 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -107,9 +107,9 @@ 31:42-31:43: @26[4]: _36 = _33 31:42-31:43: @26.Call: _35 = <() as From<()>>::from(move _36) -> [return: bb27, unwind: bb32]">@24,26,27,28⦊?⦉@24,26,27,28; }@15⦊‸⦉@15@23⦊‸⦉@23 - }@0,1⦊‸⦉@0,1@29⦊‸⦉@29 - }@29⦊‸⦉@29 + @5⦊Ok(())⦉@5 -}@30⦊‸⦉@30@31⦊‸⦉@31 +}@30⦊‸⦉@30@31⦊‸⦉@31 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html index 5c49ec1970756..49b8bb5520d86 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -65,7 +65,7 @@ while @1,2⦊num >= 10⦉@1,2 @3,5⦊{ - }⦉@3,5@3,5⦊‸⦉@3,5 + }⦉@3,5 }@4⦊‸⦉@4 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index be674dc7d38c7..3d75e61b80055 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -102,16 +102,16 @@ else { @10⦊Err(1)⦉@10 - }@9,11⦊‸⦉@9,11 + } ; } - @12⦊countdown - -= - 1⦉@12 + @12⦊countdown + -= + 1⦉@12 ; } - @4⦊Ok(())⦉@4 -}@13⦊‸⦉@13@14⦊‸⦉@14 +}@13⦊‸⦉@13@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html index 636341055dc08..cd23e4220cf17 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html @@ -188,32 +188,32 @@ ; }⦉@29@28,30⦊‸⦉@28,30 +47:5-50:6: @29[1]: _42 = const ()"> }⦉@29 - if if @31⦊!is_true⦉@31 @31⦊!is_true⦉@31 @32,34⦊{ - a = 2; - }⦉@32,34@33⦊‸⦉@33 +54:6-54:6: @34.Goto: goto -> bb35"> }⦉@32,34@33⦊‸⦉@33 - if @35⦊is_true⦉@35 if @35⦊is_true⦉@35 @36,38⦊{ - b = 30; - }⦉@36,38 else }⦉@36,38 else @37⦊{ - c = 400; - }⦉@37@36,38⦊‸⦉@36,38 + }⦉@37 }@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html index 1b9767506f26a..2164a565e22b7 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -89,6 +89,6 @@ }⦉@2@15⦊‸⦉@15 @21⦊Ok(())⦉@21 - }@16,18,19,20⦊‸⦉@16,18,19,20@22⦊‸⦉@22 + }@22⦊‸⦉@22 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html index 042845b70cc30..b30a5a9f81e1f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -117,9 +117,9 @@ 21:14-21:14: @29.Goto: goto -> bb30"> } }⦉@29@23⦊‸⦉@23 - }@6,8,9⦊‸⦉@6,8,9@30⦊‸⦉@30 - @32⦊countdown -= 1⦉@32; - }@0,1,2,3⦊‸⦉@0,1,2,3@7⦊‸⦉@7 + }@30⦊‸⦉@30 + @32⦊countdown -= 1⦉@32; + }@7⦊‸⦉@7 }@33⦊‸⦉@33 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html index a39772288a3e7..469a00f62060e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -60,11 +60,7 @@
@14⦊@11,12⦊@10⦊@13⦊Ord⦉@13⦉@10@11,12⦊@13⦊Ord⦉@13⦉@11,12⦉@14@15⦊‸⦉@15
diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html index 2c03e967eeb92..feae343bbbb8a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -61,11 +61,7 @@
@17⦊@14,15⦊@12⦊@16⦊PartialOrd⦉@16⦉@12@14,15⦊@16⦊PartialOrd⦉@16⦉@14,15⦉@17@18⦊‸⦉@18
diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html index db08315baa65e..cc5e54f87ce3a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -63,8 +63,8 @@ if @0⦊false⦉@0 { @4,5⦊loop {}⦉@4,5@1,3⦊‸⦉@1,3@4,5⦊‸⦉@4,5 +3:14-3:16: @5[0]: _3 = const ()">@4,5⦊loop {}⦉@4,5
@1,3⦊‸⦉@1,3 } -}@2⦊‸⦉@2 +}@2⦊‸⦉@2 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index 428c6fadc2741..c273c8c88e6f3 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -107,9 +107,9 @@ 31:42-31:43: @26[4]: _36 = _33 31:42-31:43: @26.Call: _35 = <() as From<()>>::from(move _36) -> [return: bb27, unwind: bb32]">@24,26,27,28⦊?⦉@24,26,27,28; }@15⦊‸⦉@15@23⦊‸⦉@23 - }@0,1⦊‸⦉@0,1@29⦊‸⦉@29 - }@29⦊‸⦉@29 + @5⦊Ok(())⦉@5 -}@30⦊‸⦉@30@31⦊‸⦉@31 +}@30⦊‸⦉@30@31⦊‸⦉@31 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html index 5c49ec1970756..49b8bb5520d86 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -65,7 +65,7 @@ while @1,2⦊num >= 10⦉@1,2 @3,5⦊{ - }⦉@3,5@3,5⦊‸⦉@3,5 + }⦉@3,5 }@4⦊‸⦉@4 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index be674dc7d38c7..3d75e61b80055 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -102,16 +102,16 @@ else { @10⦊Err(1)⦉@10 - }@9,11⦊‸⦉@9,11 + } ; } - @12⦊countdown - -= - 1⦉@12 + @12⦊countdown + -= + 1⦉@12 ; } - @4⦊Ok(())⦉@4 -}@13⦊‸⦉@13@14⦊‸⦉@14 +}@13⦊‸⦉@13@14⦊‸⦉@14 From af0c84c02223b81f6a000e6762abb7db4ba62612 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 22 Oct 2020 20:28:16 -0700 Subject: [PATCH 16/27] Adds coverage graphviz --- .../src/transform/coverage/counters.rs | 37 +- .../rustc_mir/src/transform/coverage/debug.rs | 365 +++++++++++++++++- .../rustc_mir/src/transform/coverage/mod.rs | 34 +- .../rustc_mir/src/transform/coverage/spans.rs | 8 + .../rustc_mir/src/util/generic_graphviz.rs | 185 +++++++++ compiler/rustc_mir/src/util/mod.rs | 1 + ...rage_graphviz.bar.InstrumentCoverage.0.dot | 6 + ...age_graphviz.main.InstrumentCoverage.0.dot | 11 + src/test/mir-opt/coverage_graphviz.rs | 20 + 9 files changed, 657 insertions(+), 10 deletions(-) create mode 100644 compiler/rustc_mir/src/util/generic_graphviz.rs create mode 100644 src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot create mode 100644 src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot create mode 100644 src/test/mir-opt/coverage_graphviz.rs diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs index 511ad937c248f..c31f401780e10 100644 --- a/compiler/rustc_mir/src/transform/coverage/counters.rs +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -1,3 +1,7 @@ +use super::debug; + +use debug::DebugCounters; + use rustc_middle::mir::coverage::*; /// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR @@ -6,6 +10,7 @@ pub(crate) struct CoverageCounters { function_source_hash: u64, next_counter_id: u32, num_expressions: u32, + pub debug_counters: DebugCounters, } impl CoverageCounters { @@ -14,24 +19,46 @@ impl CoverageCounters { function_source_hash, next_counter_id: CounterValueReference::START.as_u32(), num_expressions: 0, + debug_counters: DebugCounters::new(), } } - pub fn make_counter(&mut self) -> CoverageKind { - CoverageKind::Counter { + /// Activate the `DebugCounters` data structures, to provide additional debug formatting + /// features when formating `CoverageKind` (counter) values. + pub fn enable_debug(&mut self) { + self.debug_counters.enable(); + } + + pub fn make_counter(&mut self, debug_block_label_fn: F) -> CoverageKind + where + F: Fn() -> Option, + { + let counter = CoverageKind::Counter { function_source_hash: self.function_source_hash, id: self.next_counter(), + }; + if self.debug_counters.is_enabled() { + self.debug_counters.add_counter(&counter, (debug_block_label_fn)()); } + counter } - pub fn make_expression( + pub fn make_expression( &mut self, lhs: ExpressionOperandId, op: Op, rhs: ExpressionOperandId, - ) -> CoverageKind { + debug_block_label_fn: F, + ) -> CoverageKind + where + F: Fn() -> Option, + { let id = self.next_expression(); - CoverageKind::Expression { id, lhs, op, rhs } + let expression = CoverageKind::Expression { id, lhs, op, rhs }; + if self.debug_counters.is_enabled() { + self.debug_counters.add_counter(&expression, (debug_block_label_fn)()); + } + expression } /// Counter IDs start from one and go up. diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 7eb2d33453c3e..fbf2ad224a821 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -1,12 +1,294 @@ -use super::graph::CoverageGraph; +use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph}; use super::spans::CoverageSpan; +use crate::util::generic_graphviz::GraphvizWriter; use crate::util::pretty; use crate::util::spanview::{self, SpanViewable}; -use rustc_middle::mir::{self, TerminatorKind}; +use rustc_data_structures::fx::FxHashMap; +use rustc_index::vec::Idx; +use rustc_middle::mir::coverage::*; +use rustc_middle::mir::{self, BasicBlock, TerminatorKind}; use rustc_middle::ty::TyCtxt; +use std::lazy::SyncOnceCell; + +const RUSTC_COVERAGE_DEBUG_OPTIONS: &str = "RUSTC_COVERAGE_DEBUG_OPTIONS"; + +pub(crate) fn debug_options<'a>() -> &'a DebugOptions { + static DEBUG_OPTIONS: SyncOnceCell = SyncOnceCell::new(); + + &DEBUG_OPTIONS.get_or_init(|| DebugOptions::new()) +} + +/// Parses and maintains coverage-specific debug options captured from the environment variable +/// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set. Options can be set on the command line by, for example: +/// +/// $ RUSTC_COVERAGE_DEBUG_OPTIONS=counter-format=block cargo build +#[derive(Debug, Clone)] +pub(crate) struct DebugOptions { + counter_format: ExpressionFormat, +} + +impl DebugOptions { + fn new() -> Self { + let mut counter_format = ExpressionFormat::default(); + + if let Ok(env_debug_options) = std::env::var(RUSTC_COVERAGE_DEBUG_OPTIONS) { + for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(",") { + let mut setting = setting_str.splitn(2, "="); + match setting.next() { + Some(option) if option == "counter_format" => { + if let Some(strval) = setting.next() { + counter_format = counter_format_option_val(strval); + debug!( + "{} env option `counter_format` is set to {:?}", + RUSTC_COVERAGE_DEBUG_OPTIONS, counter_format + ); + } else { + bug!( + "`{}` option in environment variable {} requires one or more \ + plus-separated choices (a non-empty subset of \ + `id+block+operation`)", + option, + RUSTC_COVERAGE_DEBUG_OPTIONS + ); + } + } + Some("") => {} + Some(invalid) => bug!( + "Unsupported setting `{}` in environment variable {}", + invalid, + RUSTC_COVERAGE_DEBUG_OPTIONS + ), + None => {} + } + } + } + + Self { counter_format } + } +} + +fn counter_format_option_val(strval: &str) -> ExpressionFormat { + let mut counter_format = ExpressionFormat { id: false, block: false, operation: false }; + let components = strval.splitn(3, "+"); + for component in components { + match component { + "id" => counter_format.id = true, + "block" => counter_format.block = true, + "operation" => counter_format.operation = true, + _ => bug!( + "Unsupported counter_format choice `{}` in environment variable {}", + component, + RUSTC_COVERAGE_DEBUG_OPTIONS + ), + } + } + counter_format +} + +#[derive(Debug, Clone)] +struct ExpressionFormat { + id: bool, + block: bool, + operation: bool, +} + +impl Default for ExpressionFormat { + fn default() -> Self { + Self { id: false, block: true, operation: true } + } +} + +/// If enabled, this struct maintains a map from `CoverageKind` IDs (as `ExpressionOperandId`) to +/// the `CoverageKind` data and optional label (normally, the counter's associated +/// `BasicCoverageBlock` format string, if any). +/// +/// Use `format_counter` to convert one of these `CoverageKind` counters to a debug output string, +/// as directed by the `DebugOptions`. This allows the format of counter labels in logs and dump +/// files (including the `CoverageGraph` graphviz file) to be changed at runtime, via environment +/// variable. +/// +/// `DebugCounters` supports a recursive rendering of `Expression` counters, so they can be +/// presented as nested expressions such as `(bcb3 - (bcb0 + bcb1))`. +pub(crate) struct DebugCounters { + some_counters: Option>, +} + +impl DebugCounters { + pub fn new() -> Self { + Self { some_counters: None } + } + + pub fn enable(&mut self) { + self.some_counters.replace(FxHashMap::default()); + } + + pub fn is_enabled(&mut self) -> bool { + self.some_counters.is_some() + } + + pub fn add_counter(&mut self, counter_kind: &CoverageKind, some_block_label: Option) { + if let Some(counters) = &mut self.some_counters { + let id: ExpressionOperandId = match *counter_kind { + CoverageKind::Counter { id, .. } => id.into(), + CoverageKind::Expression { id, .. } => id.into(), + _ => bug!( + "the given `CoverageKind` is not an counter or expression: {:?}", + counter_kind + ), + }; + counters + .insert(id.into(), DebugCounter::new(counter_kind.clone(), some_block_label)) + .expect_none( + "attempt to add the same counter_kind to DebugCounters more than once", + ); + } + } + + pub fn format_counter(&self, counter_kind: &CoverageKind) -> String { + match *counter_kind { + CoverageKind::Counter { .. } => { + format!("Counter({})", self.format_counter_kind(counter_kind)) + } + CoverageKind::Expression { .. } => { + format!("Expression({})", self.format_counter_kind(counter_kind)) + } + CoverageKind::Unreachable { .. } => "Unreachable".to_owned(), + } + } + + fn format_counter_kind(&self, counter_kind: &CoverageKind) -> String { + let counter_format = &debug_options().counter_format; + if let CoverageKind::Expression { id, lhs, op, rhs } = *counter_kind { + if counter_format.operation { + return format!( + "{}{} {} {}", + if counter_format.id || self.some_counters.is_none() { + format!("#{} = ", id.index()) + } else { + String::new() + }, + self.format_operand(lhs), + if op == Op::Add { "+" } else { "-" }, + self.format_operand(rhs), + ); + } + } + + let id: ExpressionOperandId = match *counter_kind { + CoverageKind::Counter { id, .. } => id.into(), + CoverageKind::Expression { id, .. } => id.into(), + _ => { + bug!("the given `CoverageKind` is not an counter or expression: {:?}", counter_kind) + } + }; + if self.some_counters.is_some() && (counter_format.block || !counter_format.id) { + let counters = self.some_counters.as_ref().unwrap(); + if let Some(DebugCounter { some_block_label: Some(block_label), .. }) = + counters.get(&id.into()) + { + return if counter_format.id { + format!("{}#{}", block_label, id.index()) + } else { + format!("{}", block_label) + }; + } + } + format!("#{}", id.index()) + } + + fn format_operand(&self, operand: ExpressionOperandId) -> String { + if operand.index() == 0 { + return String::from("0"); + } + if let Some(counters) = &self.some_counters { + if let Some(DebugCounter { counter_kind, some_block_label }) = counters.get(&operand) { + if let CoverageKind::Expression { .. } = counter_kind { + if let Some(block_label) = some_block_label { + if debug_options().counter_format.block { + return format!( + "{}:({})", + block_label, + self.format_counter_kind(counter_kind) + ); + } + } + return format!("({})", self.format_counter_kind(counter_kind)); + } + return format!("{}", self.format_counter_kind(counter_kind)); + } + } + format!("#{}", operand.index().to_string()) + } +} + +/// A non-public support class to `DebugCounters`. +#[derive(Debug)] +struct DebugCounter { + counter_kind: CoverageKind, + some_block_label: Option, +} + +impl DebugCounter { + fn new(counter_kind: CoverageKind, some_block_label: Option) -> Self { + Self { counter_kind, some_block_label } + } +} + +/// If enabled, this data structure captures additional debugging information used when generating +/// a Graphviz (.dot file) representation of the `CoverageGraph`, for debugging purposes. +pub(crate) struct GraphvizData { + some_bcb_to_coverage_spans_with_counters: + Option>>, + some_edge_to_counter: Option>, +} + +impl GraphvizData { + pub fn new() -> Self { + Self { some_bcb_to_coverage_spans_with_counters: None, some_edge_to_counter: None } + } + + pub fn enable(&mut self) { + self.some_bcb_to_coverage_spans_with_counters = Some(FxHashMap::default()); + self.some_edge_to_counter = Some(FxHashMap::default()); + } + + pub fn is_enabled(&mut self) -> bool { + self.some_bcb_to_coverage_spans_with_counters.is_some() + } + + pub fn add_bcb_coverage_span_with_counter( + &mut self, + bcb: BasicCoverageBlock, + coverage_span: &CoverageSpan, + counter_kind: &CoverageKind, + ) { + if let Some(bcb_to_coverage_spans_with_counters) = + self.some_bcb_to_coverage_spans_with_counters.as_mut() + { + bcb_to_coverage_spans_with_counters + .entry(bcb) + .or_insert_with(|| Vec::new()) + .push((coverage_span.clone(), counter_kind.clone())); + } + } + + pub fn get_bcb_coverage_spans_with_counters( + &self, + bcb: BasicCoverageBlock, + ) -> Option<&Vec<(CoverageSpan, CoverageKind)>> { + if let Some(bcb_to_coverage_spans_with_counters) = + self.some_bcb_to_coverage_spans_with_counters.as_ref() + { + bcb_to_coverage_spans_with_counters.get(&bcb) + } else { + None + } + } +} + /// Generates the MIR pass `CoverageSpan`-specific spanview dump file. pub(crate) fn dump_coverage_spanview( tcx: TyCtxt<'tcx>, @@ -47,6 +329,85 @@ fn span_viewables( span_viewables } +/// Generates the MIR pass coverage-specific graphviz dump file. +pub(crate) fn dump_coverage_graphviz( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + pass_name: &str, + basic_coverage_blocks: &CoverageGraph, + debug_counters: &DebugCounters, + graphviz_data: &GraphvizData, +) { + let mir_source = mir_body.source; + let def_id = mir_source.def_id(); + let node_content = |bcb| { + bcb_to_string_sections( + tcx, + mir_body, + debug_counters, + &basic_coverage_blocks[bcb], + graphviz_data.get_bcb_coverage_spans_with_counters(bcb), + ) + }; + let edge_labels = |from_bcb| { + let from_bcb_data = &basic_coverage_blocks[from_bcb]; + let from_terminator = from_bcb_data.terminator(mir_body); + from_terminator + .kind + .fmt_successor_labels() + .iter() + .map(|label| label.to_string()) + .collect::>() + }; + let graphviz_name = format!("Cov_{}_{}", def_id.krate.index(), def_id.index.index()); + let graphviz_writer = + GraphvizWriter::new(basic_coverage_blocks, &graphviz_name, node_content, edge_labels); + let mut file = pretty::create_dump_file(tcx, "dot", None, pass_name, &0, mir_source) + .expect("Unexpected error creating BasicCoverageBlock graphviz DOT file"); + graphviz_writer + .write_graphviz(tcx, &mut file) + .expect("Unexpected error writing BasicCoverageBlock graphviz DOT file"); +} + +fn bcb_to_string_sections( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, + debug_counters: &DebugCounters, + bcb_data: &BasicCoverageBlockData, + some_coverage_spans_with_counters: Option<&Vec<(CoverageSpan, CoverageKind)>>, +) -> Vec { + let len = bcb_data.basic_blocks.len(); + let mut sections = Vec::new(); + if let Some(coverage_spans_with_counters) = some_coverage_spans_with_counters { + sections.push( + coverage_spans_with_counters + .iter() + .map(|(covspan, counter)| { + format!( + "{} at {}", + debug_counters.format_counter(counter), + covspan.format(tcx, mir_body) + ) + }) + .collect::>() + .join("\n"), + ); + } + let non_term_blocks = bcb_data.basic_blocks[0..len - 1] + .iter() + .map(|&bb| format!("{:?}: {}", bb, term_type(&mir_body[bb].terminator().kind))) + .collect::>(); + if non_term_blocks.len() > 0 { + sections.push(non_term_blocks.join("\n")); + } + sections.push(format!( + "{:?}: {}", + bcb_data.basic_blocks.last().unwrap(), + term_type(&bcb_data.terminator(mir_body).kind) + )); + sections +} + /// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any /// values it might hold. pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str { diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index aa5771cfad4e2..d1d94092c9def 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -103,6 +103,14 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); + let mut graphviz_data = debug::GraphvizData::new(); + + let dump_graphviz = tcx.sess.opts.debugging_opts.dump_mir_graphviz; + if dump_graphviz { + graphviz_data.enable(); + self.coverage_counters.enable_debug(); + } + //////////////////////////////////////////////////// // Compute `CoverageSpan`s from the `CoverageGraph`. let coverage_spans = CoverageSpans::generate_coverage_spans( @@ -121,7 +129,20 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { ); } - self.inject_coverage_span_counters(coverage_spans); + self.inject_coverage_span_counters(coverage_spans, &mut graphviz_data); + + if graphviz_data.is_enabled() { + // Even if there was an error, a partial CoverageGraph can still generate a useful + // graphviz output. + debug::dump_coverage_graphviz( + tcx, + self.mir_body, + self.pass_name, + &self.basic_coverage_blocks, + &self.coverage_counters.debug_counters, + &graphviz_data, + ); + } } /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given @@ -129,7 +150,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to /// the BCB `Counter` value. - fn inject_coverage_span_counters(&mut self, coverage_spans: Vec) { + fn inject_coverage_span_counters( + &mut self, + coverage_spans: Vec, + graphviz_data: &mut debug::GraphvizData, + ) { let tcx = self.tcx; let source_map = tcx.sess.source_map(); let body_span = self.body_span; @@ -145,6 +170,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { counter_operand, Op::Add, ExpressionOperandId::ZERO, + || Some(format!("{:?}", bcb)), ); debug!( "Injecting counter expression {:?} at: {:?}:\n{}\n==========", @@ -152,11 +178,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { span, source_map.span_to_snippet(span).expect("Error getting source for span"), ); + graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &expression); let bb = self.basic_coverage_blocks[bcb].leader_bb(); let code_region = make_code_region(file_name, &source_file, span, body_span); inject_statement(self.mir_body, expression, bb, Some(code_region)); } else { - let counter = self.coverage_counters.make_counter(); + let counter = self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb))); debug!( "Injecting counter {:?} at: {:?}:\n{}\n==========", counter, @@ -165,6 +192,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { ); let counter_operand = counter.as_operand_id(); bcb_counters[bcb] = Some(counter_operand); + graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &counter); let bb = self.basic_coverage_blocks[bcb].leader_bb(); let code_region = make_code_region(file_name, &source_file, span, body_span); inject_statement(self.mir_body, counter, bb, Some(code_region)); diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index 23531ecf22931..61b5b1480532a 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -134,6 +134,14 @@ impl CoverageSpan { self.bcb == other.bcb } + pub fn format(&self, tcx: TyCtxt<'tcx>, mir_body: &'a mir::Body<'tcx>) -> String { + format!( + "{}\n {}", + source_range_no_file(tcx, &self.span), + self.format_coverage_statements(tcx, mir_body).replace("\n", "\n "), + ) + } + pub fn format_coverage_statements( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir/src/util/generic_graphviz.rs b/compiler/rustc_mir/src/util/generic_graphviz.rs new file mode 100644 index 0000000000000..91499bb61c287 --- /dev/null +++ b/compiler/rustc_mir/src/util/generic_graphviz.rs @@ -0,0 +1,185 @@ +use rustc_data_structures::graph::{self, iterate}; +use rustc_graphviz as dot; +use rustc_middle::ty::TyCtxt; +use std::io::{self, Write}; + +pub struct GraphvizWriter< + 'a, + G: graph::DirectedGraph + graph::WithSuccessors + graph::WithStartNode + graph::WithNumNodes, + NodeContentFn: Fn(::Node) -> Vec, + EdgeLabelsFn: Fn(::Node) -> Vec, +> { + graph: &'a G, + is_subgraph: bool, + graphviz_name: String, + graph_label: Option, + node_content_fn: NodeContentFn, + edge_labels_fn: EdgeLabelsFn, +} + +impl< + 'a, + G: graph::DirectedGraph + graph::WithSuccessors + graph::WithStartNode + graph::WithNumNodes, + NodeContentFn: Fn(::Node) -> Vec, + EdgeLabelsFn: Fn(::Node) -> Vec, +> GraphvizWriter<'a, G, NodeContentFn, EdgeLabelsFn> +{ + pub fn new( + graph: &'a G, + graphviz_name: &str, + node_content_fn: NodeContentFn, + edge_labels_fn: EdgeLabelsFn, + ) -> Self { + Self { + graph, + is_subgraph: false, + graphviz_name: graphviz_name.to_owned(), + graph_label: None, + node_content_fn, + edge_labels_fn, + } + } + + pub fn new_subgraph( + graph: &'a G, + graphviz_name: &str, + node_content_fn: NodeContentFn, + edge_labels_fn: EdgeLabelsFn, + ) -> Self { + Self { + graph, + is_subgraph: true, + graphviz_name: graphviz_name.to_owned(), + graph_label: None, + node_content_fn, + edge_labels_fn, + } + } + + pub fn set_graph_label(&mut self, graph_label: &str) { + self.graph_label = Some(graph_label.to_owned()); + } + + /// Write a graphviz DOT of the graph + pub fn write_graphviz<'tcx, W>(&self, tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> + where + W: Write, + { + let kind = if self.is_subgraph { "subgraph" } else { "digraph" }; + let cluster = if self.is_subgraph { "cluster_" } else { "" }; // Print border around graph + // FIXME(richkadel): If/when migrating the MIR graphviz to this generic implementation, + // prepend "Mir_" to the graphviz_safe_def_name(def_id) + writeln!(w, "{} {}{} {{", kind, cluster, self.graphviz_name)?; + + // Global graph properties + let font = format!(r#"fontname="{}""#, tcx.sess.opts.debugging_opts.graphviz_font); + let mut graph_attrs = vec![&font[..]]; + let mut content_attrs = vec![&font[..]]; + + let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode; + if dark_mode { + graph_attrs.push(r#"bgcolor="black""#); + graph_attrs.push(r#"fontcolor="white""#); + content_attrs.push(r#"color="white""#); + content_attrs.push(r#"fontcolor="white""#); + } + + writeln!(w, r#" graph [{}];"#, graph_attrs.join(" "))?; + let content_attrs_str = content_attrs.join(" "); + writeln!(w, r#" node [{}];"#, content_attrs_str)?; + writeln!(w, r#" edge [{}];"#, content_attrs_str)?; + + // Graph label + if let Some(graph_label) = &self.graph_label { + self.write_graph_label(graph_label, w)?; + } + + // Nodes + for node in iterate::post_order_from(self.graph, self.graph.start_node()) { + self.write_node(node, dark_mode, w)?; + } + + // Edges + for source in iterate::post_order_from(self.graph, self.graph.start_node()) { + self.write_edges(source, w)?; + } + writeln!(w, "}}") + } + + /// Write a graphviz DOT node for the given node. + pub fn write_node(&self, node: G::Node, dark_mode: bool, w: &mut W) -> io::Result<()> + where + W: Write, + { + // Start a new node with the label to follow, in one of DOT's pseudo-HTML tables. + write!(w, r#" {} [shape="none", label=<"#, self.node(node))?; + + write!(w, r#""#)?; + + // FIXME(richkadel): Need generic way to know if node header should have a different color + // let (blk, bgcolor) = if data.is_cleanup { + // (format!("{:?} (cleanup)", node), "lightblue") + // } else { + // let color = if dark_mode { "dimgray" } else { "gray" }; + // (format!("{:?}", node), color) + // }; + let color = if dark_mode { "dimgray" } else { "gray" }; + let (blk, bgcolor) = (format!("{:?}", node), color); + write!( + w, + r#""#, + attrs = r#"align="center""#, + colspan = 1, + blk = blk, + bgcolor = bgcolor + )?; + + for section in (self.node_content_fn)(node) { + write!( + w, + r#""#, + dot::escape_html(§ion).replace("\n", "
") + )?; + } + + // Close the table + write!(w, "
{blk}
{}
")?; + + // Close the node label and the node itself. + writeln!(w, ">];") + } + + /// Write graphviz DOT edges with labels between the given node and all of its successors. + fn write_edges(&self, source: G::Node, w: &mut W) -> io::Result<()> + where + W: Write, + { + let edge_labels = (self.edge_labels_fn)(source); + for (index, target) in self.graph.successors(source).enumerate() { + let src = self.node(source); + let trg = self.node(target); + let escaped_edge_label = if let Some(edge_label) = edge_labels.get(index) { + dot::escape_html(edge_label).replace("\n", r#"
"#) + } else { + "".to_owned() + }; + writeln!(w, r#" {} -> {} [label=<{}>];"#, src, trg, escaped_edge_label)?; + } + Ok(()) + } + + /// Write the graphviz DOT label for the overall graph. This is essentially a block of text that + /// will appear below the graph. + fn write_graph_label(&self, label: &str, w: &mut W) -> io::Result<()> + where + W: Write, + { + let lines = label.split("\n").map(|s| dot::escape_html(s)).collect::>(); + let escaped_label = lines.join(r#"
"#); + writeln!(w, r#" label=<

{}



>;"#, escaped_label) + } + + fn node(&self, node: G::Node) -> String { + format!("{:?}__{}", node, self.graphviz_name) + } +} diff --git a/compiler/rustc_mir/src/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs index 7da2f4ffe0889..aaee0bc526db5 100644 --- a/compiler/rustc_mir/src/util/mod.rs +++ b/compiler/rustc_mir/src/util/mod.rs @@ -7,6 +7,7 @@ pub mod storage; mod alignment; pub mod collect_writes; mod find_self_call; +pub(crate) mod generic_graphviz; mod graphviz; pub(crate) mod pretty; pub(crate) mod spanview; diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot new file mode 100644 index 0000000000000..df9f7aa627b26 --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot @@ -0,0 +1,6 @@ +digraph Cov_0_4 { + graph [fontname="Courier, monospace"]; + node [fontname="Courier, monospace"]; + edge [fontname="Courier, monospace"]; + bcb0__Cov_0_4 [shape="none", label=<
bcb0
Counter(bcb0) at 19:5-20:2
19:5-19:9: @0[0]: _0 = const true
20:2-20:2: @0.Return: return
bb0: Return
>]; +} diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot new file mode 100644 index 0000000000000..051ef498fb7fe --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot @@ -0,0 +1,11 @@ +digraph Cov_0_3 { + graph [fontname="Courier, monospace"]; + node [fontname="Courier, monospace"]; + edge [fontname="Courier, monospace"]; + bcb2__Cov_0_3 [shape="none", label=<
bcb2
Counter(bcb2) at 14:6-14:6
14:6-14:6: @4.Goto: goto -> bb0
bb4: Goto
>]; + bcb1__Cov_0_3 [shape="none", label=<
bcb1
Counter(bcb1) at 12:13-12:18
12:13-12:18: @5[0]: _0 = const ()
Expression(bcb1 + 0) at 15:2-15:2
15:2-15:2: @5.Return: return
bb3: FalseEdge
bb5: Return
>]; + bcb0__Cov_0_3 [shape="none", label=<
bcb0
Counter(bcb0) at 11:12-11:17
11:12-11:17: @1.Call: _2 = bar() -> [return: bb2, unwind: bb6]
11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)
bb0: FalseUnwind
bb1: Call
bb2: SwitchInt
>]; + bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>]; + bcb0__Cov_0_3 -> bcb2__Cov_0_3 [label=]; + bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=]; +} diff --git a/src/test/mir-opt/coverage_graphviz.rs b/src/test/mir-opt/coverage_graphviz.rs new file mode 100644 index 0000000000000..b3c90c528377d --- /dev/null +++ b/src/test/mir-opt/coverage_graphviz.rs @@ -0,0 +1,20 @@ +// Test that `-Z instrument-coverage` with `-Z dump-mir-graphviz` generates a graphviz (.dot file) +// rendering of the `BasicCoverageBlock` coverage control flow graph, with counters and +// expressions. + +// needs-profiler-support +// compile-flags: -Z instrument-coverage -Z dump-mir-graphviz +// EMIT_MIR coverage_graphviz.main.InstrumentCoverage.0.dot +// EMIT_MIR coverage_graphviz.bar.InstrumentCoverage.0.dot +fn main() { + loop { + if bar() { + break; + } + } +} + +#[inline(never)] +fn bar() -> bool { + true +} From 868de57c22bb7dbbe2e8fe6d9ea35ddc50a0425b Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 22 Oct 2020 14:30:03 -0700 Subject: [PATCH 17/27] Injecting expressions in place of counters where helpful Implementing the Graph traits for the BasicCoverageBlock graph. optimized replacement of counters with expressions plus new BCB graphviz * Avoid adding coverage to unreachable blocks. * Special case for Goto at the end of the body. Make it non-reportable. Improved debugging and formatting options (from env) Don't automatically add counters to BCBs without CoverageSpans. They may still get counters but only if there are dependencies from other BCBs that have spans, I think. Make CodeRegions optional for Counters too. It is possible to inject counters (`llvm.instrprof.increment` intrinsic calls without corresponding code regions in the coverage map. An expression can still uses these counter values. Refactored instrument_coverage.rs -> instrument_coverage/mod.rs, and then broke up the mod into multiple files. Compiling with coverage, with the expression optimization, works on the json5format crate and its dependencies. Refactored debug features from mod.rs to debug.rs --- .../src/coverageinfo/mod.rs | 19 +- .../rustc_codegen_ssa/src/mir/coverageinfo.rs | 4 +- .../src/traits/coverageinfo.rs | 10 +- .../src/transform/coverage/counters.rs | 524 +++++++++++++++++- .../rustc_mir/src/transform/coverage/debug.rs | 310 ++++++++++- .../rustc_mir/src/transform/coverage/graph.rs | 321 ++++++++++- .../rustc_mir/src/transform/coverage/mod.rs | 323 +++++++++-- ...rage_graphviz.bar.InstrumentCoverage.0.dot | 2 +- ...age_graphviz.main.InstrumentCoverage.0.dot | 4 +- ...ment_coverage.main.InstrumentCoverage.diff | 8 +- .../expected_export_coverage.drop_trait.json | 8 +- .../expected_export_coverage.generics.json | 8 +- .../expected_export_coverage.if_else.json | 24 +- ...cted_export_coverage.try_error_result.json | 12 +- ...ed_export_coverage.various_conditions.json | 12 +- ...ed_export_coverage.while_early_return.json | 12 +- .../expected_show_coverage.drop_trait.txt | 2 +- .../expected_show_coverage.generics.txt | 2 +- .../expected_show_coverage.if_else.txt | 4 +- ...xpected_show_coverage.try_error_result.txt | 2 +- ...ected_show_coverage.various_conditions.txt | 2 +- ...ected_show_coverage.while_early_return.txt | 2 +- ...xpected_show_coverage_counters.closure.txt | 16 +- ...cted_show_coverage_counters.drop_trait.txt | 2 +- ...pected_show_coverage_counters.generics.txt | 2 +- .../expected_show_coverage_counters.if.txt | 4 +- ...xpected_show_coverage_counters.if_else.txt | 10 +- ...ted_show_coverage_counters.inner_items.txt | 10 +- ...ed_show_coverage_counters.lazy_boolean.txt | 68 +-- ...w_coverage_counters.loops_and_branches.txt | 12 +- ...ed_show_coverage_counters.nested_loops.txt | 34 +- ...ted_show_coverage_counters.simple_loop.txt | 12 +- ...ed_show_coverage_counters.simple_match.txt | 24 +- ..._coverage_counters.tight_infinite_loop.txt | 2 +- ...how_coverage_counters.try_error_result.txt | 33 +- ...w_coverage_counters.various_conditions.txt | 137 +++-- .../expected_show_coverage_counters.while.txt | 6 +- ...w_coverage_counters.while_early_return.txt | 21 +- .../expected_export_coverage.drop_trait.json | 8 +- .../expected_export_coverage.generics.json | 8 +- .../expected_export_coverage.if_else.json | 24 +- ...cted_export_coverage.try_error_result.json | 12 +- ...ed_export_coverage.various_conditions.json | 12 +- ...ed_export_coverage.while_early_return.json | 12 +- .../expected_show_coverage.drop_trait.txt | 2 +- .../expected_show_coverage.generics.txt | 2 +- .../expected_show_coverage.if_else.txt | 4 +- ...xpected_show_coverage.try_error_result.txt | 2 +- ...ected_show_coverage.various_conditions.txt | 2 +- ...ected_show_coverage.while_early_return.txt | 2 +- ...xpected_show_coverage_counters.closure.txt | 16 +- ...cted_show_coverage_counters.drop_trait.txt | 2 +- ...pected_show_coverage_counters.generics.txt | 2 +- .../expected_show_coverage_counters.if.txt | 4 +- ...xpected_show_coverage_counters.if_else.txt | 10 +- ...ted_show_coverage_counters.inner_items.txt | 10 +- ...ed_show_coverage_counters.lazy_boolean.txt | 68 +-- ...w_coverage_counters.loops_and_branches.txt | 12 +- ...ed_show_coverage_counters.nested_loops.txt | 34 +- ...ters.partial_eq_counter_without_region.txt | 20 +- ...ted_show_coverage_counters.simple_loop.txt | 12 +- ...ed_show_coverage_counters.simple_match.txt | 24 +- ..._coverage_counters.tight_infinite_loop.txt | 2 +- ...how_coverage_counters.try_error_result.txt | 33 +- ...w_coverage_counters.various_conditions.txt | 137 +++-- .../expected_show_coverage_counters.while.txt | 6 +- ...w_coverage_counters.while_early_return.txt | 21 +- ...ait.main.-------.InstrumentCoverage.0.html | 2 +- ...ics.main.-------.InstrumentCoverage.0.html | 2 +- ...lse.main.-------.InstrumentCoverage.0.html | 30 +- ...ult.call.-------.InstrumentCoverage.0.html | 4 +- ...ait.main.-------.InstrumentCoverage.0.html | 2 +- ...ics.main.-------.InstrumentCoverage.0.html | 2 +- ...lse.main.-------.InstrumentCoverage.0.html | 30 +- ...ult.call.-------.InstrumentCoverage.0.html | 4 +- 75 files changed, 1984 insertions(+), 603 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index c4b4032fd478c..75e8abaf2a9e9 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -58,7 +58,11 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar(llfn, mangled_fn_name.as_ptr()) } } - fn set_function_source_hash(&mut self, instance: Instance<'tcx>, function_source_hash: u64) -> bool { + fn set_function_source_hash( + &mut self, + instance: Instance<'tcx>, + function_source_hash: u64, + ) -> bool { if let Some(coverage_context) = self.coverage_context() { debug!( "ensuring function source hash is set for instance={:?}; function_source_hash={}", @@ -69,6 +73,7 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .set_function_source_hash(function_source_hash); + true } else { false } @@ -92,6 +97,7 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_counter(function_source_hash, id, region); + true } else { false } @@ -105,8 +111,8 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { op: Op, rhs: ExpressionOperandId, region: Option, - ) { - if let Some(coverage_context) = self.coverage_context() -> bool { + ) -> bool { + if let Some(coverage_context) = self.coverage_context() { debug!( "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; \ region: {:?}", @@ -117,6 +123,7 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_counter_expression(id, lhs, op, rhs, region); + true } else { false } @@ -124,12 +131,16 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool { if let Some(coverage_context) = self.coverage_context() { - debug!("adding unreachable code to coverage_map: instance={:?}, at {:?}", instance, region,); + debug!( + "adding unreachable code to coverage_map: instance={:?}, at {:?}", + instance, region, + ); let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); coverage_map .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) .add_unreachable_region(region); + true } else { false } diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index e52f952e93278..339e0d95fdffc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -24,10 +24,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_name = bx.create_pgo_func_name_var(self.instance); let hash = bx.const_u64(function_source_hash); let num_counters = bx.const_u32(coverageinfo.num_counters); - let id = bx.const_u32(u32::from(id)); + let index = bx.const_u32(u32::from(id)); debug!( "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})", - fn_name, hash, num_counters, id, + fn_name, hash, num_counters, index, ); bx.instrprof_increment(fn_name, hash, num_counters, index); } diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index 5aa0950b399e3..7da38880d603c 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -11,7 +11,11 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { /// Returns true if the function source hash was added to the coverage map; false if /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). - fn set_function_source_hash(&mut self, instance: Instance<'tcx>, function_source_hash: u64) -> bool; + fn set_function_source_hash( + &mut self, + instance: Instance<'tcx>, + function_source_hash: u64, + ) -> bool; /// Returns true if the counter was added to the coverage map; false if `-Z instrument-coverage` /// is not enabled (a coverage map is not being generated). @@ -19,7 +23,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { &mut self, instance: Instance<'tcx>, function_source_hash: u64, - id: CounterValueReference, + index: CounterValueReference, region: CodeRegion, ) -> bool; @@ -33,7 +37,7 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { op: Op, rhs: ExpressionOperandId, region: Option, - ); + ) -> bool; /// Returns true if the region was added to the coverage map; false if `-Z instrument-coverage` /// is not enabled (a coverage map is not being generated). diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs index c31f401780e10..a3ae302152486 100644 --- a/compiler/rustc_mir/src/transform/coverage/counters.rs +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -1,7 +1,15 @@ +use super::Error; + use super::debug; +use super::graph; +use super::spans; -use debug::DebugCounters; +use debug::{DebugCounters, NESTED_INDENT}; +use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops}; +use spans::CoverageSpan; +use rustc_data_structures::graph::WithNumNodes; +use rustc_index::bit_set::BitSet; use rustc_middle::mir::coverage::*; /// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR @@ -29,7 +37,19 @@ impl CoverageCounters { self.debug_counters.enable(); } - pub fn make_counter(&mut self, debug_block_label_fn: F) -> CoverageKind + /// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlocks` directly or + /// indirectly associated with `CoverageSpans`, and returns additional `Expression`s + /// representing intermediate values. + pub fn make_bcb_counters( + &mut self, + basic_coverage_blocks: &mut CoverageGraph, + coverage_spans: &Vec, + ) -> Result, Error> { + let mut bcb_counters = BcbCounters::new(self, basic_coverage_blocks); + bcb_counters.make_bcb_counters(coverage_spans) + } + + fn make_counter(&mut self, debug_block_label_fn: F) -> CoverageKind where F: Fn() -> Option, { @@ -43,7 +63,7 @@ impl CoverageCounters { counter } - pub fn make_expression( + fn make_expression( &mut self, lhs: ExpressionOperandId, op: Op, @@ -61,6 +81,17 @@ impl CoverageCounters { expression } + pub fn make_identity_counter(&mut self, counter_operand: ExpressionOperandId) -> CoverageKind { + let some_debug_block_label = if self.debug_counters.is_enabled() { + self.debug_counters.some_block_label(counter_operand).cloned() + } else { + None + }; + self.make_expression(counter_operand, Op::Add, ExpressionOperandId::ZERO, || { + some_debug_block_label.clone() + }) + } + /// Counter IDs start from one and go up. fn next_counter(&mut self) -> CounterValueReference { assert!(self.next_counter_id < u32::MAX - self.num_expressions); @@ -79,3 +110,490 @@ impl CoverageCounters { InjectedExpressionId::from(next) } } + +/// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be +/// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable expression +/// (adding or subtracting two other counters or expressions) can compute the same result as an +/// embedded counter, an `Expression` should be used. +struct BcbCounters<'a> { + coverage_counters: &'a mut CoverageCounters, + basic_coverage_blocks: &'a mut CoverageGraph, +} + +impl<'a> BcbCounters<'a> { + fn new( + coverage_counters: &'a mut CoverageCounters, + basic_coverage_blocks: &'a mut CoverageGraph, + ) -> Self { + Self { coverage_counters, basic_coverage_blocks } + } + + /// If two `CoverageGraph` branch from another `BasicCoverageBlock`, one of the branches + /// can be counted by `Expression` by subtracting the other branch from the branching + /// block. Otherwise, the `BasicCoverageBlock` executed the least should have the `Counter`. + /// One way to predict which branch executes the least is by considering loops. A loop is exited + /// at a branch, so the branch that jumps to a `BasicCoverageBlock` outside the loop is almost + /// always executed less than the branch that does not exit the loop. + /// + /// Returns any non-code-span expressions created to represent intermediate values (such as to + /// add two counters so the result can be subtracted from another counter), or an Error with + /// message for subsequent debugging. + fn make_bcb_counters( + &mut self, + coverage_spans: &Vec, + ) -> Result, Error> { + debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock"); + let num_bcbs = self.basic_coverage_blocks.num_nodes(); + let mut collect_intermediate_expressions = Vec::with_capacity(num_bcbs); + + let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs); + for covspan in coverage_spans { + bcbs_with_coverage.insert(covspan.bcb); + } + + // FIXME(richkadel): Add more comments to explain the logic here and in the rest of this + // function, and refactor this function to break it up into smaller functions that are + // easier to understand. + + let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks); + while let Some(bcb) = traversal.next(self.basic_coverage_blocks) { + if bcbs_with_coverage.contains(bcb) { + debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb); + let branching_counter_operand = + self.get_or_make_counter_operand(bcb, &mut collect_intermediate_expressions)?; + + if self.bcb_needs_branch_counters(bcb) { + self.make_branch_counters( + &mut traversal, + bcb, + branching_counter_operand, + &mut collect_intermediate_expressions, + )?; + } + } else { + debug!( + "{:?} does not have any `CoverageSpan`s. A counter will only be added if \ + and when a covered BCB has an expression dependency.", + bcb, + ); + } + } + + if traversal.is_complete() { + Ok(collect_intermediate_expressions) + } else { + Error::from_string(format!( + "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: {:?}", + traversal.unvisited(), + )) + } + } + + fn make_branch_counters( + &mut self, + traversal: &mut TraverseCoverageGraphWithLoops, + branching_bcb: BasicCoverageBlock, + branching_counter_operand: ExpressionOperandId, + collect_intermediate_expressions: &mut Vec, + ) -> Result<(), Error> { + let branches = self.bcb_branches(branching_bcb); + debug!( + "{:?} has some branch(es) without counters:\n {}", + branching_bcb, + branches + .iter() + .map(|branch| { + format!("{:?}: {:?}", branch, branch.counter(&self.basic_coverage_blocks)) + }) + .collect::>() + .join("\n "), + ); + + let expression_branch = self.choose_preferred_expression_branch(traversal, &branches); + // Assign a Counter or Expression to each branch, plus additional + // `Expression`s, as needed, to sum up intermediate results. + let mut some_sumup_counter_operand = None; + for branch in branches { + if branch != expression_branch { + let branch_counter_operand = if branch.is_only_path_to_target() { + debug!( + " {:?} has only one incoming edge (from {:?}), so adding a \ + counter", + branch, branching_bcb + ); + self.get_or_make_counter_operand( + branch.target_bcb, + collect_intermediate_expressions, + )? + } else { + debug!(" {:?} has multiple incoming edges, so adding an edge counter", branch); + self.get_or_make_edge_counter_operand( + branching_bcb, + branch.target_bcb, + collect_intermediate_expressions, + )? + }; + if let Some(sumup_counter_operand) = + some_sumup_counter_operand.replace(branch_counter_operand) + { + let intermediate_expression = self.coverage_counters.make_expression( + branch_counter_operand, + Op::Add, + sumup_counter_operand, + || None, + ); + debug!( + " [new intermediate expression: {}]", + self.format_counter(&intermediate_expression) + ); + let intermediate_expression_operand = intermediate_expression.as_operand_id(); + collect_intermediate_expressions.push(intermediate_expression); + some_sumup_counter_operand.replace(intermediate_expression_operand); + } + } + } + let sumup_counter_operand = + some_sumup_counter_operand.expect("sumup_counter_operand should have a value"); + debug!( + "Making an expression for the selected expression_branch: {:?} \ + (expression_branch predecessors: {:?})", + expression_branch, + self.bcb_predecessors(expression_branch.target_bcb), + ); + let expression = self.coverage_counters.make_expression( + branching_counter_operand, + Op::Subtract, + sumup_counter_operand, + || Some(format!("{:?}", expression_branch)), + ); + debug!("{:?} gets an expression: {}", expression_branch, self.format_counter(&expression)); + let bcb = expression_branch.target_bcb; + if expression_branch.is_only_path_to_target() { + self.basic_coverage_blocks[bcb].set_counter(expression)?; + } else { + self.basic_coverage_blocks[bcb].set_edge_counter_from(branching_bcb, expression)?; + } + Ok(()) + } + + fn get_or_make_counter_operand( + &mut self, + bcb: BasicCoverageBlock, + collect_intermediate_expressions: &mut Vec, + ) -> Result { + self.recursive_get_or_make_counter_operand(bcb, collect_intermediate_expressions, 1) + } + + fn recursive_get_or_make_counter_operand( + &mut self, + bcb: BasicCoverageBlock, + collect_intermediate_expressions: &mut Vec, + debug_indent_level: usize, + ) -> Result { + Ok({ + if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() { + debug!( + "{}{:?} already has a counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(counter_kind), + ); + counter_kind.as_operand_id() + } else { + let one_path_to_target = self.bcb_has_one_path_to_target(bcb); + if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) { + let counter_kind = + self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb))); + if one_path_to_target { + debug!( + "{}{:?} gets a new counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(&counter_kind), + ); + } else { + debug!( + "{}{:?} has itself as its own predecessor. It can't be part of its own \ + Expression sum, so it will get its own new counter: {}. (Note, the \ + compiled code will generate an infinite loop.)", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(&counter_kind), + ); + } + self.basic_coverage_blocks[bcb].set_counter(counter_kind)? + } else { + let mut predecessors = self.bcb_predecessors(bcb).clone().into_iter(); + debug!( + "{}{:?} has multiple incoming edges and will get an expression that sums \ + them up...", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + ); + let first_edge_counter_operand = self + .recursive_get_or_make_edge_counter_operand( + predecessors.next().unwrap(), + bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + )?; + let mut some_sumup_edge_counter_operand = None; + for predecessor in predecessors { + let edge_counter_operand = self + .recursive_get_or_make_edge_counter_operand( + predecessor, + bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + )?; + if let Some(sumup_edge_counter_operand) = + some_sumup_edge_counter_operand.replace(edge_counter_operand) + { + let intermediate_expression = self.coverage_counters.make_expression( + sumup_edge_counter_operand, + Op::Add, + edge_counter_operand, + || None, + ); + debug!( + "{}new intermediate expression: {}", + NESTED_INDENT.repeat(debug_indent_level), + self.format_counter(&intermediate_expression) + ); + let intermediate_expression_operand = + intermediate_expression.as_operand_id(); + collect_intermediate_expressions.push(intermediate_expression); + some_sumup_edge_counter_operand + .replace(intermediate_expression_operand); + } + } + let counter_kind = self.coverage_counters.make_expression( + first_edge_counter_operand, + Op::Add, + some_sumup_edge_counter_operand.unwrap(), + || Some(format!("{:?}", bcb)), + ); + debug!( + "{}{:?} gets a new counter (sum of predecessor counters): {}", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(&counter_kind) + ); + self.basic_coverage_blocks[bcb].set_counter(counter_kind)? + } + } + }) + } + + fn get_or_make_edge_counter_operand( + &mut self, + from_bcb: BasicCoverageBlock, + to_bcb: BasicCoverageBlock, + collect_intermediate_expressions: &mut Vec, + ) -> Result { + self.recursive_get_or_make_edge_counter_operand( + from_bcb, + to_bcb, + collect_intermediate_expressions, + 1, + ) + } + + fn recursive_get_or_make_edge_counter_operand( + &mut self, + from_bcb: BasicCoverageBlock, + to_bcb: BasicCoverageBlock, + collect_intermediate_expressions: &mut Vec, + debug_indent_level: usize, + ) -> Result { + Ok({ + let successors = self.bcb_successors(from_bcb).iter(); + if successors.len() > 1 { + if let Some(counter_kind) = + self.basic_coverage_blocks[to_bcb].edge_counter_from(from_bcb) + { + debug!( + "{}Edge {:?}->{:?} already has a counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + from_bcb, + to_bcb, + self.format_counter(counter_kind) + ); + counter_kind.as_operand_id() + } else { + let counter_kind = self + .coverage_counters + .make_counter(|| Some(format!("{:?}->{:?}", from_bcb, to_bcb))); + debug!( + "{}Edge {:?}->{:?} gets a new counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + from_bcb, + to_bcb, + self.format_counter(&counter_kind) + ); + self.basic_coverage_blocks[to_bcb] + .set_edge_counter_from(from_bcb, counter_kind)? + } + } else { + self.recursive_get_or_make_counter_operand( + from_bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + )? + } + }) + } + + /// Select a branch for the expression, either the recommended `reloop_branch`, or + /// if none was found, select any branch. + fn choose_preferred_expression_branch( + &self, + traversal: &TraverseCoverageGraphWithLoops, + branches: &Vec, + ) -> BcbBranch { + let branch_needs_a_counter = + |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none(); + + let some_reloop_branch = self.find_some_reloop_branch(traversal, &branches); + if let Some(reloop_branch_without_counter) = + some_reloop_branch.filter(branch_needs_a_counter) + { + debug!( + "Selecting reloop_branch={:?} that still needs a counter, to get the \ + `Expression`", + reloop_branch_without_counter + ); + reloop_branch_without_counter + } else { + let &branch_without_counter = branches + .iter() + .find(|&&branch| branch.counter(&self.basic_coverage_blocks).is_none()) + .expect( + "needs_branch_counters was `true` so there should be at least one \ + branch", + ); + debug!( + "Selecting any branch={:?} that still needs a counter, to get the \ + `Expression` because there was no `reloop_branch`, or it already had a \ + counter", + branch_without_counter + ); + branch_without_counter + } + } + + /// At most one of the branches (or its edge, from the branching_bcb, + /// if the branch has multiple incoming edges) can have a counter computed by + /// expression. + /// + /// If at least one of the branches leads outside of a loop (`found_loop_exit` is + /// true), and at least one other branch does not exit the loop (the first of which + /// is captured in `some_reloop_branch`), it's likely any reloop branch will be + /// executed far more often than loop exit branch, making the reloop branch a better + /// candidate for an expression. + fn find_some_reloop_branch( + &self, + traversal: &TraverseCoverageGraphWithLoops, + branches: &Vec, + ) -> Option { + let branch_needs_a_counter = + |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none(); + + let mut some_reloop_branch: Option = None; + for context in traversal.context_stack.iter().rev() { + if let Some((backedge_from_bcbs, _)) = &context.loop_backedges { + let mut found_loop_exit = false; + for &branch in branches.iter() { + if backedge_from_bcbs.iter().any(|&backedge_from_bcb| { + self.bcb_is_dominated_by(backedge_from_bcb, branch.target_bcb) + }) { + if let Some(reloop_branch) = some_reloop_branch { + if reloop_branch.counter(&self.basic_coverage_blocks).is_none() { + // we already found a candidate reloop_branch that still + // needs a counter + continue; + } + } + // The path from branch leads back to the top of the loop. Set this + // branch as the `reloop_branch`. If this branch already has a + // counter, and we find another reloop branch that doesn't have a + // counter yet, that branch will be selected as the `reloop_branch` + // instead. + some_reloop_branch = Some(branch); + } else { + // The path from branch leads outside this loop + found_loop_exit = true; + } + if found_loop_exit + && some_reloop_branch.filter(branch_needs_a_counter).is_some() + { + // Found both a branch that exits the loop and a branch that returns + // to the top of the loop (`reloop_branch`), and the `reloop_branch` + // doesn't already have a counter. + break; + } + } + if !found_loop_exit { + debug!( + "No branches exit the loop, so any branch without an existing \ + counter can have the `Expression`." + ); + break; + } + if some_reloop_branch.is_some() { + debug!( + "Found a branch that exits the loop and a branch the loops back to \ + the top of the loop (`reloop_branch`). The `reloop_branch` will \ + get the `Expression`, as long as it still needs a counter." + ); + break; + } + // else all branches exited this loop context, so run the same checks with + // the outer loop(s) + } + } + some_reloop_branch + } + + #[inline] + fn bcb_predecessors(&self, bcb: BasicCoverageBlock) -> &Vec { + &self.basic_coverage_blocks.predecessors[bcb] + } + + #[inline] + fn bcb_successors(&self, bcb: BasicCoverageBlock) -> &Vec { + &self.basic_coverage_blocks.successors[bcb] + } + + #[inline] + fn bcb_branches(&self, from_bcb: BasicCoverageBlock) -> Vec { + self.bcb_successors(from_bcb) + .iter() + .map(|&to_bcb| BcbBranch::from_to(from_bcb, to_bcb, &self.basic_coverage_blocks)) + .collect::>() + } + + fn bcb_needs_branch_counters(&self, bcb: BasicCoverageBlock) -> bool { + let branch_needs_a_counter = + |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none(); + let branches = self.bcb_branches(bcb); + branches.len() > 1 && branches.iter().any(branch_needs_a_counter) + } + + /// Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be + /// the entry point for the function.) + #[inline] + fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool { + self.bcb_predecessors(bcb).len() <= 1 + } + + #[inline] + fn bcb_is_dominated_by(&self, node: BasicCoverageBlock, dom: BasicCoverageBlock) -> bool { + self.basic_coverage_blocks.is_dominated_by(node, dom) + } + + #[inline] + fn format_counter(&self, counter_kind: &CoverageKind) -> String { + self.coverage_counters.debug_counters.format_counter(counter_kind) + } +} diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index fbf2ad224a821..7080975aee5ce 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -13,6 +13,8 @@ use rustc_middle::ty::TyCtxt; use std::lazy::SyncOnceCell; +pub const NESTED_INDENT: &str = " "; + const RUSTC_COVERAGE_DEBUG_OPTIONS: &str = "RUSTC_COVERAGE_DEBUG_OPTIONS"; pub(crate) fn debug_options<'a>() -> &'a DebugOptions { @@ -24,20 +26,29 @@ pub(crate) fn debug_options<'a>() -> &'a DebugOptions { /// Parses and maintains coverage-specific debug options captured from the environment variable /// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set. Options can be set on the command line by, for example: /// -/// $ RUSTC_COVERAGE_DEBUG_OPTIONS=counter-format=block cargo build +/// $ RUSTC_COVERAGE_DEBUG_OPTIONS=counter-format=block,allow_unused_expressions=n cargo build #[derive(Debug, Clone)] pub(crate) struct DebugOptions { + pub allow_unused_expressions: bool, counter_format: ExpressionFormat, } impl DebugOptions { fn new() -> Self { + let mut allow_unused_expressions = true; let mut counter_format = ExpressionFormat::default(); if let Ok(env_debug_options) = std::env::var(RUSTC_COVERAGE_DEBUG_OPTIONS) { for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(",") { let mut setting = setting_str.splitn(2, "="); match setting.next() { + Some(option) if option == "allow_unused_expressions" => { + allow_unused_expressions = bool_option_val(option, setting.next()); + debug!( + "{} env option `allow_unused_expressions` is set to {}", + RUSTC_COVERAGE_DEBUG_OPTIONS, allow_unused_expressions + ); + } Some(option) if option == "counter_format" => { if let Some(strval) = setting.next() { counter_format = counter_format_option_val(strval); @@ -66,7 +77,26 @@ impl DebugOptions { } } - Self { counter_format } + Self { allow_unused_expressions, counter_format } + } +} + +fn bool_option_val(option: &str, some_strval: Option<&str>) -> bool { + if let Some(val) = some_strval { + if vec!["yes", "y", "on", "true"].contains(&val) { + true + } else if vec!["no", "n", "off", "false"].contains(&val) { + false + } else { + bug!( + "Unsupported value `{}` for option `{}` in environment variable {}", + option, + val, + RUSTC_COVERAGE_DEBUG_OPTIONS + ) + } + } else { + true } } @@ -147,6 +177,14 @@ impl DebugCounters { } } + pub fn some_block_label(&self, operand: ExpressionOperandId) -> Option<&String> { + self.some_counters.as_ref().map_or(None, |counters| { + counters + .get(&operand) + .map_or(None, |debug_counter| debug_counter.some_block_label.as_ref()) + }) + } + pub fn format_counter(&self, counter_kind: &CoverageKind) -> String { match *counter_kind { CoverageKind::Counter { .. } => { @@ -242,16 +280,22 @@ impl DebugCounter { pub(crate) struct GraphvizData { some_bcb_to_coverage_spans_with_counters: Option>>, + some_bcb_to_dependency_counters: Option>>, some_edge_to_counter: Option>, } impl GraphvizData { pub fn new() -> Self { - Self { some_bcb_to_coverage_spans_with_counters: None, some_edge_to_counter: None } + Self { + some_bcb_to_coverage_spans_with_counters: None, + some_bcb_to_dependency_counters: None, + some_edge_to_counter: None, + } } pub fn enable(&mut self) { self.some_bcb_to_coverage_spans_with_counters = Some(FxHashMap::default()); + self.some_bcb_to_dependency_counters = Some(FxHashMap::default()); self.some_edge_to_counter = Some(FxHashMap::default()); } @@ -287,6 +331,187 @@ impl GraphvizData { None } } + + pub fn add_bcb_dependency_counter( + &mut self, + bcb: BasicCoverageBlock, + counter_kind: &CoverageKind, + ) { + if let Some(bcb_to_dependency_counters) = self.some_bcb_to_dependency_counters.as_mut() { + bcb_to_dependency_counters + .entry(bcb) + .or_insert_with(|| Vec::new()) + .push(counter_kind.clone()); + } + } + + pub fn get_bcb_dependency_counters( + &self, + bcb: BasicCoverageBlock, + ) -> Option<&Vec> { + if let Some(bcb_to_dependency_counters) = self.some_bcb_to_dependency_counters.as_ref() { + bcb_to_dependency_counters.get(&bcb) + } else { + None + } + } + + pub fn set_edge_counter( + &mut self, + from_bcb: BasicCoverageBlock, + to_bb: BasicBlock, + counter_kind: &CoverageKind, + ) { + if let Some(edge_to_counter) = self.some_edge_to_counter.as_mut() { + edge_to_counter.insert((from_bcb, to_bb), counter_kind.clone()).expect_none( + "invalid attempt to insert more than one edge counter for the same edge", + ); + } + } + + pub fn get_edge_counter( + &self, + from_bcb: BasicCoverageBlock, + to_bb: BasicBlock, + ) -> Option<&CoverageKind> { + if let Some(edge_to_counter) = self.some_edge_to_counter.as_ref() { + edge_to_counter.get(&(from_bcb, to_bb)) + } else { + None + } + } +} + +/// If enabled, this struct captures additional data used to track whether expressions were used, +/// directly or indirectly, to compute the coverage counts for all `CoverageSpan`s, and any that are +/// _not_ used are retained in the `unused_expressions` Vec, to be included in debug output (logs +/// and/or a `CoverageGraph` graphviz output). +pub(crate) struct UsedExpressions { + some_used_expression_operands: + Option>>, + some_unused_expressions: + Option, BasicCoverageBlock)>>, +} + +impl UsedExpressions { + pub fn new() -> Self { + Self { some_used_expression_operands: None, some_unused_expressions: None } + } + + pub fn enable(&mut self) { + self.some_used_expression_operands = Some(FxHashMap::default()); + self.some_unused_expressions = Some(Vec::new()); + } + + pub fn is_enabled(&mut self) -> bool { + self.some_used_expression_operands.is_some() + } + + pub fn add_expression_operands(&mut self, expression: &CoverageKind) { + if let Some(used_expression_operands) = self.some_used_expression_operands.as_mut() { + if let CoverageKind::Expression { id, lhs, rhs, .. } = *expression { + used_expression_operands.entry(lhs).or_insert_with(|| Vec::new()).push(id); + used_expression_operands.entry(rhs).or_insert_with(|| Vec::new()).push(id); + } + } + } + + pub fn expression_is_used(&mut self, expression: &CoverageKind) -> bool { + if let Some(used_expression_operands) = self.some_used_expression_operands.as_ref() { + used_expression_operands.contains_key(&expression.as_operand_id()) + } else { + false + } + } + + pub fn add_unused_expression_if_not_found( + &mut self, + expression: &CoverageKind, + edge_from_bcb: Option, + target_bcb: BasicCoverageBlock, + ) { + if let Some(used_expression_operands) = self.some_used_expression_operands.as_ref() { + if !used_expression_operands.contains_key(&expression.as_operand_id()) { + self.some_unused_expressions.as_mut().unwrap().push(( + expression.clone(), + edge_from_bcb, + target_bcb, + )); + } + } + } + + /// Return the list of unused counters (if any) as a tuple with the counter (`CoverageKind`), + /// optional `from_bcb` (if it was an edge counter), and `target_bcb`. + pub fn get_unused_expressions( + &self, + ) -> Vec<(CoverageKind, Option, BasicCoverageBlock)> { + if let Some(unused_expressions) = self.some_unused_expressions.as_ref() { + unused_expressions.clone() + } else { + Vec::new() + } + } + + /// If enabled, validate that every BCB or edge counter not directly associated with a coverage + /// span is at least indirectly associated (it is a dependency of a BCB counter that _is_ + /// associated with a coverage span). + pub fn validate( + &mut self, + bcb_counters_without_direct_coverage_spans: &Vec<( + Option, + BasicCoverageBlock, + CoverageKind, + )>, + ) { + if self.is_enabled() { + let mut not_validated = bcb_counters_without_direct_coverage_spans + .iter() + .map(|(_, _, counter_kind)| counter_kind) + .collect::>(); + let mut validating_count = 0; + while not_validated.len() != validating_count { + let to_validate = not_validated.split_off(0); + validating_count = to_validate.len(); + for counter_kind in to_validate { + if self.expression_is_used(counter_kind) { + self.add_expression_operands(counter_kind); + } else { + not_validated.push(counter_kind); + } + } + } + } + } + + pub fn alert_on_unused_expressions(&self, debug_counters: &DebugCounters) { + if let Some(unused_expressions) = self.some_unused_expressions.as_ref() { + for (counter_kind, edge_from_bcb, target_bcb) in unused_expressions { + let unused_counter_message = if let Some(from_bcb) = edge_from_bcb.as_ref() { + format!( + "non-coverage edge counter found without a dependent expression, in \ + {:?}->{:?}; counter={}", + from_bcb, + target_bcb, + debug_counters.format_counter(&counter_kind), + ) + } else { + format!( + "non-coverage counter found without a dependent expression, in {:?}; \ + counter={}", + target_bcb, + debug_counters.format_counter(&counter_kind), + ) + }; + + if debug_options().allow_unused_expressions { + debug!("WARNING: {}", unused_counter_message); + } else { + bug!("{}", unused_counter_message); + } + } + } + } } /// Generates the MIR pass `CoverageSpan`-specific spanview dump file. @@ -337,6 +562,8 @@ pub(crate) fn dump_coverage_graphviz( basic_coverage_blocks: &CoverageGraph, debug_counters: &DebugCounters, graphviz_data: &GraphvizData, + intermediate_expressions: &Vec, + debug_used_expressions: &UsedExpressions, ) { let mir_source = mir_body.source; let def_id = mir_source.def_id(); @@ -347,21 +574,62 @@ pub(crate) fn dump_coverage_graphviz( debug_counters, &basic_coverage_blocks[bcb], graphviz_data.get_bcb_coverage_spans_with_counters(bcb), + graphviz_data.get_bcb_dependency_counters(bcb), + // intermediate_expressions are injected into the mir::START_BLOCK, so + // include them in the first BCB. + if bcb.index() == 0 { Some(&intermediate_expressions) } else { None }, ) }; let edge_labels = |from_bcb| { let from_bcb_data = &basic_coverage_blocks[from_bcb]; let from_terminator = from_bcb_data.terminator(mir_body); - from_terminator - .kind - .fmt_successor_labels() + let mut edge_labels = from_terminator.kind.fmt_successor_labels(); + edge_labels.retain(|label| label.to_string() != "unreachable"); + let edge_counters = from_terminator + .successors() + .map(|&successor_bb| graphviz_data.get_edge_counter(from_bcb, successor_bb)); + edge_labels .iter() - .map(|label| label.to_string()) + .zip(edge_counters) + .map(|(label, some_counter)| { + if let Some(counter) = some_counter { + format!("{}\n{}", label, debug_counters.format_counter(counter)) + } else { + label.to_string() + } + }) .collect::>() }; let graphviz_name = format!("Cov_{}_{}", def_id.krate.index(), def_id.index.index()); - let graphviz_writer = + let mut graphviz_writer = GraphvizWriter::new(basic_coverage_blocks, &graphviz_name, node_content, edge_labels); + let unused_expressions = debug_used_expressions.get_unused_expressions(); + if unused_expressions.len() > 0 { + graphviz_writer.set_graph_label(&format!( + "Unused expressions:\n {}", + unused_expressions + .as_slice() + .iter() + .map(|(counter_kind, edge_from_bcb, target_bcb)| { + if let Some(from_bcb) = edge_from_bcb.as_ref() { + format!( + "{:?}->{:?}: {}", + from_bcb, + target_bcb, + debug_counters.format_counter(&counter_kind), + ) + } else { + format!( + "{:?}: {}", + target_bcb, + debug_counters.format_counter(&counter_kind), + ) + } + }) + .collect::>() + .join("\n ") + )); + } let mut file = pretty::create_dump_file(tcx, "dot", None, pass_name, &0, mir_source) .expect("Unexpected error creating BasicCoverageBlock graphviz DOT file"); graphviz_writer @@ -375,9 +643,22 @@ fn bcb_to_string_sections( debug_counters: &DebugCounters, bcb_data: &BasicCoverageBlockData, some_coverage_spans_with_counters: Option<&Vec<(CoverageSpan, CoverageKind)>>, + some_dependency_counters: Option<&Vec>, + some_intermediate_expressions: Option<&Vec>, ) -> Vec { let len = bcb_data.basic_blocks.len(); let mut sections = Vec::new(); + if let Some(collect_intermediate_expressions) = some_intermediate_expressions { + sections.push( + collect_intermediate_expressions + .iter() + .map(|expression| { + format!("Intermediate {}", debug_counters.format_counter(expression)) + }) + .collect::>() + .join("\n"), + ); + } if let Some(coverage_spans_with_counters) = some_coverage_spans_with_counters { sections.push( coverage_spans_with_counters @@ -393,6 +674,19 @@ fn bcb_to_string_sections( .join("\n"), ); } + if let Some(dependency_counters) = some_dependency_counters { + sections.push(format!( + "Non-coverage counters:\n {}", + dependency_counters + .iter() + .map(|counter| debug_counters.format_counter(counter)) + .collect::>() + .join(" \n"), + )); + } + if let Some(counter_kind) = &bcb_data.counter_kind { + sections.push(format!("{:?}", counter_kind)); + } let non_term_blocks = bcb_data.basic_blocks[0..len - 1] .iter() .map(|&bb| format!("{:?}: {}", bb, term_type(&mir_body[bb].terminator().kind))) diff --git a/compiler/rustc_mir/src/transform/coverage/graph.rs b/compiler/rustc_mir/src/transform/coverage/graph.rs index 3d3e76f907b64..8406254170196 100644 --- a/compiler/rustc_mir/src/transform/coverage/graph.rs +++ b/compiler/rustc_mir/src/transform/coverage/graph.rs @@ -1,7 +1,11 @@ +use super::Error; + +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::dominators::{self, Dominators}; -use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes}; +use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode}; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; +use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind}; use std::ops::{Index, IndexMut}; @@ -183,6 +187,13 @@ impl CoverageGraph { self.bcbs.iter_enumerated() } + #[inline(always)] + pub fn iter_enumerated_mut( + &mut self, + ) -> impl Iterator { + self.bcbs.iter_enumerated_mut() + } + #[inline(always)] pub fn bcb_from_bb(&self, bb: BasicBlock) -> Option { if bb.index() < self.bb_to_bcb.len() { self.bb_to_bcb[bb] } else { None } @@ -293,12 +304,14 @@ rustc_index::newtype_index! { #[derive(Debug, Clone)] pub(crate) struct BasicCoverageBlockData { pub basic_blocks: Vec, + pub counter_kind: Option, + edge_from_bcbs: Option>, } impl BasicCoverageBlockData { pub fn from(basic_blocks: Vec) -> Self { assert!(basic_blocks.len() > 0); - Self { basic_blocks } + Self { basic_blocks, counter_kind: None, edge_from_bcbs: None } } #[inline(always)] @@ -316,6 +329,91 @@ impl BasicCoverageBlockData { &mir_body[self.last_bb()].terminator() } + #[inline(always)] + pub fn set_counter( + &mut self, + counter_kind: CoverageKind, + ) -> Result { + debug_assert!( + // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also + // have an expression (to be injected into an existing `BasicBlock` represented by this + // `BasicCoverageBlock`). + self.edge_from_bcbs.is_none() || counter_kind.is_expression(), + "attempt to add a `Counter` to a BCB target with existing incoming edge counters" + ); + let operand = counter_kind.as_operand_id(); + let expect_none = self.counter_kind.replace(counter_kind); + if expect_none.is_some() { + return Error::from_string(format!( + "attempt to set a BasicCoverageBlock coverage counter more than once; \ + {:?} already had counter {:?}", + self, + expect_none.unwrap(), + )); + } + Ok(operand) + } + + #[inline(always)] + pub fn counter(&self) -> Option<&CoverageKind> { + self.counter_kind.as_ref() + } + + #[inline(always)] + pub fn take_counter(&mut self) -> Option { + self.counter_kind.take() + } + + #[inline(always)] + pub fn set_edge_counter_from( + &mut self, + from_bcb: BasicCoverageBlock, + counter_kind: CoverageKind, + ) -> Result { + if level_enabled!(tracing::Level::DEBUG) { + // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also + // have an expression (to be injected into an existing `BasicBlock` represented by this + // `BasicCoverageBlock`). + if !self.counter_kind.as_ref().map_or(true, |c| c.is_expression()) { + return Error::from_string(format!( + "attempt to add an incoming edge counter from {:?} when the target BCB already \ + has a `Counter`", + from_bcb + )); + } + } + let operand = counter_kind.as_operand_id(); + let expect_none = self + .edge_from_bcbs + .get_or_insert_with(|| FxHashMap::default()) + .insert(from_bcb, counter_kind); + if expect_none.is_some() { + return Error::from_string(format!( + "attempt to set an edge counter more than once; from_bcb: \ + {:?} already had counter {:?}", + from_bcb, + expect_none.unwrap(), + )); + } + Ok(operand) + } + + #[inline(always)] + pub fn edge_counter_from(&self, from_bcb: BasicCoverageBlock) -> Option<&CoverageKind> { + if let Some(edge_from_bcbs) = &self.edge_from_bcbs { + edge_from_bcbs.get(&from_bcb) + } else { + None + } + } + + #[inline(always)] + pub fn take_edge_counters( + &mut self, + ) -> Option> { + self.edge_from_bcbs.take().map_or(None, |m| Some(m.into_iter())) + } + pub fn id(&self) -> String { format!( "@{}", @@ -328,6 +426,56 @@ impl BasicCoverageBlockData { } } +/// Represents a successor from a branching BasicCoverageBlock (such as the arms of a `SwitchInt`) +/// as either the successor BCB itself, if it has only one incoming edge, or the successor _plus_ +/// the specific branching BCB, representing the edge between the two. The latter case +/// distinguishes this incoming edge from other incoming edges to the same `target_bcb`. +#[derive(Clone, Copy, PartialEq, Eq)] +pub(crate) struct BcbBranch { + pub edge_from_bcb: Option, + pub target_bcb: BasicCoverageBlock, +} + +impl BcbBranch { + pub fn from_to( + from_bcb: BasicCoverageBlock, + to_bcb: BasicCoverageBlock, + basic_coverage_blocks: &CoverageGraph, + ) -> Self { + let edge_from_bcb = if basic_coverage_blocks.predecessors[to_bcb].len() > 1 { + Some(from_bcb) + } else { + None + }; + Self { edge_from_bcb, target_bcb: to_bcb } + } + + pub fn counter<'a>( + &self, + basic_coverage_blocks: &'a CoverageGraph, + ) -> Option<&'a CoverageKind> { + if let Some(from_bcb) = self.edge_from_bcb { + basic_coverage_blocks[self.target_bcb].edge_counter_from(from_bcb) + } else { + basic_coverage_blocks[self.target_bcb].counter() + } + } + + pub fn is_only_path_to_target(&self) -> bool { + self.edge_from_bcb.is_none() + } +} + +impl std::fmt::Debug for BcbBranch { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(from_bcb) = self.edge_from_bcb { + write!(fmt, "{:?}->{:?}", from_bcb, self.target_bcb) + } else { + write!(fmt, "{:?}", self.target_bcb) + } + } +} + fn bcb_filtered_successors<'a, 'tcx>( body: &'tcx &'a mir::Body<'tcx>, term_kind: &'tcx TerminatorKind<'tcx>, @@ -344,6 +492,175 @@ fn bcb_filtered_successors<'a, 'tcx>( .filter(move |&&successor| body[successor].terminator().kind != TerminatorKind::Unreachable) } +/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the +/// CoverageGraph outside all loops. This supports traversing the BCB CFG in a way that +/// ensures a loop is completely traversed before processing Blocks after the end of the loop. +#[derive(Debug)] +pub(crate) struct TraversalContext { + /// From one or more backedges returning to a loop header. + pub loop_backedges: Option<(Vec, BasicCoverageBlock)>, + + /// worklist, to be traversed, of CoverageGraph in the loop with the given loop + /// backedges, such that the loop is the inner inner-most loop containing these + /// CoverageGraph + pub worklist: Vec, +} + +pub(crate) struct TraverseCoverageGraphWithLoops { + pub backedges: IndexVec>, + pub context_stack: Vec, + visited: BitSet, +} + +impl TraverseCoverageGraphWithLoops { + pub fn new(basic_coverage_blocks: &CoverageGraph) -> Self { + let start_bcb = basic_coverage_blocks.start_node(); + let backedges = find_loop_backedges(basic_coverage_blocks); + let mut context_stack = Vec::new(); + context_stack.push(TraversalContext { loop_backedges: None, worklist: vec![start_bcb] }); + // `context_stack` starts with a `TraversalContext` for the main function context (beginning + // with the `start` BasicCoverageBlock of the function). New worklists are pushed to the top + // of the stack as loops are entered, and popped off of the stack when a loop's worklist is + // exhausted. + let visited = BitSet::new_empty(basic_coverage_blocks.num_nodes()); + Self { backedges, context_stack, visited } + } + + pub fn next(&mut self, basic_coverage_blocks: &CoverageGraph) -> Option { + debug!( + "TraverseCoverageGraphWithLoops::next - context_stack: {:?}", + self.context_stack.iter().rev().collect::>() + ); + while let Some(next_bcb) = { + // Strip contexts with empty worklists from the top of the stack + while self.context_stack.last().map_or(false, |context| context.worklist.is_empty()) { + self.context_stack.pop(); + } + // Pop the next bcb off of the current context_stack. If none, all BCBs were visited. + self.context_stack.last_mut().map_or(None, |context| context.worklist.pop()) + } { + if !self.visited.insert(next_bcb) { + debug!("Already visited: {:?}", next_bcb); + continue; + } + debug!("Visiting {:?}", next_bcb); + if self.backedges[next_bcb].len() > 0 { + debug!("{:?} is a loop header! Start a new TraversalContext...", next_bcb); + self.context_stack.push(TraversalContext { + loop_backedges: Some((self.backedges[next_bcb].clone(), next_bcb)), + worklist: Vec::new(), + }); + } + self.extend_worklist(basic_coverage_blocks, next_bcb); + return Some(next_bcb); + } + None + } + + pub fn extend_worklist( + &mut self, + basic_coverage_blocks: &CoverageGraph, + bcb: BasicCoverageBlock, + ) { + let successors = &basic_coverage_blocks.successors[bcb]; + debug!("{:?} has {} successors:", bcb, successors.len()); + for &successor in successors { + if successor == bcb { + debug!( + "{:?} has itself as its own successor. (Note, the compiled code will \ + generate an infinite loop.)", + bcb + ); + // Don't re-add this successor to the worklist. We are already processing it. + break; + } + for context in self.context_stack.iter_mut().rev() { + // Add successors of the current BCB to the appropriate context. Successors that + // stay within a loop are added to the BCBs context worklist. Successors that + // exit the loop (they are not dominated by the loop header) must be reachable + // from other BCBs outside the loop, and they will be added to a different + // worklist. + // + // Branching blocks (with more than one successor) must be processed before + // blocks with only one successor, to prevent unnecessarily complicating + // `Expression`s by creating a Counter in a `BasicCoverageBlock` that the + // branching block would have given an `Expression` (or vice versa). + let (some_successor_to_add, some_loop_header) = + if let Some((_, loop_header)) = context.loop_backedges { + if basic_coverage_blocks.is_dominated_by(successor, loop_header) { + (Some(successor), Some(loop_header)) + } else { + (None, None) + } + } else { + (Some(successor), None) + }; + if let Some(successor_to_add) = some_successor_to_add { + if basic_coverage_blocks.successors[successor_to_add].len() > 1 { + debug!( + "{:?} successor is branching. Prioritize it at the beginning of \ + the {}", + successor_to_add, + if let Some(loop_header) = some_loop_header { + format!("worklist for the loop headed by {:?}", loop_header) + } else { + String::from("non-loop worklist") + }, + ); + context.worklist.insert(0, successor_to_add); + } else { + debug!( + "{:?} successor is non-branching. Defer it to the end of the {}", + successor_to_add, + if let Some(loop_header) = some_loop_header { + format!("worklist for the loop headed by {:?}", loop_header) + } else { + String::from("non-loop worklist") + }, + ); + context.worklist.push(successor_to_add); + } + break; + } + } + } + } + + pub fn is_complete(&self) -> bool { + self.visited.count() == self.visited.domain_size() + } + + pub fn unvisited(&self) -> Vec { + let mut unvisited_set: BitSet = + BitSet::new_filled(self.visited.domain_size()); + unvisited_set.subtract(&self.visited); + unvisited_set.iter().collect::>() + } +} + +fn find_loop_backedges( + basic_coverage_blocks: &CoverageGraph, +) -> IndexVec> { + let num_bcbs = basic_coverage_blocks.num_nodes(); + let mut backedges = IndexVec::from_elem_n(Vec::::new(), num_bcbs); + + // Identify loops by their backedges + for (bcb, _) in basic_coverage_blocks.iter_enumerated() { + for &successor in &basic_coverage_blocks.successors[bcb] { + if basic_coverage_blocks.is_dominated_by(bcb, successor) { + let loop_header = successor; + let backedge_from_bcb = bcb; + debug!( + "Found BCB backedge: {:?} -> loop_header: {:?}", + backedge_from_bcb, loop_header + ); + backedges[loop_header].push(backedge_from_bcb); + } + } + } + backedges +} + pub struct ShortCircuitPreorder< 'a, 'tcx, diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index d1d94092c9def..c84ccf19213b8 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -6,7 +6,7 @@ mod graph; mod spans; use counters::CoverageCounters; -use graph::CoverageGraph; +use graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph}; use spans::{CoverageSpan, CoverageSpans}; use crate::transform::MirPass; @@ -21,11 +21,26 @@ use rustc_middle::hir; use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::ich::StableHashingContext; use rustc_middle::mir::coverage::*; -use rustc_middle::mir::{self, BasicBlock, Coverage, Statement, StatementKind}; +use rustc_middle::mir::{ + self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator, + TerminatorKind, +}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol}; +/// A simple error message wrapper for `coverage::Error`s. +#[derive(Debug)] +pub(crate) struct Error { + message: String, +} + +impl Error { + pub fn from_string(message: String) -> Result { + Err(Self { message }) + } +} + /// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected /// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen /// to construct the coverage map. @@ -104,6 +119,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { debug!("instrumenting {:?}, span: {}", def_id, source_map.span_to_string(body_span)); let mut graphviz_data = debug::GraphvizData::new(); + let mut debug_used_expressions = debug::UsedExpressions::new(); let dump_graphviz = tcx.sess.opts.debugging_opts.dump_mir_graphviz; if dump_graphviz { @@ -111,6 +127,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { self.coverage_counters.enable_debug(); } + if dump_graphviz || level_enabled!(tracing::Level::DEBUG) { + debug_used_expressions.enable(); + } + //////////////////////////////////////////////////// // Compute `CoverageSpan`s from the `CoverageGraph`. let coverage_spans = CoverageSpans::generate_coverage_spans( @@ -129,7 +149,53 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { ); } - self.inject_coverage_span_counters(coverage_spans, &mut graphviz_data); + //////////////////////////////////////////////////// + // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure + // every `CoverageSpan` has a `Counter` or `Expression` assigned to its `BasicCoverageBlock` + // and all `Expression` dependencies (operands) are also generated, for any other + // `BasicCoverageBlock`s not already associated with a `CoverageSpan`. + // + // Intermediate expressions (used to compute other `Expression` values), which have no + // direct associate to any `BasicCoverageBlock`, are returned in the method `Result`. + let intermediate_expressions_or_error = self + .coverage_counters + .make_bcb_counters(&mut self.basic_coverage_blocks, &coverage_spans); + + let (result, intermediate_expressions) = match intermediate_expressions_or_error { + Ok(intermediate_expressions) => { + // If debugging, add any intermediate expressions (which are not associated with any + // BCB) to the `debug_used_expressions` map. + if debug_used_expressions.is_enabled() { + for intermediate_expression in &intermediate_expressions { + debug_used_expressions.add_expression_operands(intermediate_expression); + } + } + + //////////////////////////////////////////////////// + // Remove the counter or edge counter from of each `CoverageSpan`s associated + // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR. + self.inject_coverage_span_counters( + coverage_spans, + &mut graphviz_data, + &mut debug_used_expressions, + ); + + //////////////////////////////////////////////////// + // For any remaining `BasicCoverageBlock` counters (that were not associated with + // any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s) + // to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on + // are in fact counted, even though they don't directly contribute to counting + // their own independent code region's coverage. + self.inject_indirect_counters(&mut graphviz_data, &mut debug_used_expressions); + + // Intermediate expressions will be injected as the final step, after generating + // debug output, if any. + //////////////////////////////////////////////////// + + (Ok(()), intermediate_expressions) + } + Err(e) => (Err(e), Vec::new()), + }; if graphviz_data.is_enabled() { // Even if there was an error, a partial CoverageGraph can still generate a useful @@ -141,19 +207,40 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { &self.basic_coverage_blocks, &self.coverage_counters.debug_counters, &graphviz_data, + &intermediate_expressions, + &debug_used_expressions, ); } + + if let Err(e) = result { + bug!("Error processing: {:?}: {:?}", self.mir_body.source.def_id(), e) + }; + + // Depending on current `debug_options()`, `alert_on_unused_expressions()` could panic, so + // this check is performed as late as possible, to allow other debug output (logs and dump + // files), which might be helpful in analyzing unused expressions, to still be generated. + debug_used_expressions.alert_on_unused_expressions(&self.coverage_counters.debug_counters); + + //////////////////////////////////////////////////// + // Finally, inject the intermediate expressions collected along the way. + for intermediate_expression in intermediate_expressions { + inject_intermediate_expression(self.mir_body, intermediate_expression); + } } /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given - /// BCB, but only one actual counter needs to be incremented per BCB. `bcb_counters` maps each + /// BCB, but only one actual counter needs to be incremented per BCB. `bb_counters` maps each /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to /// the BCB `Counter` value. + /// + /// If debugging, add every BCB `Expression` associated with a `CoverageSpan`s to the + /// `used_expression_operands` map. fn inject_coverage_span_counters( &mut self, coverage_spans: Vec, graphviz_data: &mut debug::GraphvizData, + debug_used_expressions: &mut debug::UsedExpressions, ) { let tcx = self.tcx; let source_map = tcx.sess.source_map(); @@ -165,40 +252,194 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { for covspan in coverage_spans { let bcb = covspan.bcb; let span = covspan.span; - if let Some(&counter_operand) = bcb_counters[bcb].as_ref() { - let expression = self.coverage_counters.make_expression( - counter_operand, - Op::Add, - ExpressionOperandId::ZERO, - || Some(format!("{:?}", bcb)), - ); - debug!( - "Injecting counter expression {:?} at: {:?}:\n{}\n==========", - expression, - span, - source_map.span_to_snippet(span).expect("Error getting source for span"), - ); - graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &expression); - let bb = self.basic_coverage_blocks[bcb].leader_bb(); - let code_region = make_code_region(file_name, &source_file, span, body_span); - inject_statement(self.mir_body, expression, bb, Some(code_region)); + let counter_kind = if let Some(&counter_operand) = bcb_counters[bcb].as_ref() { + self.coverage_counters.make_identity_counter(counter_operand) + } else if let Some(counter_kind) = self.bcb_data_mut(bcb).take_counter() { + bcb_counters[bcb] = Some(counter_kind.as_operand_id()); + debug_used_expressions.add_expression_operands(&counter_kind); + counter_kind } else { - let counter = self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb))); - debug!( - "Injecting counter {:?} at: {:?}:\n{}\n==========", - counter, - span, - source_map.span_to_snippet(span).expect("Error getting source for span"), - ); - let counter_operand = counter.as_operand_id(); - bcb_counters[bcb] = Some(counter_operand); - graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &counter); - let bb = self.basic_coverage_blocks[bcb].leader_bb(); - let code_region = make_code_region(file_name, &source_file, span, body_span); - inject_statement(self.mir_body, counter, bb, Some(code_region)); + bug!("Every BasicCoverageBlock should have a Counter or Expression"); + }; + graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &counter_kind); + let some_code_region = if self.is_code_region_redundant(bcb, span, body_span) { + None + } else { + Some(make_code_region(file_name, &source_file, span, body_span)) + }; + inject_statement(self.mir_body, counter_kind, self.bcb_last_bb(bcb), some_code_region); + } + } + + /// Returns true if the type of `BasicCoverageBlock` (specifically, it's `BasicBlock`s + /// `TerminatorKind`) with the given `Span` (relative to the `body_span`) is known to produce + /// a redundant coverage count. + /// + /// There is at least one case for this, and if it's not handled, the last line in a function + /// will be double-counted. + /// + /// If this method returns `true`, the counter (which other `Expressions` may depend on) is + /// still injected, but without an associated code region. + fn is_code_region_redundant( + &self, + bcb: BasicCoverageBlock, + span: Span, + body_span: Span, + ) -> bool { + if span.hi() == body_span.hi() { + // All functions execute a `Return`-terminated `BasicBlock`, regardless of how the + // function returns; but only some functions also _can_ return after a `Goto` block + // that ends on the closing brace of the function (with the `Return`). When this + // happens, the last character is counted 2 (or possibly more) times, when we know + // the function returned only once (of course). By giving all `Goto` terminators at + // the end of a function a `non-reportable` code region, they are still counted + // if appropriate, but they don't increment the line counter, as long as their is + // also a `Return` on that last line. + if let TerminatorKind::Goto { .. } = self.bcb_terminator(bcb).kind { + return true; } } + false } + + /// `inject_coverage_span_counters()` looped through the `CoverageSpan`s and injected the + /// counter from the `CoverageSpan`s `BasicCoverageBlock`, removing it from the BCB in the + /// process (via `take_counter()`). + /// + /// Any other counter associated with a `BasicCoverageBlock`, or its incoming edge, but not + /// associated with a `CoverageSpan`, should only exist if the counter is a `Expression` + /// dependency (one of the expression operands). Collect them, and inject the additional + /// counters into the MIR, without a reportable coverage span. + fn inject_indirect_counters( + &mut self, + graphviz_data: &mut debug::GraphvizData, + debug_used_expressions: &mut debug::UsedExpressions, + ) { + let mut bcb_counters_without_direct_coverage_spans = Vec::new(); + for (target_bcb, target_bcb_data) in self.basic_coverage_blocks.iter_enumerated_mut() { + if let Some(counter_kind) = target_bcb_data.take_counter() { + bcb_counters_without_direct_coverage_spans.push((None, target_bcb, counter_kind)); + } + if let Some(edge_counters) = target_bcb_data.take_edge_counters() { + for (from_bcb, counter_kind) in edge_counters { + bcb_counters_without_direct_coverage_spans.push(( + Some(from_bcb), + target_bcb, + counter_kind, + )); + } + } + } + + // If debug is enabled, validate that every BCB or edge counter not directly associated + // with a coverage span is at least indirectly associated (it is a dependency of a BCB + // counter that _is_ associated with a coverage span). + debug_used_expressions.validate(&bcb_counters_without_direct_coverage_spans); + + for (edge_from_bcb, target_bcb, counter_kind) in bcb_counters_without_direct_coverage_spans + { + debug_used_expressions.add_unused_expression_if_not_found( + &counter_kind, + edge_from_bcb, + target_bcb, + ); + + match counter_kind { + CoverageKind::Counter { .. } => { + let inject_to_bb = if let Some(from_bcb) = edge_from_bcb { + // The MIR edge starts `from_bb` (the outgoing / last BasicBlock in + // `from_bcb`) and ends at `to_bb` (the incoming / first BasicBlock in the + // `target_bcb`; also called the `leader_bb`). + let from_bb = self.bcb_last_bb(from_bcb); + let to_bb = self.bcb_leader_bb(target_bcb); + + let new_bb = inject_edge_counter_basic_block(self.mir_body, from_bb, to_bb); + graphviz_data.set_edge_counter(from_bcb, new_bb, &counter_kind); + debug!( + "Edge {:?} (last {:?}) -> {:?} (leader {:?}) requires a new MIR \ + BasicBlock {:?}, for unclaimed edge counter {}", + edge_from_bcb, + from_bb, + target_bcb, + to_bb, + new_bb, + self.format_counter(&counter_kind), + ); + new_bb + } else { + let target_bb = self.bcb_last_bb(target_bcb); + graphviz_data.add_bcb_dependency_counter(target_bcb, &counter_kind); + debug!( + "{:?} ({:?}) gets a new Coverage statement for unclaimed counter {}", + target_bcb, + target_bb, + self.format_counter(&counter_kind), + ); + target_bb + }; + + inject_statement(self.mir_body, counter_kind, inject_to_bb, None); + } + CoverageKind::Expression { .. } => { + inject_intermediate_expression(self.mir_body, counter_kind) + } + _ => bug!("CoverageKind should be a counter"), + } + } + } + + #[inline] + fn bcb_leader_bb(&self, bcb: BasicCoverageBlock) -> BasicBlock { + self.bcb_data(bcb).leader_bb() + } + + #[inline] + fn bcb_last_bb(&self, bcb: BasicCoverageBlock) -> BasicBlock { + self.bcb_data(bcb).last_bb() + } + + #[inline] + fn bcb_terminator(&self, bcb: BasicCoverageBlock) -> &Terminator<'tcx> { + self.bcb_data(bcb).terminator(self.mir_body) + } + + #[inline] + fn bcb_data(&self, bcb: BasicCoverageBlock) -> &BasicCoverageBlockData { + &self.basic_coverage_blocks[bcb] + } + + #[inline] + fn bcb_data_mut(&mut self, bcb: BasicCoverageBlock) -> &mut BasicCoverageBlockData { + &mut self.basic_coverage_blocks[bcb] + } + + #[inline] + fn format_counter(&self, counter_kind: &CoverageKind) -> String { + self.coverage_counters.debug_counters.format_counter(counter_kind) + } +} + +fn inject_edge_counter_basic_block( + mir_body: &mut mir::Body<'tcx>, + from_bb: BasicBlock, + to_bb: BasicBlock, +) -> BasicBlock { + let span = mir_body[from_bb].terminator().source_info.span.shrink_to_hi(); + let new_bb = mir_body.basic_blocks_mut().push(BasicBlockData { + statements: vec![], // counter will be injected here + terminator: Some(Terminator { + source_info: SourceInfo::outermost(span), + kind: TerminatorKind::Goto { target: to_bb }, + }), + is_cleanup: false, + }); + let edge_ref = mir_body[from_bb] + .terminator_mut() + .successors_mut() + .find(|successor| **successor == to_bb) + .expect("from_bb should have a successor for to_bb"); + *edge_ref = new_bb; + new_bb } fn inject_statement( @@ -223,6 +464,20 @@ fn inject_statement( data.statements.push(statement); } +// Non-code expressions are injected into the coverage map, without generating executable code. +fn inject_intermediate_expression(mir_body: &mut mir::Body<'tcx>, expression: CoverageKind) { + debug_assert!(if let CoverageKind::Expression { .. } = expression { true } else { false }); + debug!(" injecting non-code expression {:?}", expression); + let inject_in_bb = mir::START_BLOCK; + let data = &mut mir_body[inject_in_bb]; + let source_info = data.terminator().source_info; + let statement = Statement { + source_info, + kind: StatementKind::Coverage(box Coverage { kind: expression, code_region: None }), + }; + data.statements.push(statement); +} + /// Convert the Span into its file name, start line and column, and end line and column fn make_code_region( file_name: Symbol, diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot index df9f7aa627b26..efc06bdea57a6 100644 --- a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot +++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot @@ -2,5 +2,5 @@ digraph Cov_0_4 { graph [fontname="Courier, monospace"]; node [fontname="Courier, monospace"]; edge [fontname="Courier, monospace"]; - bcb0__Cov_0_4 [shape="none", label=<
bcb0
Counter(bcb0) at 19:5-20:2
19:5-19:9: @0[0]: _0 = const true
20:2-20:2: @0.Return: return
bb0: Return
>]; + bcb0__Cov_0_4 [shape="none", label=<
bcb0
Counter(bcb0) at 19:5-20:2
19:5-19:9: @0[0]: _0 = const true
20:2-20:2: @0.Return: return
bb0: Return
>]; } diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot index 051ef498fb7fe..5ddd112fe62e6 100644 --- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot +++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot @@ -2,9 +2,9 @@ digraph Cov_0_3 { graph [fontname="Courier, monospace"]; node [fontname="Courier, monospace"]; edge [fontname="Courier, monospace"]; - bcb2__Cov_0_3 [shape="none", label=<
bcb2
Counter(bcb2) at 14:6-14:6
14:6-14:6: @4.Goto: goto -> bb0
bb4: Goto
>]; + bcb2__Cov_0_3 [shape="none", label=<
bcb2
Expression(bcb0 - bcb1) at 14:6-14:6
14:6-14:6: @4.Goto: goto -> bb0
bb4: Goto
>]; bcb1__Cov_0_3 [shape="none", label=<
bcb1
Counter(bcb1) at 12:13-12:18
12:13-12:18: @5[0]: _0 = const ()
Expression(bcb1 + 0) at 15:2-15:2
15:2-15:2: @5.Return: return
bb3: FalseEdge
bb5: Return
>]; - bcb0__Cov_0_3 [shape="none", label=<
bcb0
Counter(bcb0) at 11:12-11:17
11:12-11:17: @1.Call: _2 = bar() -> [return: bb2, unwind: bb6]
11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)
bb0: FalseUnwind
bb1: Call
bb2: SwitchInt
>]; + bcb0__Cov_0_3 [shape="none", label=<
bcb0
Counter(bcb0) at 11:12-11:17
11:12-11:17: @1.Call: _2 = bar() -> [return: bb2, unwind: bb6]
11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)
bb0: FalseUnwind
bb1: Call
bb2: SwitchInt
>]; bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>]; bcb0__Cov_0_3 -> bcb2__Cov_0_3 [label=]; bcb0__Cov_0_3 -> bcb1__Cov_0_3 [label=]; diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff index ddc65085e8093..c67d0e2ffe656 100644 --- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff +++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff @@ -8,7 +8,6 @@ let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10 bb0: { -+ Coverage::Counter(1) for /the/src/instrument_coverage.rs:12:12 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 falseUnwind -> [real: bb1, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } @@ -22,25 +21,26 @@ bb2: { FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17 ++ Coverage::Counter(1) for /the/src/instrument_coverage.rs:12:12 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb3: { -+ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 -+ Coverage::Expression(4294967295) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 } bb4: { _1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10 StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 -+ Coverage::Counter(3) for /the/src/instrument_coverage.rs:15:6 - 15:7; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 ++ Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:15:6 - 15:7; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6 } bb5: { _0 = const (); // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18 StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6 ++ Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 ++ Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 return; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2 } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json index 7a7e4c04f0018..bd2e2d56d4a55 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.drop_trait.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 5, + "covered": 5, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 5, + "covered": 5, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json index 1025cd3de80d2..a50f4657e20aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.generics.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 7, - "covered": 7, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 7, - "covered": 7, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json index 2d2ad1dbe3f71..36f81ceae19bf 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.if_else.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 29, - "covered": 21, - "percent": 72.41379310344827 + "count": 28, + "covered": 19, + "percent": 67.85714285714286 }, "regions": { - "count": 9, - "covered": 7, + "count": 7, + "covered": 5, "notcovered": 2, - "percent": 77.77777777777779 + "percent": 71.42857142857143 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 29, - "covered": 21, - "percent": 72.41379310344827 + "count": 28, + "covered": 19, + "percent": 67.85714285714286 }, "regions": { - "count": 9, - "covered": 7, + "count": 7, + "covered": 5, "notcovered": 2, - "percent": 77.77777777777779 + "percent": 71.42857142857143 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json index 39e17359eee76..929e769b50a98 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json @@ -21,10 +21,10 @@ "percent": 94.73684210526315 }, "regions": { - "count": 18, - "covered": 15, + "count": 17, + "covered": 14, "notcovered": 3, - "percent": 83.33333333333334 + "percent": 82.35294117647058 } } } @@ -46,10 +46,10 @@ "percent": 94.73684210526315 }, "regions": { - "count": 18, - "covered": 15, + "count": 17, + "covered": 14, "notcovered": 3, - "percent": 83.33333333333334 + "percent": 82.35294117647058 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json index 464bb614ea1b1..d93458b614372 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.various_conditions.json @@ -21,10 +21,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 70, - "covered": 19, + "count": 69, + "covered": 18, "notcovered": 51, - "percent": 27.142857142857142 + "percent": 26.08695652173913 } } } @@ -46,10 +46,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 70, - "covered": 19, + "count": 69, + "covered": 18, "notcovered": 51, - "percent": 27.142857142857142 + "percent": 26.08695652173913 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json index a116a91a60aae..a9e01604ccd5b 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.while_early_return.json @@ -21,10 +21,10 @@ "percent": 88.23529411764706 }, "regions": { - "count": 10, - "covered": 8, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 80 + "percent": 77.77777777777779 } } } @@ -46,10 +46,10 @@ "percent": 88.23529411764706 }, "regions": { - "count": 10, - "covered": 8, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 80 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt index 43592df1059aa..72aa020ca1691 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.drop_trait.txt @@ -24,7 +24,7 @@ 24| | let _ = Firework { strength: 1000 }; 25| | 26| | Ok(()) - 27| 2|} + 27| 1|} 28| | 29| |// Expected program output: 30| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt index 11dc0aa65e2d1..86199d7476302 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.generics.txt @@ -57,7 +57,7 @@ 35| | let _ = Firework { strength: 1000 }; 36| | 37| | Ok(()) - 38| 2|} + 38| 1|} 39| | 40| |// Expected program output: 41| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt index 64cbc262521bf..5f899723e2554 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.if_else.txt @@ -20,7 +20,7 @@ 20| 0| countdown 21| 0| = 22| 0| 100 - 23| 1| } + 23| | } 24| | 25| | if 26| 1| is_true @@ -36,6 +36,6 @@ 36| 0| = 37| 0| 100 38| 0| ; - 39| 1| } + 39| 0| } 40| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt index c43b492db6057..94c63c9a2b906 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt @@ -33,5 +33,5 @@ 32| 5| } 33| 5| } 34| 0| Ok(()) - 35| 2|} + 35| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt index e0efe75043d4a..173ff4aa4c481 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.various_conditions.txt @@ -65,5 +65,5 @@ 64| | } else { 65| 0| return; 66| | }; - 67| 2|} + 67| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt index e5c5b05a6fc80..26041136d2f4c 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.while_early_return.txt @@ -33,7 +33,7 @@ 33| | ; 34| | } 35| 0| Ok(()) - 36| 2|} + 36| 1|} 37| | 38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and 39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt index 3eb07757c0da5..ef43bbd78a6b5 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt @@ -2,8 +2,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 20:21 -> 20:38, #1 Counter in file 0 21:20 -> 21:28, (#1 + 0) Counter in file 0 21:29 -> 23:18, #2 -Counter in file 0 23:18 -> 23:19, #3 -Counter in file 0 24:17 -> 25:14, #4 +Counter in file 0 23:18 -> 23:19, (#1 - #2) +Counter in file 0 24:17 -> 25:14, (#2 + (#1 - #2)) Counter in file 0 3:11 -> 18:13, #1 Counter in file 0 25:14 -> 33:9, (#1 + 0) Counter in file 0 40:6 -> 60:13, (#1 + 0) @@ -12,18 +12,18 @@ Counter in file 0 82:6 -> 93:2, (#1 + 0) Counter in file 0 77:13 -> 77:30, #1 Counter in file 0 78:12 -> 78:20, (#1 + 0) Counter in file 0 78:21 -> 80:10, #2 -Counter in file 0 80:10 -> 80:11, #3 -Counter in file 0 81:9 -> 82:6, #4 +Counter in file 0 80:10 -> 80:11, (#1 - #2) +Counter in file 0 81:9 -> 82:6, (#2 + (#1 - #2)) Counter in file 0 62:21 -> 62:38, #1 Counter in file 0 63:20 -> 63:28, (#1 + 0) Counter in file 0 63:29 -> 65:18, #2 -Counter in file 0 65:18 -> 65:19, #3 -Counter in file 0 66:17 -> 67:14, #4 +Counter in file 0 65:18 -> 65:19, (#1 - #2) +Counter in file 0 66:17 -> 67:14, (#2 + (#1 - #2)) Counter in file 0 35:13 -> 35:30, #1 Counter in file 0 36:12 -> 36:20, (#1 + 0) Counter in file 0 36:21 -> 38:10, #2 -Counter in file 0 38:10 -> 38:11, #3 -Counter in file 0 39:9 -> 40:6, #4 +Counter in file 0 38:10 -> 38:11, (#1 - #2) +Counter in file 0 39:9 -> 40:6, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/closure.rs Combined regions: 3:11 -> 18:13 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt index 2bafe7d88e24c..9716284f52521 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt @@ -3,7 +3,7 @@ Counter in file 0 9:24 -> 11:6, #1 Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) Counter in file 0 20:9 -> 21:22, #2 -Counter in file 0 27:1 -> 27:2, #4 +Counter in file 0 27:1 -> 27:2, (#2 + 0) Emitting segments for file: ../coverage/drop_trait.rs Combined regions: 9:24 -> 11:6 (count=2) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt index a13b1f3d78614..5fbfe69b891c0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt @@ -4,7 +4,7 @@ Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 23:9 -> 28:28, #1 Counter in file 0 30:8 -> 30:12, (#1 + 0) Counter in file 0 31:9 -> 32:22, #2 -Counter in file 0 38:1 -> 38:2, #4 +Counter in file 0 38:1 -> 38:2, (#2 + 0) Counter in file 0 10:49 -> 12:6, #1 Counter in file 0 10:49 -> 12:6, #1 Emitting segments for file: ../coverage/generics.rs diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt index 2f063de5a3959..48c9278a23917 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt @@ -2,8 +2,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 8:5 -> 18:10, #1 Counter in file 0 21:9 -> 21:16, (#1 + 0) Counter in file 0 22:5 -> 27:6, #2 -Counter in file 0 27:6 -> 27:7, #3 -Counter in file 0 28:1 -> 28:2, #4 +Counter in file 0 27:6 -> 27:7, (#1 - #2) +Counter in file 0 28:1 -> 28:2, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/if.rs Combined regions: 8:5 -> 18:10 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt index 270a6f2b14a34..1adf92300bfbd 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt @@ -1,11 +1,11 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 -Counter in file 0 20:9 -> 22:16, #3 -Counter in file 0 26:9 -> 26:16, #4 -Counter in file 0 27:5 -> 32:6, #5 -Counter in file 0 34:5 -> 39:6, #6 -Counter in file 0 40:1 -> 40:2, #7 +Counter in file 0 20:9 -> 22:16, (#1 - #2) +Counter in file 0 26:9 -> 26:16, (#2 + (#1 - #2)) +Counter in file 0 27:5 -> 32:6, #3 +Counter in file 0 34:5 -> 39:6, ((#2 + (#1 - #2)) - #3) +Counter in file 0 40:1 -> 40:2, (#3 + ((#2 + (#1 - #2)) - #3)) Emitting segments for file: ../coverage/if_else.rs Combined regions: 7:9 -> 11:16 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt index fb863c73a6366..0678be30dc341 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt @@ -6,11 +6,11 @@ Counter in file 0 21:9 -> 22:6, (#2 + 0) Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, #3 -Counter in file 0 48:8 -> 48:15, #4 -Counter in file 0 48:16 -> 50:6, #5 -Counter in file 0 50:6 -> 50:7, #6 -Counter in file 0 52:9 -> 57:2, #7 +Counter in file 0 12:6 -> 12:7, (#1 - #2) +Counter in file 0 48:8 -> 48:15, (#2 + (#1 - #2)) +Counter in file 0 48:16 -> 50:6, #3 +Counter in file 0 50:6 -> 50:7, ((#2 + (#1 - #2)) - #3) +Counter in file 0 52:9 -> 57:2, (#3 + ((#2 + (#1 - #2)) - #3)) Counter in file 0 33:42 -> 36:10, #1 Counter in file 0 41:37 -> 41:41, #1 Counter in file 0 42:13 -> 43:10, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt index 4561fcc5b36a5..e955fcd8ba05e 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt @@ -2,40 +2,40 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:42, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 14:6, #2 -Counter in file 0 14:6 -> 14:7, #3 -Counter in file 0 16:9 -> 16:17, #4 -Counter in file 0 18:13 -> 18:18, #5 -Counter in file 0 20:13 -> 20:18, #6 -Counter in file 0 20:18 -> 20:19, #7 -Counter in file 0 20:18 -> 20:19, #8 -Counter in file 0 23:9 -> 23:17, #9 -Counter in file 0 25:13 -> 25:18, (#4 + 0) -Counter in file 0 27:13 -> 27:18, #10 -Counter in file 0 27:18 -> 27:19, #11 -Counter in file 0 27:18 -> 27:19, #12 -Counter in file 0 29:9 -> 29:17, #13 -Counter in file 0 29:20 -> 29:25, (#9 + 0) -Counter in file 0 29:29 -> 29:34, #14 -Counter in file 0 29:34 -> 29:35, #15 -Counter in file 0 29:34 -> 29:35, #16 -Counter in file 0 30:9 -> 30:17, #17 -Counter in file 0 30:20 -> 30:25, (#13 + 0) -Counter in file 0 30:29 -> 30:34, #18 -Counter in file 0 30:34 -> 30:35, #19 -Counter in file 0 30:34 -> 30:35, #20 -Counter in file 0 33:9 -> 34:16, (#17 + 0) -Counter in file 0 35:5 -> 38:6, #21 -Counter in file 0 38:6 -> 38:7, #22 -Counter in file 0 41:9 -> 41:16, #23 -Counter in file 0 42:5 -> 45:6, #24 -Counter in file 0 47:5 -> 50:6, #25 -Counter in file 0 52:8 -> 52:16, #26 -Counter in file 0 52:17 -> 54:6, #27 -Counter in file 0 54:6 -> 54:7, #28 -Counter in file 0 56:8 -> 56:15, #29 -Counter in file 0 56:16 -> 58:6, #30 -Counter in file 0 58:12 -> 60:6, #31 -Counter in file 0 61:1 -> 61:2, #32 +Counter in file 0 14:6 -> 14:7, (#1 - #2) +Counter in file 0 16:9 -> 16:17, ((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) +Counter in file 0 18:13 -> 18:18, (#2 + (#1 - #2)) +Counter in file 0 20:13 -> 20:18, ((#2 + (#1 - #2)) - #3) +Counter in file 0 20:18 -> 20:19, (#3 + #4) +Counter in file 0 20:18 -> 20:19, (((#2 + (#1 - #2)) - #3) - #4) +Counter in file 0 23:9 -> 23:17, ((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) +Counter in file 0 25:13 -> 25:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) + 0) +Counter in file 0 27:13 -> 27:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) +Counter in file 0 27:18 -> 27:19, (#5 + #6) +Counter in file 0 27:18 -> 27:19, ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6) +Counter in file 0 29:9 -> 29:17, ((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) +Counter in file 0 29:20 -> 29:25, (((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) + 0) +Counter in file 0 29:29 -> 29:34, #7 +Counter in file 0 29:34 -> 29:35, ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8) +Counter in file 0 29:34 -> 29:35, (#7 - #8) +Counter in file 0 30:9 -> 30:17, ((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) +Counter in file 0 30:20 -> 30:25, (((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) + 0) +Counter in file 0 30:29 -> 30:34, #9 +Counter in file 0 30:34 -> 30:35, ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10) +Counter in file 0 30:34 -> 30:35, (#9 - #10) +Counter in file 0 33:9 -> 34:16, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) + 0) +Counter in file 0 35:5 -> 38:6, #11 +Counter in file 0 38:6 -> 38:7, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11) +Counter in file 0 41:9 -> 41:16, (#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) +Counter in file 0 42:5 -> 45:6, #12 +Counter in file 0 47:5 -> 50:6, ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12) +Counter in file 0 52:8 -> 52:16, (#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) +Counter in file 0 52:17 -> 54:6, #13 +Counter in file 0 54:6 -> 54:7, ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13) +Counter in file 0 56:8 -> 56:15, (#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) +Counter in file 0 56:16 -> 58:6, #14 +Counter in file 0 58:12 -> 60:6, ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14) +Counter in file 0 61:1 -> 61:2, (#14 + ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14)) Emitting segments for file: ../coverage/lazy_boolean.rs Combined regions: 7:9 -> 9:42 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt index 7cde2205cbfd4..171b77c9cc749 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt @@ -1,12 +1,12 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches Counter in file 0 10:12 -> 10:16, #1 Counter in file 0 11:16 -> 11:21, #2 -Counter in file 0 14:14 -> 14:15, #6 -Counter in file 0 15:13 -> 15:31, #7 -Counter in file 0 15:31 -> 15:32, #8 -Counter in file 0 17:10 -> 17:11, #10 -Counter in file 0 18:9 -> 18:15, #11 -Counter in file 0 19:5 -> 19:6, #12 +Counter in file 0 14:14 -> 14:15, (#2 - #5) +Counter in file 0 15:13 -> 15:31, (0 + (#2 - #5)) +Counter in file 0 15:31 -> 15:32, #4 +Counter in file 0 17:10 -> 17:11, #3 +Counter in file 0 18:9 -> 18:15, (#3 + 0) +Counter in file 0 19:5 -> 19:6, (#4 + (#3 + 0)) Counter in file 0 22:11 -> 25:2, #1 Emitting segments for file: ../coverage/loops_and_branches.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt index 59fb5c366f2cb..ac376c4f36a40 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt @@ -1,22 +1,22 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops Counter in file 0 2:9 -> 3:27, #1 -Counter in file 0 5:19 -> 5:32, #2 -Counter in file 0 6:13 -> 7:24, #3 -Counter in file 0 8:13 -> 8:14, #4 -Counter in file 0 8:18 -> 8:23, #5 -Counter in file 0 9:16 -> 9:22, (#4 + 0) -Counter in file 0 10:17 -> 10:22, #6 -Counter in file 0 12:13 -> 12:19, #7 -Counter in file 0 13:13 -> 13:19, #8 -Counter in file 0 14:16 -> 14:22, (#8 + 0) -Counter in file 0 15:17 -> 16:27, #9 -Counter in file 0 17:21 -> 17:33, #10 -Counter in file 0 19:21 -> 21:14, #11 -Counter in file 0 21:14 -> 21:15, #12 -Counter in file 0 22:10 -> 22:11, #13 -Counter in file 0 23:9 -> 23:23, #14 -Counter in file 0 24:6 -> 24:7, #15 -Counter in file 0 25:1 -> 25:2, #16 +Counter in file 0 5:19 -> 5:32, (#1 + #2) +Counter in file 0 6:13 -> 7:24, ((#1 + #2) - #3) +Counter in file 0 8:13 -> 8:14, ((((#1 + #2) - #3) + (#5 + #6)) - #7) +Counter in file 0 8:18 -> 8:23, (((#1 + #2) - #3) + (#5 + #6)) +Counter in file 0 9:16 -> 9:22, (((((#1 + #2) - #3) + (#5 + #6)) - #7) + 0) +Counter in file 0 10:17 -> 10:22, #8 +Counter in file 0 12:13 -> 12:19, #9 +Counter in file 0 13:13 -> 13:19, #10 +Counter in file 0 14:16 -> 14:22, (#10 + 0) +Counter in file 0 15:17 -> 16:27, #11 +Counter in file 0 17:21 -> 17:33, #4 +Counter in file 0 19:21 -> 21:14, #5 +Counter in file 0 21:14 -> 21:15, #6 +Counter in file 0 22:10 -> 22:11, (#5 + #6) +Counter in file 0 23:9 -> 23:23, #2 +Counter in file 0 24:6 -> 24:7, #3 +Counter in file 0 25:1 -> 25:2, (#4 + #3) Emitting segments for file: ../coverage/nested_loops.rs Combined regions: 2:9 -> 3:27 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt index d828e40ca3fa6..148768f423ba0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt @@ -2,12 +2,12 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 12:9 -> 12:16, (#1 + 0) Counter in file 0 13:5 -> 18:6, #2 -Counter in file 0 18:6 -> 18:7, #3 -Counter in file 0 23:13 -> 25:14, #4 -Counter in file 0 27:13 -> 27:18, #5 -Counter in file 0 30:9 -> 32:10, #6 -Counter in file 0 34:6 -> 34:7, #7 -Counter in file 0 35:1 -> 35:2, (#5 + 0) +Counter in file 0 18:6 -> 18:7, (#1 - #2) +Counter in file 0 23:13 -> 25:14, ((#2 + (#1 - #2)) + #3) +Counter in file 0 27:13 -> 27:18, #4 +Counter in file 0 30:9 -> 32:10, #3 +Counter in file 0 34:6 -> 34:7, (#2 + (#1 - #2)) +Counter in file 0 35:1 -> 35:2, (#4 + 0) Emitting segments for file: ../coverage/simple_loop.rs Combined regions: 7:9 -> 9:26 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt index e7932e0be0473..2a3c004fa7abe 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt @@ -2,18 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, #3 -Counter in file 0 15:9 -> 15:10, #4 -Counter in file 0 17:9 -> 17:13, #5 -Counter in file 0 22:13 -> 22:22, (#4 + 0) -Counter in file 0 24:13 -> 24:14, #6 -Counter in file 0 26:17 -> 28:18, (#4 + 0) -Counter in file 0 28:18 -> 28:19, #7 -Counter in file 0 30:13 -> 37:14, (#6 + 0) -Counter in file 0 40:13 -> 40:15, #8 -Counter in file 0 42:6 -> 42:7, #9 -Counter in file 0 42:6 -> 42:7, #10 -Counter in file 0 43:1 -> 43:2, #11 +Counter in file 0 12:6 -> 12:7, (#1 - #2) +Counter in file 0 15:9 -> 15:10, (((#2 + (#1 - #2)) + (#3 + #4)) - #5) +Counter in file 0 17:9 -> 17:13, ((#2 + (#1 - #2)) + (#3 + #4)) +Counter in file 0 22:13 -> 22:22, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) +Counter in file 0 24:13 -> 24:14, #3 +Counter in file 0 26:17 -> 28:18, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) +Counter in file 0 28:18 -> 28:19, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) - #3) +Counter in file 0 30:13 -> 37:14, (#3 + 0) +Counter in file 0 40:13 -> 40:15, #4 +Counter in file 0 42:6 -> 42:7, (#2 + (#1 - #2)) +Counter in file 0 42:6 -> 42:7, (#3 + #4) +Counter in file 0 43:1 -> 43:2, #5 Emitting segments for file: ../coverage/simple_match.rs Combined regions: 7:9 -> 9:26 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt index a690874e3c007..5180ddd7de669 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt @@ -1,6 +1,6 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop Counter in file 0 2:8 -> 2:13, #1 -Counter in file 0 5:1 -> 5:2, #4 +Counter in file 0 5:1 -> 5:2, (#1 - #2) Emitting segments for file: ../coverage/tight_infinite_loop.rs Combined regions: 2:8 -> 2:13 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt index 7dea637551db4..30109a1e20020 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt @@ -1,22 +1,21 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result Counter in file 0 13:9 -> 14:23, #1 -Counter in file 0 17:9 -> 17:10, #2 -Counter in file 0 19:9 -> 19:14, #3 -Counter in file 0 21:9 -> 25:26, #4 -Counter in file 0 27:13 -> 27:41, #5 -Counter in file 0 27:41 -> 27:42, #6 -Counter in file 0 31:13 -> 31:42, #7 -Counter in file 0 31:42 -> 31:43, #8 -Counter in file 0 32:10 -> 32:11, #9 -Counter in file 0 32:10 -> 32:11, #10 -Counter in file 0 33:6 -> 33:7, #11 -Counter in file 0 34:5 -> 34:11, #12 -Counter in file 0 35:1 -> 35:2, #13 -Counter in file 0 35:1 -> 35:2, #14 +Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) +Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) +Counter in file 0 21:9 -> 25:26, #7 +Counter in file 0 27:13 -> 27:41, #8 +Counter in file 0 27:41 -> 27:42, #5 +Counter in file 0 31:13 -> 31:42, (#7 - #8) +Counter in file 0 31:42 -> 31:43, #6 +Counter in file 0 32:10 -> 32:11, #2 +Counter in file 0 32:10 -> 32:11, #3 +Counter in file 0 33:6 -> 33:7, (#2 + #3) +Counter in file 0 34:5 -> 34:11, #4 +Counter in file 0 35:1 -> 35:2, ((#5 + #6) + #4) Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 -Counter in file 0 8:9 -> 8:15, #3 -Counter in file 0 10:1 -> 10:2, #4 +Counter in file 0 8:9 -> 8:15, (#1 - #2) +Counter in file 0 10:1 -> 10:2, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/try_error_result.rs Combined regions: 5:8 -> 5:20 (count=6) @@ -34,7 +33,7 @@ Combined regions: 32:10 -> 32:11 (count=5) 33:6 -> 33:7 (count=5) 34:5 -> 34:11 (count=0) - 35:1 -> 35:2 (count=2) + 35:1 -> 35:2 (count=1) Segment at 5:8 (count = 6), RegionEntry Segment at 5:20 (count = 0), Skipped Segment at 6:9 (count = 1), RegionEntry @@ -63,5 +62,5 @@ Segment at 33:6 (count = 5), RegionEntry Segment at 33:7 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry Segment at 34:11 (count = 0), Skipped -Segment at 35:1 (count = 2), RegionEntry +Segment at 35:1 (count = 1), RegionEntry Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt index 0fb135b2cc994..b229410a495a3 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt @@ -2,73 +2,72 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 4:9 -> 4:26, #1 Counter in file 0 5:8 -> 5:12, (#1 + 0) Counter in file 0 5:13 -> 7:6, #2 -Counter in file 0 10:9 -> 10:10, #4 -Counter in file 0 10:16 -> 10:29, #5 -Counter in file 0 11:9 -> 12:10, #6 -Counter in file 0 13:15 -> 13:28, #7 -Counter in file 0 14:12 -> 14:25, #8 -Counter in file 0 14:29 -> 14:42, #9 -Counter in file 0 14:42 -> 14:43, #10 -Counter in file 0 14:42 -> 14:43, #11 -Counter in file 0 14:46 -> 14:60, #12 -Counter in file 0 14:60 -> 14:61, #13 -Counter in file 0 14:60 -> 14:61, #14 -Counter in file 0 14:61 -> 16:10, #15 -Counter in file 0 16:10 -> 16:11, #16 -Counter in file 0 17:9 -> 18:18, #17 -Counter in file 0 20:9 -> 20:15, #18 -Counter in file 0 23:9 -> 23:26, (#4 + 0) -Counter in file 0 24:8 -> 24:12, (#4 + 0) -Counter in file 0 24:13 -> 26:6, #19 -Counter in file 0 28:8 -> 28:21, #21 -Counter in file 0 29:9 -> 29:23, #22 -Counter in file 0 30:15 -> 30:28, #23 -Counter in file 0 31:12 -> 31:25, #24 -Counter in file 0 31:29 -> 31:42, #25 -Counter in file 0 31:42 -> 31:43, #26 -Counter in file 0 31:42 -> 31:43, #27 -Counter in file 0 31:46 -> 31:60, #28 -Counter in file 0 31:60 -> 31:61, #29 -Counter in file 0 31:60 -> 31:61, #30 -Counter in file 0 31:61 -> 33:10, #31 -Counter in file 0 33:10 -> 33:11, #32 -Counter in file 0 34:9 -> 34:23, #33 -Counter in file 0 36:9 -> 36:15, #34 -Counter in file 0 39:9 -> 39:26, #35 -Counter in file 0 40:8 -> 40:12, (#35 + 0) -Counter in file 0 40:13 -> 42:6, #36 -Counter in file 0 44:9 -> 44:10, #38 -Counter in file 0 44:16 -> 44:29, #39 -Counter in file 0 45:9 -> 45:23, #40 -Counter in file 0 46:15 -> 46:28, #41 -Counter in file 0 47:12 -> 47:25, #42 -Counter in file 0 47:29 -> 47:42, #43 -Counter in file 0 47:42 -> 47:43, #44 -Counter in file 0 47:42 -> 47:43, #45 -Counter in file 0 47:46 -> 47:60, #46 -Counter in file 0 47:60 -> 47:61, #47 -Counter in file 0 47:60 -> 47:61, #48 -Counter in file 0 47:61 -> 49:10, #49 -Counter in file 0 49:10 -> 49:11, #50 -Counter in file 0 50:9 -> 50:23, #51 -Counter in file 0 52:13 -> 54:15, #52 -Counter in file 0 57:9 -> 57:10, #53 -Counter in file 0 57:16 -> 57:29, (#38 + 0) -Counter in file 0 58:9 -> 58:23, #54 -Counter in file 0 59:15 -> 59:28, #55 -Counter in file 0 60:12 -> 60:25, #56 -Counter in file 0 60:29 -> 60:42, #57 -Counter in file 0 60:42 -> 60:43, #58 -Counter in file 0 60:42 -> 60:43, #59 -Counter in file 0 60:46 -> 60:60, #60 -Counter in file 0 60:60 -> 60:61, #61 -Counter in file 0 60:60 -> 60:61, #62 -Counter in file 0 60:61 -> 62:10, #63 -Counter in file 0 62:10 -> 62:11, #64 -Counter in file 0 63:9 -> 63:23, #65 -Counter in file 0 65:9 -> 65:15, #66 -Counter in file 0 67:1 -> 67:2, #67 -Counter in file 0 67:1 -> 67:2, #68 +Counter in file 0 10:9 -> 10:10, (#4 + #11) +Counter in file 0 10:16 -> 10:29, (#2 + 0) +Counter in file 0 11:9 -> 12:10, #4 +Counter in file 0 13:15 -> 13:28, ((#2 + 0) - #3) +Counter in file 0 14:12 -> 14:25, #5 +Counter in file 0 14:29 -> 14:42, (#5 - #13) +Counter in file 0 14:42 -> 14:43, (#13 + #14) +Counter in file 0 14:42 -> 14:43, ((#5 - #13) - #14) +Counter in file 0 14:46 -> 14:60, #21 +Counter in file 0 14:60 -> 14:61, (#17 + #18) +Counter in file 0 14:60 -> 14:61, (#21 - #18) +Counter in file 0 14:61 -> 16:10, #22 +Counter in file 0 16:10 -> 16:11, #23 +Counter in file 0 17:9 -> 18:18, #11 +Counter in file 0 20:9 -> 20:15, (((#2 + 0) - #3) - #5) +Counter in file 0 23:9 -> 23:26, ((#4 + #11) + 0) +Counter in file 0 24:8 -> 24:12, ((#4 + #11) + 0) +Counter in file 0 24:13 -> 26:6, #12 +Counter in file 0 28:8 -> 28:21, (#12 + 0) +Counter in file 0 29:9 -> 29:23, #16 +Counter in file 0 30:15 -> 30:28, ((#12 + 0) - #15) +Counter in file 0 31:12 -> 31:25, (((#12 + 0) - #15) - #8) +Counter in file 0 31:29 -> 31:42, ((((#12 + 0) - #15) - #8) - #24) +Counter in file 0 31:42 -> 31:43, (((((#12 + 0) - #15) - #8) - #24) - #25) +Counter in file 0 31:42 -> 31:43, (#24 + #25) +Counter in file 0 31:46 -> 31:60, #32 +Counter in file 0 31:60 -> 31:61, (#28 + #29) +Counter in file 0 31:60 -> 31:61, (#32 - #29) +Counter in file 0 31:61 -> 33:10, #33 +Counter in file 0 33:10 -> 33:11, #34 +Counter in file 0 34:9 -> 34:23, #19 +Counter in file 0 36:9 -> 36:15, #8 +Counter in file 0 39:9 -> 39:26, (#16 + #19) +Counter in file 0 40:8 -> 40:12, ((#16 + #19) + 0) +Counter in file 0 40:13 -> 42:6, #20 +Counter in file 0 44:9 -> 44:10, (#27 + #30) +Counter in file 0 44:16 -> 44:29, (#20 + 0) +Counter in file 0 45:9 -> 45:23, #27 +Counter in file 0 46:15 -> 46:28, ((#20 + 0) - #26) +Counter in file 0 47:12 -> 47:25, (((#20 + 0) - #26) - #7) +Counter in file 0 47:29 -> 47:42, ((((#20 + 0) - #26) - #7) - #35) +Counter in file 0 47:42 -> 47:43, (#35 + #36) +Counter in file 0 47:42 -> 47:43, (((((#20 + 0) - #26) - #7) - #35) - #36) +Counter in file 0 47:46 -> 47:60, #41 +Counter in file 0 47:60 -> 47:61, (#37 + #38) +Counter in file 0 47:60 -> 47:61, (#41 - #38) +Counter in file 0 47:61 -> 49:10, #42 +Counter in file 0 49:10 -> 49:11, #43 +Counter in file 0 50:9 -> 50:23, #30 +Counter in file 0 52:13 -> 54:15, #7 +Counter in file 0 57:9 -> 57:10, (#9 + #10) +Counter in file 0 57:16 -> 57:29, ((#27 + #30) + 0) +Counter in file 0 58:9 -> 58:23, #9 +Counter in file 0 59:15 -> 59:28, ((#27 + #30) - #31) +Counter in file 0 60:12 -> 60:25, (((#27 + #30) - #31) - #6) +Counter in file 0 60:29 -> 60:42, ((((#27 + #30) - #31) - #6) - #39) +Counter in file 0 60:42 -> 60:43, (#39 + #40) +Counter in file 0 60:42 -> 60:43, (((((#27 + #30) - #31) - #6) - #39) - #40) +Counter in file 0 60:46 -> 60:60, #46 +Counter in file 0 60:60 -> 60:61, (#46 - #45) +Counter in file 0 60:60 -> 60:61, (#44 + #45) +Counter in file 0 60:61 -> 62:10, #47 +Counter in file 0 62:10 -> 62:11, #48 +Counter in file 0 63:9 -> 63:23, #10 +Counter in file 0 65:9 -> 65:15, #6 +Counter in file 0 67:1 -> 67:2, ((#9 + #10) + (((#6 + #7) + #8) + (((#2 + 0) - #3) - #5))) Emitting segments for file: ../coverage/various_conditions.rs Combined regions: 4:9 -> 4:26 (count=1) @@ -131,7 +130,7 @@ Combined regions: 62:10 -> 62:11 (count=0) 63:9 -> 63:23 (count=0) 65:9 -> 65:15 (count=0) - 67:1 -> 67:2 (count=2) + 67:1 -> 67:2 (count=1) Segment at 4:9 (count = 1), RegionEntry Segment at 4:26 (count = 0), Skipped Segment at 5:8 (count = 1), RegionEntry @@ -236,5 +235,5 @@ Segment at 63:9 (count = 0), RegionEntry Segment at 63:23 (count = 0), Skipped Segment at 65:9 (count = 0), RegionEntry Segment at 65:15 (count = 0), Skipped -Segment at 67:1 (count = 2), RegionEntry +Segment at 67:1 (count = 1), RegionEntry Segment at 67:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt index a2be958660eda..d496805955f78 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt @@ -1,8 +1,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while Counter in file 0 2:9 -> 2:16, #1 -Counter in file 0 3:11 -> 3:20, #2 -Counter in file 0 3:21 -> 4:6, #3 -Counter in file 0 5:1 -> 5:2, #4 +Counter in file 0 3:11 -> 3:20, (#1 + #2) +Counter in file 0 3:21 -> 4:6, #2 +Counter in file 0 5:1 -> 5:2, ((#1 + #2) - #2) Emitting segments for file: ../coverage/while.rs Combined regions: 2:9 -> 2:16 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt index 02ab24050bad5..a343f5056ac29 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt @@ -1,14 +1,13 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return Counter in file 0 5:9 -> 5:27, #1 -Counter in file 0 7:9 -> 9:10, #2 -Counter in file 0 12:13 -> 14:14, #3 -Counter in file 0 18:21 -> 20:22, #4 -Counter in file 0 22:21 -> 22:27, #5 -Counter in file 0 26:21 -> 26:27, #6 -Counter in file 0 30:9 -> 32:10, #7 -Counter in file 0 35:5 -> 35:11, #8 -Counter in file 0 36:1 -> 36:2, #9 -Counter in file 0 36:1 -> 36:2, #10 +Counter in file 0 7:9 -> 9:10, (#1 + #2) +Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3) +Counter in file 0 18:21 -> 20:22, #6 +Counter in file 0 22:21 -> 22:27, #4 +Counter in file 0 26:21 -> 26:27, #5 +Counter in file 0 30:9 -> 32:10, #2 +Counter in file 0 35:5 -> 35:11, #3 +Counter in file 0 36:1 -> 36:2, ((#4 + #5) + #3) Emitting segments for file: ../coverage/while_early_return.rs Combined regions: 5:9 -> 5:27 (count=1) @@ -19,7 +18,7 @@ Combined regions: 26:21 -> 26:27 (count=1) 30:9 -> 32:10 (count=6) 35:5 -> 35:11 (count=0) - 36:1 -> 36:2 (count=2) + 36:1 -> 36:2 (count=1) Segment at 5:9 (count = 1), RegionEntry Segment at 5:27 (count = 0), Skipped Segment at 7:9 (count = 7), RegionEntry @@ -36,5 +35,5 @@ Segment at 30:9 (count = 6), RegionEntry Segment at 32:10 (count = 0), Skipped Segment at 35:5 (count = 0), RegionEntry Segment at 35:11 (count = 0), Skipped -Segment at 36:1 (count = 2), RegionEntry +Segment at 36:1 (count = 1), RegionEntry Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json index 7a7e4c04f0018..bd2e2d56d4a55 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.drop_trait.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 5, + "covered": 5, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 6, - "covered": 6, + "count": 5, + "covered": 5, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json index 1025cd3de80d2..a50f4657e20aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.generics.json @@ -21,8 +21,8 @@ "percent": 100 }, "regions": { - "count": 7, - "covered": 7, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } @@ -46,8 +46,8 @@ "percent": 100 }, "regions": { - "count": 7, - "covered": 7, + "count": 6, + "covered": 6, "notcovered": 0, "percent": 100 } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json index 2d2ad1dbe3f71..36f81ceae19bf 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.if_else.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 29, - "covered": 21, - "percent": 72.41379310344827 + "count": 28, + "covered": 19, + "percent": 67.85714285714286 }, "regions": { - "count": 9, - "covered": 7, + "count": 7, + "covered": 5, "notcovered": 2, - "percent": 77.77777777777779 + "percent": 71.42857142857143 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 29, - "covered": 21, - "percent": 72.41379310344827 + "count": 28, + "covered": 19, + "percent": 67.85714285714286 }, "regions": { - "count": 9, - "covered": 7, + "count": 7, + "covered": 5, "notcovered": 2, - "percent": 77.77777777777779 + "percent": 71.42857142857143 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json index 39e17359eee76..929e769b50a98 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json @@ -21,10 +21,10 @@ "percent": 94.73684210526315 }, "regions": { - "count": 18, - "covered": 15, + "count": 17, + "covered": 14, "notcovered": 3, - "percent": 83.33333333333334 + "percent": 82.35294117647058 } } } @@ -46,10 +46,10 @@ "percent": 94.73684210526315 }, "regions": { - "count": 18, - "covered": 15, + "count": 17, + "covered": 14, "notcovered": 3, - "percent": 83.33333333333334 + "percent": 82.35294117647058 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json index 464bb614ea1b1..d93458b614372 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.various_conditions.json @@ -21,10 +21,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 70, - "covered": 19, + "count": 69, + "covered": 18, "notcovered": 51, - "percent": 27.142857142857142 + "percent": 26.08695652173913 } } } @@ -46,10 +46,10 @@ "percent": 46.93877551020408 }, "regions": { - "count": 70, - "covered": 19, + "count": 69, + "covered": 18, "notcovered": 51, - "percent": 27.142857142857142 + "percent": 26.08695652173913 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json index a116a91a60aae..a9e01604ccd5b 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.while_early_return.json @@ -21,10 +21,10 @@ "percent": 88.23529411764706 }, "regions": { - "count": 10, - "covered": 8, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 80 + "percent": 77.77777777777779 } } } @@ -46,10 +46,10 @@ "percent": 88.23529411764706 }, "regions": { - "count": 10, - "covered": 8, + "count": 9, + "covered": 7, "notcovered": 2, - "percent": 80 + "percent": 77.77777777777779 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt index 43592df1059aa..72aa020ca1691 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.drop_trait.txt @@ -24,7 +24,7 @@ 24| | let _ = Firework { strength: 1000 }; 25| | 26| | Ok(()) - 27| 2|} + 27| 1|} 28| | 29| |// Expected program output: 30| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt index 11dc0aa65e2d1..86199d7476302 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.generics.txt @@ -57,7 +57,7 @@ 35| | let _ = Firework { strength: 1000 }; 36| | 37| | Ok(()) - 38| 2|} + 38| 1|} 39| | 40| |// Expected program output: 41| |// Exiting with error... diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt index 64cbc262521bf..5f899723e2554 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.if_else.txt @@ -20,7 +20,7 @@ 20| 0| countdown 21| 0| = 22| 0| 100 - 23| 1| } + 23| | } 24| | 25| | if 26| 1| is_true @@ -36,6 +36,6 @@ 36| 0| = 37| 0| 100 38| 0| ; - 39| 1| } + 39| 0| } 40| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt index c43b492db6057..94c63c9a2b906 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt @@ -33,5 +33,5 @@ 32| 5| } 33| 5| } 34| 0| Ok(()) - 35| 2|} + 35| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt index e0efe75043d4a..173ff4aa4c481 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.various_conditions.txt @@ -65,5 +65,5 @@ 64| | } else { 65| 0| return; 66| | }; - 67| 2|} + 67| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt index e5c5b05a6fc80..26041136d2f4c 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.while_early_return.txt @@ -33,7 +33,7 @@ 33| | ; 34| | } 35| 0| Ok(()) - 36| 2|} + 36| 1|} 37| | 38| |// ISSUE(77553): Originally, this test had `Err(1)` on line 22 (instead of `Ok(())`) and 39| |// `std::process::exit(2)` on line 26 (instead of `Err(1)`); and this worked as expected on Linux diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt index 39bf7bad9a1a2..d443ba0aba3a0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt @@ -2,8 +2,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 20:21 -> 20:38, #1 Counter in file 0 21:20 -> 21:28, (#1 + 0) Counter in file 0 21:29 -> 23:18, #2 -Counter in file 0 23:18 -> 23:19, #3 -Counter in file 0 24:17 -> 25:14, #4 +Counter in file 0 23:18 -> 23:19, (#1 - #2) +Counter in file 0 24:17 -> 25:14, (#2 + (#1 - #2)) Counter in file 0 3:11 -> 18:13, #1 Counter in file 0 25:14 -> 33:9, (#1 + 0) Counter in file 0 40:6 -> 60:13, (#1 + 0) @@ -12,18 +12,18 @@ Counter in file 0 82:6 -> 93:2, (#1 + 0) Counter in file 0 77:13 -> 77:30, #1 Counter in file 0 78:12 -> 78:20, (#1 + 0) Counter in file 0 78:21 -> 80:10, #2 -Counter in file 0 80:10 -> 80:11, #3 -Counter in file 0 81:9 -> 82:6, #4 +Counter in file 0 80:10 -> 80:11, (#1 - #2) +Counter in file 0 81:9 -> 82:6, (#2 + (#1 - #2)) Counter in file 0 62:21 -> 62:38, #1 Counter in file 0 63:20 -> 63:28, (#1 + 0) Counter in file 0 63:29 -> 65:18, #2 -Counter in file 0 65:18 -> 65:19, #3 -Counter in file 0 66:17 -> 67:14, #4 +Counter in file 0 65:18 -> 65:19, (#1 - #2) +Counter in file 0 66:17 -> 67:14, (#2 + (#1 - #2)) Counter in file 0 35:13 -> 35:30, #1 Counter in file 0 36:12 -> 36:20, (#1 + 0) Counter in file 0 36:21 -> 38:10, #2 -Counter in file 0 38:10 -> 38:11, #3 -Counter in file 0 39:9 -> 40:6, #4 +Counter in file 0 38:10 -> 38:11, (#1 - #2) +Counter in file 0 39:9 -> 40:6, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/closure.rs Combined regions: 3:11 -> 18:13 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt index 124a01af34212..08fbbd13adbe1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt @@ -3,7 +3,7 @@ Counter in file 0 9:24 -> 11:6, #1 Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) Counter in file 0 20:9 -> 21:22, #2 -Counter in file 0 27:1 -> 27:2, #4 +Counter in file 0 27:1 -> 27:2, (#2 + 0) Emitting segments for file: ../coverage/drop_trait.rs Combined regions: 9:24 -> 11:6 (count=2) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt index a0e9146035eec..eb707c5e7acc2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt @@ -4,7 +4,7 @@ Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 23:9 -> 28:28, #1 Counter in file 0 30:8 -> 30:12, (#1 + 0) Counter in file 0 31:9 -> 32:22, #2 -Counter in file 0 38:1 -> 38:2, #4 +Counter in file 0 38:1 -> 38:2, (#2 + 0) Counter in file 0 10:49 -> 12:6, #1 Counter in file 0 10:49 -> 12:6, #1 Emitting segments for file: ../coverage/generics.rs diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt index 325e6985e3041..d186f440ddb1f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt @@ -2,8 +2,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 8:5 -> 18:10, #1 Counter in file 0 21:9 -> 21:16, (#1 + 0) Counter in file 0 22:5 -> 27:6, #2 -Counter in file 0 27:6 -> 27:7, #3 -Counter in file 0 28:1 -> 28:2, #4 +Counter in file 0 27:6 -> 27:7, (#1 - #2) +Counter in file 0 28:1 -> 28:2, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/if.rs Combined regions: 8:5 -> 18:10 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt index 9406b6a269d4a..8220060f26ff2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt @@ -1,11 +1,11 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 -Counter in file 0 20:9 -> 22:16, #3 -Counter in file 0 26:9 -> 26:16, #4 -Counter in file 0 27:5 -> 32:6, #5 -Counter in file 0 34:5 -> 39:6, #6 -Counter in file 0 40:1 -> 40:2, #7 +Counter in file 0 20:9 -> 22:16, (#1 - #2) +Counter in file 0 26:9 -> 26:16, (#2 + (#1 - #2)) +Counter in file 0 27:5 -> 32:6, #3 +Counter in file 0 34:5 -> 39:6, ((#2 + (#1 - #2)) - #3) +Counter in file 0 40:1 -> 40:2, (#3 + ((#2 + (#1 - #2)) - #3)) Emitting segments for file: ../coverage/if_else.rs Combined regions: 7:9 -> 11:16 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt index ea6db9452a75c..c173cc20f815a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt @@ -6,11 +6,11 @@ Counter in file 0 21:9 -> 22:6, (#2 + 0) Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, #3 -Counter in file 0 48:8 -> 48:15, #4 -Counter in file 0 48:16 -> 50:6, #5 -Counter in file 0 50:6 -> 50:7, #6 -Counter in file 0 52:9 -> 57:2, #7 +Counter in file 0 12:6 -> 12:7, (#1 - #2) +Counter in file 0 48:8 -> 48:15, (#2 + (#1 - #2)) +Counter in file 0 48:16 -> 50:6, #3 +Counter in file 0 50:6 -> 50:7, ((#2 + (#1 - #2)) - #3) +Counter in file 0 52:9 -> 57:2, (#3 + ((#2 + (#1 - #2)) - #3)) Counter in file 0 33:42 -> 36:10, #1 Counter in file 0 41:37 -> 41:41, #1 Counter in file 0 42:13 -> 43:10, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt index c95275c6223ba..191a3a58355d2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt @@ -2,40 +2,40 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:42, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 14:6, #2 -Counter in file 0 14:6 -> 14:7, #3 -Counter in file 0 16:9 -> 16:17, #4 -Counter in file 0 18:13 -> 18:18, #5 -Counter in file 0 20:13 -> 20:18, #6 -Counter in file 0 20:18 -> 20:19, #7 -Counter in file 0 20:18 -> 20:19, #8 -Counter in file 0 23:9 -> 23:17, #9 -Counter in file 0 25:13 -> 25:18, (#4 + 0) -Counter in file 0 27:13 -> 27:18, #10 -Counter in file 0 27:18 -> 27:19, #11 -Counter in file 0 27:18 -> 27:19, #12 -Counter in file 0 29:9 -> 29:17, #13 -Counter in file 0 29:20 -> 29:25, (#9 + 0) -Counter in file 0 29:29 -> 29:34, #14 -Counter in file 0 29:34 -> 29:35, #15 -Counter in file 0 29:34 -> 29:35, #16 -Counter in file 0 30:9 -> 30:17, #17 -Counter in file 0 30:20 -> 30:25, (#13 + 0) -Counter in file 0 30:29 -> 30:34, #18 -Counter in file 0 30:34 -> 30:35, #19 -Counter in file 0 30:34 -> 30:35, #20 -Counter in file 0 33:9 -> 34:16, (#17 + 0) -Counter in file 0 35:5 -> 38:6, #21 -Counter in file 0 38:6 -> 38:7, #22 -Counter in file 0 41:9 -> 41:16, #23 -Counter in file 0 42:5 -> 45:6, #24 -Counter in file 0 47:5 -> 50:6, #25 -Counter in file 0 52:8 -> 52:16, #26 -Counter in file 0 52:17 -> 54:6, #27 -Counter in file 0 54:6 -> 54:7, #28 -Counter in file 0 56:8 -> 56:15, #29 -Counter in file 0 56:16 -> 58:6, #30 -Counter in file 0 58:12 -> 60:6, #31 -Counter in file 0 61:1 -> 61:2, #32 +Counter in file 0 14:6 -> 14:7, (#1 - #2) +Counter in file 0 16:9 -> 16:17, ((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) +Counter in file 0 18:13 -> 18:18, (#2 + (#1 - #2)) +Counter in file 0 20:13 -> 20:18, ((#2 + (#1 - #2)) - #3) +Counter in file 0 20:18 -> 20:19, (#3 + #4) +Counter in file 0 20:18 -> 20:19, (((#2 + (#1 - #2)) - #3) - #4) +Counter in file 0 23:9 -> 23:17, ((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) +Counter in file 0 25:13 -> 25:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) + 0) +Counter in file 0 27:13 -> 27:18, (((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) +Counter in file 0 27:18 -> 27:19, (#5 + #6) +Counter in file 0 27:18 -> 27:19, ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6) +Counter in file 0 29:9 -> 29:17, ((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) +Counter in file 0 29:20 -> 29:25, (((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) + 0) +Counter in file 0 29:29 -> 29:34, #7 +Counter in file 0 29:34 -> 29:35, ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8) +Counter in file 0 29:34 -> 29:35, (#7 - #8) +Counter in file 0 30:9 -> 30:17, ((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) +Counter in file 0 30:20 -> 30:25, (((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) + 0) +Counter in file 0 30:29 -> 30:34, #9 +Counter in file 0 30:34 -> 30:35, ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10) +Counter in file 0 30:34 -> 30:35, (#9 - #10) +Counter in file 0 33:9 -> 34:16, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) + 0) +Counter in file 0 35:5 -> 38:6, #11 +Counter in file 0 38:6 -> 38:7, (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11) +Counter in file 0 41:9 -> 41:16, (#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) +Counter in file 0 42:5 -> 45:6, #12 +Counter in file 0 47:5 -> 50:6, ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12) +Counter in file 0 52:8 -> 52:16, (#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) +Counter in file 0 52:17 -> 54:6, #13 +Counter in file 0 54:6 -> 54:7, ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13) +Counter in file 0 56:8 -> 56:15, (#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) +Counter in file 0 56:16 -> 58:6, #14 +Counter in file 0 58:12 -> 60:6, ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14) +Counter in file 0 61:1 -> 61:2, (#14 + ((#13 + ((#12 + ((#11 + (((#9 - #10) + ((((#7 - #8) + ((((#5 + #6) + ((((#3 + #4) + (((#2 + (#1 - #2)) - #3) - #4)) - #5) - #6)) - #7) + #8)) - #9) + #10)) - #11)) - #12)) - #13)) - #14)) Emitting segments for file: ../coverage/lazy_boolean.rs Combined regions: 7:9 -> 9:42 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt index 3e0bc6e495929..235557ba3495c 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt @@ -1,12 +1,12 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches Counter in file 0 10:12 -> 10:16, #1 Counter in file 0 11:16 -> 11:21, #2 -Counter in file 0 14:14 -> 14:15, #6 -Counter in file 0 15:13 -> 15:31, #7 -Counter in file 0 15:31 -> 15:32, #8 -Counter in file 0 17:10 -> 17:11, #10 -Counter in file 0 18:9 -> 18:15, #11 -Counter in file 0 19:5 -> 19:6, #12 +Counter in file 0 14:14 -> 14:15, (#2 - #5) +Counter in file 0 15:13 -> 15:31, (0 + (#2 - #5)) +Counter in file 0 15:31 -> 15:32, #4 +Counter in file 0 17:10 -> 17:11, #3 +Counter in file 0 18:9 -> 18:15, (#3 + 0) +Counter in file 0 19:5 -> 19:6, (#4 + (#3 + 0)) Counter in file 0 22:11 -> 25:2, #1 Emitting segments for file: ../coverage/loops_and_branches.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt index a19f625331655..6bc26f94ac7c0 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt @@ -1,22 +1,22 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops Counter in file 0 2:9 -> 3:27, #1 -Counter in file 0 5:19 -> 5:32, #2 -Counter in file 0 6:13 -> 7:24, #3 -Counter in file 0 8:13 -> 8:14, #4 -Counter in file 0 8:18 -> 8:23, #5 -Counter in file 0 9:16 -> 9:22, (#4 + 0) -Counter in file 0 10:17 -> 10:22, #6 -Counter in file 0 12:13 -> 12:19, #7 -Counter in file 0 13:13 -> 13:19, #8 -Counter in file 0 14:16 -> 14:22, (#8 + 0) -Counter in file 0 15:17 -> 16:27, #9 -Counter in file 0 17:21 -> 17:33, #10 -Counter in file 0 19:21 -> 21:14, #11 -Counter in file 0 21:14 -> 21:15, #12 -Counter in file 0 22:10 -> 22:11, #13 -Counter in file 0 23:9 -> 23:23, #14 -Counter in file 0 24:6 -> 24:7, #15 -Counter in file 0 25:1 -> 25:2, #16 +Counter in file 0 5:19 -> 5:32, (#1 + #2) +Counter in file 0 6:13 -> 7:24, ((#1 + #2) - #3) +Counter in file 0 8:13 -> 8:14, ((((#1 + #2) - #3) + (#5 + #6)) - #7) +Counter in file 0 8:18 -> 8:23, (((#1 + #2) - #3) + (#5 + #6)) +Counter in file 0 9:16 -> 9:22, (((((#1 + #2) - #3) + (#5 + #6)) - #7) + 0) +Counter in file 0 10:17 -> 10:22, #8 +Counter in file 0 12:13 -> 12:19, #9 +Counter in file 0 13:13 -> 13:19, #10 +Counter in file 0 14:16 -> 14:22, (#10 + 0) +Counter in file 0 15:17 -> 16:27, #11 +Counter in file 0 17:21 -> 17:33, #4 +Counter in file 0 19:21 -> 21:14, #5 +Counter in file 0 21:14 -> 21:15, #6 +Counter in file 0 22:10 -> 22:11, (#5 + #6) +Counter in file 0 23:9 -> 23:23, #2 +Counter in file 0 24:6 -> 24:7, #3 +Counter in file 0 25:1 -> 25:2, (#4 + #3) Emitting segments for file: ../coverage/nested_loops.rs Combined regions: 2:9 -> 3:27 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt index a444ea4490175..5ab9a99d6868f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -1,8 +1,5 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region -Counter in file 0 4:39 -> 4:49, #1 -Counter in file 0 4:39 -> 4:49, #2 -Counter in file 0 4:39 -> 4:49, #3 -Counter in file 0 4:48 -> 4:49, #4 +Counter in file 0 4:48 -> 4:49, ((#1 + #2) + ((#3 + #4) + ((#5 + #6) + #7))) Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 21:11 -> 26:2, #1 Counter in file 0 4:39 -> 4:40, #1 @@ -11,15 +8,8 @@ Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) -Counter in file 0 4:24 -> 4:33, #1 -Counter in file 0 4:24 -> 4:33, #2 -Counter in file 0 4:24 -> 4:33, #3 -Counter in file 0 4:24 -> 4:33, #4 -Counter in file 0 4:32 -> 4:33, #5 -Counter in file 0 4:51 -> 4:54, #1 -Counter in file 0 4:51 -> 4:54, #2 -Counter in file 0 4:51 -> 4:54, #3 -Counter in file 0 4:53 -> 4:54, #4 +Counter in file 0 4:32 -> 4:33, ((#4 + #5) + #6) +Counter in file 0 4:53 -> 4:54, (#1 + (#2 + (#3 + #4))) Counter in file 0 13:9 -> 18:6, #1 Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 4:39 -> 4:40, #1 @@ -33,9 +23,7 @@ Counter in file 0 4:17 -> 4:22, #1 Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) -Counter in file 0 4:24 -> 4:33, #1 -Counter in file 0 4:24 -> 4:33, #2 -Counter in file 0 4:32 -> 4:33, #3 +Counter in file 0 4:32 -> 4:33, (#3 + (#1 + #2)) Emitting segments for file: ../coverage/partial_eq_counter_without_region.rs Combined regions: 4:17 -> 4:22 (count=2) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt index 90e09099dcc4f..60d861e9d2e15 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt @@ -2,12 +2,12 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 12:9 -> 12:16, (#1 + 0) Counter in file 0 13:5 -> 18:6, #2 -Counter in file 0 18:6 -> 18:7, #3 -Counter in file 0 23:13 -> 25:14, #4 -Counter in file 0 27:13 -> 27:18, #5 -Counter in file 0 30:9 -> 32:10, #6 -Counter in file 0 34:6 -> 34:7, #7 -Counter in file 0 35:1 -> 35:2, (#5 + 0) +Counter in file 0 18:6 -> 18:7, (#1 - #2) +Counter in file 0 23:13 -> 25:14, ((#2 + (#1 - #2)) + #3) +Counter in file 0 27:13 -> 27:18, #4 +Counter in file 0 30:9 -> 32:10, #3 +Counter in file 0 34:6 -> 34:7, (#2 + (#1 - #2)) +Counter in file 0 35:1 -> 35:2, (#4 + 0) Emitting segments for file: ../coverage/simple_loop.rs Combined regions: 7:9 -> 9:26 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt index 39a986332cd9f..1683b68e96641 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt @@ -2,18 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 -Counter in file 0 12:6 -> 12:7, #3 -Counter in file 0 15:9 -> 15:10, #4 -Counter in file 0 17:9 -> 17:13, #5 -Counter in file 0 22:13 -> 22:22, (#4 + 0) -Counter in file 0 24:13 -> 24:14, #6 -Counter in file 0 26:17 -> 28:18, (#4 + 0) -Counter in file 0 28:18 -> 28:19, #7 -Counter in file 0 30:13 -> 37:14, (#6 + 0) -Counter in file 0 40:13 -> 40:15, #8 -Counter in file 0 42:6 -> 42:7, #9 -Counter in file 0 42:6 -> 42:7, #10 -Counter in file 0 43:1 -> 43:2, #11 +Counter in file 0 12:6 -> 12:7, (#1 - #2) +Counter in file 0 15:9 -> 15:10, (((#2 + (#1 - #2)) + (#3 + #4)) - #5) +Counter in file 0 17:9 -> 17:13, ((#2 + (#1 - #2)) + (#3 + #4)) +Counter in file 0 22:13 -> 22:22, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) +Counter in file 0 24:13 -> 24:14, #3 +Counter in file 0 26:17 -> 28:18, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) + 0) +Counter in file 0 28:18 -> 28:19, ((((#2 + (#1 - #2)) + (#3 + #4)) - #5) - #3) +Counter in file 0 30:13 -> 37:14, (#3 + 0) +Counter in file 0 40:13 -> 40:15, #4 +Counter in file 0 42:6 -> 42:7, (#2 + (#1 - #2)) +Counter in file 0 42:6 -> 42:7, (#3 + #4) +Counter in file 0 43:1 -> 43:2, #5 Emitting segments for file: ../coverage/simple_match.rs Combined regions: 7:9 -> 9:26 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt index a0687815fb967..39a3cf5458c64 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt @@ -1,6 +1,6 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop Counter in file 0 2:8 -> 2:13, #1 -Counter in file 0 5:1 -> 5:2, #4 +Counter in file 0 5:1 -> 5:2, (#1 - #2) Emitting segments for file: ../coverage/tight_infinite_loop.rs Combined regions: 2:8 -> 2:13 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt index 25e1c8930bca8..9cfc05e874a51 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt @@ -1,22 +1,21 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result Counter in file 0 13:9 -> 14:23, #1 -Counter in file 0 17:9 -> 17:10, #2 -Counter in file 0 19:9 -> 19:14, #3 -Counter in file 0 21:9 -> 25:26, #4 -Counter in file 0 27:13 -> 27:41, #5 -Counter in file 0 27:41 -> 27:42, #6 -Counter in file 0 31:13 -> 31:42, #7 -Counter in file 0 31:42 -> 31:43, #8 -Counter in file 0 32:10 -> 32:11, #9 -Counter in file 0 32:10 -> 32:11, #10 -Counter in file 0 33:6 -> 33:7, #11 -Counter in file 0 34:5 -> 34:11, #12 -Counter in file 0 35:1 -> 35:2, #13 -Counter in file 0 35:1 -> 35:2, #14 +Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) +Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) +Counter in file 0 21:9 -> 25:26, #7 +Counter in file 0 27:13 -> 27:41, #8 +Counter in file 0 27:41 -> 27:42, #5 +Counter in file 0 31:13 -> 31:42, (#7 - #8) +Counter in file 0 31:42 -> 31:43, #6 +Counter in file 0 32:10 -> 32:11, #2 +Counter in file 0 32:10 -> 32:11, #3 +Counter in file 0 33:6 -> 33:7, (#2 + #3) +Counter in file 0 34:5 -> 34:11, #4 +Counter in file 0 35:1 -> 35:2, ((#5 + #6) + #4) Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 -Counter in file 0 8:9 -> 8:15, #3 -Counter in file 0 10:1 -> 10:2, #4 +Counter in file 0 8:9 -> 8:15, (#1 - #2) +Counter in file 0 10:1 -> 10:2, (#2 + (#1 - #2)) Emitting segments for file: ../coverage/try_error_result.rs Combined regions: 5:8 -> 5:20 (count=6) @@ -34,7 +33,7 @@ Combined regions: 32:10 -> 32:11 (count=5) 33:6 -> 33:7 (count=5) 34:5 -> 34:11 (count=0) - 35:1 -> 35:2 (count=2) + 35:1 -> 35:2 (count=1) Segment at 5:8 (count = 6), RegionEntry Segment at 5:20 (count = 0), Skipped Segment at 6:9 (count = 1), RegionEntry @@ -63,5 +62,5 @@ Segment at 33:6 (count = 5), RegionEntry Segment at 33:7 (count = 0), Skipped Segment at 34:5 (count = 0), RegionEntry Segment at 34:11 (count = 0), Skipped -Segment at 35:1 (count = 2), RegionEntry +Segment at 35:1 (count = 1), RegionEntry Segment at 35:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt index 567c8cd9b6df0..ba80cadbd3c8a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt @@ -2,73 +2,72 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 4:9 -> 4:26, #1 Counter in file 0 5:8 -> 5:12, (#1 + 0) Counter in file 0 5:13 -> 7:6, #2 -Counter in file 0 10:9 -> 10:10, #4 -Counter in file 0 10:16 -> 10:29, #5 -Counter in file 0 11:9 -> 12:10, #6 -Counter in file 0 13:15 -> 13:28, #7 -Counter in file 0 14:12 -> 14:25, #8 -Counter in file 0 14:29 -> 14:42, #9 -Counter in file 0 14:42 -> 14:43, #10 -Counter in file 0 14:42 -> 14:43, #11 -Counter in file 0 14:46 -> 14:60, #12 -Counter in file 0 14:60 -> 14:61, #13 -Counter in file 0 14:60 -> 14:61, #14 -Counter in file 0 14:61 -> 16:10, #15 -Counter in file 0 16:10 -> 16:11, #16 -Counter in file 0 17:9 -> 18:18, #17 -Counter in file 0 20:9 -> 20:15, #18 -Counter in file 0 23:9 -> 23:26, (#4 + 0) -Counter in file 0 24:8 -> 24:12, (#4 + 0) -Counter in file 0 24:13 -> 26:6, #19 -Counter in file 0 28:8 -> 28:21, #21 -Counter in file 0 29:9 -> 29:23, #22 -Counter in file 0 30:15 -> 30:28, #23 -Counter in file 0 31:12 -> 31:25, #24 -Counter in file 0 31:29 -> 31:42, #25 -Counter in file 0 31:42 -> 31:43, #26 -Counter in file 0 31:42 -> 31:43, #27 -Counter in file 0 31:46 -> 31:60, #28 -Counter in file 0 31:60 -> 31:61, #29 -Counter in file 0 31:60 -> 31:61, #30 -Counter in file 0 31:61 -> 33:10, #31 -Counter in file 0 33:10 -> 33:11, #32 -Counter in file 0 34:9 -> 34:23, #33 -Counter in file 0 36:9 -> 36:15, #34 -Counter in file 0 39:9 -> 39:26, #35 -Counter in file 0 40:8 -> 40:12, (#35 + 0) -Counter in file 0 40:13 -> 42:6, #36 -Counter in file 0 44:9 -> 44:10, #38 -Counter in file 0 44:16 -> 44:29, #39 -Counter in file 0 45:9 -> 45:23, #40 -Counter in file 0 46:15 -> 46:28, #41 -Counter in file 0 47:12 -> 47:25, #42 -Counter in file 0 47:29 -> 47:42, #43 -Counter in file 0 47:42 -> 47:43, #44 -Counter in file 0 47:42 -> 47:43, #45 -Counter in file 0 47:46 -> 47:60, #46 -Counter in file 0 47:60 -> 47:61, #47 -Counter in file 0 47:60 -> 47:61, #48 -Counter in file 0 47:61 -> 49:10, #49 -Counter in file 0 49:10 -> 49:11, #50 -Counter in file 0 50:9 -> 50:23, #51 -Counter in file 0 52:13 -> 54:15, #52 -Counter in file 0 57:9 -> 57:10, #53 -Counter in file 0 57:16 -> 57:29, (#38 + 0) -Counter in file 0 58:9 -> 58:23, #54 -Counter in file 0 59:15 -> 59:28, #55 -Counter in file 0 60:12 -> 60:25, #56 -Counter in file 0 60:29 -> 60:42, #57 -Counter in file 0 60:42 -> 60:43, #58 -Counter in file 0 60:42 -> 60:43, #59 -Counter in file 0 60:46 -> 60:60, #60 -Counter in file 0 60:60 -> 60:61, #61 -Counter in file 0 60:60 -> 60:61, #62 -Counter in file 0 60:61 -> 62:10, #63 -Counter in file 0 62:10 -> 62:11, #64 -Counter in file 0 63:9 -> 63:23, #65 -Counter in file 0 65:9 -> 65:15, #66 -Counter in file 0 67:1 -> 67:2, #67 -Counter in file 0 67:1 -> 67:2, #68 +Counter in file 0 10:9 -> 10:10, (#4 + #11) +Counter in file 0 10:16 -> 10:29, (#2 + 0) +Counter in file 0 11:9 -> 12:10, #4 +Counter in file 0 13:15 -> 13:28, ((#2 + 0) - #3) +Counter in file 0 14:12 -> 14:25, #5 +Counter in file 0 14:29 -> 14:42, (#5 - #13) +Counter in file 0 14:42 -> 14:43, (#13 + #14) +Counter in file 0 14:42 -> 14:43, ((#5 - #13) - #14) +Counter in file 0 14:46 -> 14:60, #21 +Counter in file 0 14:60 -> 14:61, (#17 + #18) +Counter in file 0 14:60 -> 14:61, (#21 - #18) +Counter in file 0 14:61 -> 16:10, #22 +Counter in file 0 16:10 -> 16:11, #23 +Counter in file 0 17:9 -> 18:18, #11 +Counter in file 0 20:9 -> 20:15, (((#2 + 0) - #3) - #5) +Counter in file 0 23:9 -> 23:26, ((#4 + #11) + 0) +Counter in file 0 24:8 -> 24:12, ((#4 + #11) + 0) +Counter in file 0 24:13 -> 26:6, #12 +Counter in file 0 28:8 -> 28:21, (#12 + 0) +Counter in file 0 29:9 -> 29:23, #16 +Counter in file 0 30:15 -> 30:28, ((#12 + 0) - #15) +Counter in file 0 31:12 -> 31:25, (((#12 + 0) - #15) - #8) +Counter in file 0 31:29 -> 31:42, ((((#12 + 0) - #15) - #8) - #24) +Counter in file 0 31:42 -> 31:43, (((((#12 + 0) - #15) - #8) - #24) - #25) +Counter in file 0 31:42 -> 31:43, (#24 + #25) +Counter in file 0 31:46 -> 31:60, #32 +Counter in file 0 31:60 -> 31:61, (#28 + #29) +Counter in file 0 31:60 -> 31:61, (#32 - #29) +Counter in file 0 31:61 -> 33:10, #33 +Counter in file 0 33:10 -> 33:11, #34 +Counter in file 0 34:9 -> 34:23, #19 +Counter in file 0 36:9 -> 36:15, #8 +Counter in file 0 39:9 -> 39:26, (#16 + #19) +Counter in file 0 40:8 -> 40:12, ((#16 + #19) + 0) +Counter in file 0 40:13 -> 42:6, #20 +Counter in file 0 44:9 -> 44:10, (#27 + #30) +Counter in file 0 44:16 -> 44:29, (#20 + 0) +Counter in file 0 45:9 -> 45:23, #27 +Counter in file 0 46:15 -> 46:28, ((#20 + 0) - #26) +Counter in file 0 47:12 -> 47:25, (((#20 + 0) - #26) - #7) +Counter in file 0 47:29 -> 47:42, ((((#20 + 0) - #26) - #7) - #35) +Counter in file 0 47:42 -> 47:43, (#35 + #36) +Counter in file 0 47:42 -> 47:43, (((((#20 + 0) - #26) - #7) - #35) - #36) +Counter in file 0 47:46 -> 47:60, #41 +Counter in file 0 47:60 -> 47:61, (#37 + #38) +Counter in file 0 47:60 -> 47:61, (#41 - #38) +Counter in file 0 47:61 -> 49:10, #42 +Counter in file 0 49:10 -> 49:11, #43 +Counter in file 0 50:9 -> 50:23, #30 +Counter in file 0 52:13 -> 54:15, #7 +Counter in file 0 57:9 -> 57:10, (#9 + #10) +Counter in file 0 57:16 -> 57:29, ((#27 + #30) + 0) +Counter in file 0 58:9 -> 58:23, #9 +Counter in file 0 59:15 -> 59:28, ((#27 + #30) - #31) +Counter in file 0 60:12 -> 60:25, (((#27 + #30) - #31) - #6) +Counter in file 0 60:29 -> 60:42, ((((#27 + #30) - #31) - #6) - #39) +Counter in file 0 60:42 -> 60:43, (#39 + #40) +Counter in file 0 60:42 -> 60:43, (((((#27 + #30) - #31) - #6) - #39) - #40) +Counter in file 0 60:46 -> 60:60, #46 +Counter in file 0 60:60 -> 60:61, (#46 - #45) +Counter in file 0 60:60 -> 60:61, (#44 + #45) +Counter in file 0 60:61 -> 62:10, #47 +Counter in file 0 62:10 -> 62:11, #48 +Counter in file 0 63:9 -> 63:23, #10 +Counter in file 0 65:9 -> 65:15, #6 +Counter in file 0 67:1 -> 67:2, ((#9 + #10) + (((#6 + #7) + #8) + (((#2 + 0) - #3) - #5))) Emitting segments for file: ../coverage/various_conditions.rs Combined regions: 4:9 -> 4:26 (count=1) @@ -131,7 +130,7 @@ Combined regions: 62:10 -> 62:11 (count=0) 63:9 -> 63:23 (count=0) 65:9 -> 65:15 (count=0) - 67:1 -> 67:2 (count=2) + 67:1 -> 67:2 (count=1) Segment at 4:9 (count = 1), RegionEntry Segment at 4:26 (count = 0), Skipped Segment at 5:8 (count = 1), RegionEntry @@ -236,5 +235,5 @@ Segment at 63:9 (count = 0), RegionEntry Segment at 63:23 (count = 0), Skipped Segment at 65:9 (count = 0), RegionEntry Segment at 65:15 (count = 0), Skipped -Segment at 67:1 (count = 2), RegionEntry +Segment at 67:1 (count = 1), RegionEntry Segment at 67:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt index b75a88b2e929e..76cf1e92ecd3b 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt @@ -1,8 +1,8 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while Counter in file 0 2:9 -> 2:16, #1 -Counter in file 0 3:11 -> 3:20, #2 -Counter in file 0 3:21 -> 4:6, #3 -Counter in file 0 5:1 -> 5:2, #4 +Counter in file 0 3:11 -> 3:20, (#1 + #2) +Counter in file 0 3:21 -> 4:6, #2 +Counter in file 0 5:1 -> 5:2, ((#1 + #2) - #2) Emitting segments for file: ../coverage/while.rs Combined regions: 2:9 -> 2:16 (count=1) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt index 908613018a49a..60f389fc9d467 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt @@ -1,14 +1,13 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return Counter in file 0 5:9 -> 5:27, #1 -Counter in file 0 7:9 -> 9:10, #2 -Counter in file 0 12:13 -> 14:14, #3 -Counter in file 0 18:21 -> 20:22, #4 -Counter in file 0 22:21 -> 22:27, #5 -Counter in file 0 26:21 -> 26:27, #6 -Counter in file 0 30:9 -> 32:10, #7 -Counter in file 0 35:5 -> 35:11, #8 -Counter in file 0 36:1 -> 36:2, #9 -Counter in file 0 36:1 -> 36:2, #10 +Counter in file 0 7:9 -> 9:10, (#1 + #2) +Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3) +Counter in file 0 18:21 -> 20:22, #6 +Counter in file 0 22:21 -> 22:27, #4 +Counter in file 0 26:21 -> 26:27, #5 +Counter in file 0 30:9 -> 32:10, #2 +Counter in file 0 35:5 -> 35:11, #3 +Counter in file 0 36:1 -> 36:2, ((#4 + #5) + #3) Emitting segments for file: ../coverage/while_early_return.rs Combined regions: 5:9 -> 5:27 (count=1) @@ -19,7 +18,7 @@ Combined regions: 26:21 -> 26:27 (count=1) 30:9 -> 32:10 (count=6) 35:5 -> 35:11 (count=0) - 36:1 -> 36:2 (count=2) + 36:1 -> 36:2 (count=1) Segment at 5:9 (count = 1), RegionEntry Segment at 5:27 (count = 0), Skipped Segment at 7:9 (count = 7), RegionEntry @@ -36,5 +35,5 @@ Segment at 30:9 (count = 6), RegionEntry Segment at 32:10 (count = 0), Skipped Segment at 35:5 (count = 0), RegionEntry Segment at 35:11 (count = 0), Skipped -Segment at 36:1 (count = 2), RegionEntry +Segment at 36:1 (count = 1), RegionEntry Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 325b6c64345a4..494e6f20ea763 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -114,6 +114,6 @@ Ok(())⦉@2,6,7,8
-}@1,3,4,5,9,10⦊‸⦉@1,3,4,5,9,10@2,6,7,8⦊‸⦉@2,6,7,8@11⦊‸⦉@11 +}@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 55d7e8bfbae18..6dc893d28ff52 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -162,6 +162,6 @@ Ok(())⦉@5,9,10,11
-}@4,6,7,8,12,13⦊‸⦉@4,6,7,8,12,13@5,9,10,11⦊‸⦉@5,9,10,11@14⦊‸⦉@14 +}@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index 094dacde9868d..b51c5c84c0d6e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -128,36 +128,36 @@ 20:9-22:16: @5[1]: _6 = const ()"> =
100⦉@5 - }@4,6⦊‸⦉@4,6 + } if - @7⦊is_true⦉@7 - @8,10⦊{ - countdown - = - 10 - ; - }⦉@8,10 else - @9⦊{ - countdown - = - 100 - ; - }⦉@9@8,10⦊‸⦉@8,10 + }⦉@9 }@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 8a0b1ae8dab11..9f9933423406e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -67,7 +67,7 @@ } else { @2⦊Ok(())⦉@2 - }@1,3⦊‸⦉@1,3 -}@4⦊‸⦉@4 + } +}@4⦊‸⦉@4 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 325b6c64345a4..494e6f20ea763 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -114,6 +114,6 @@ Ok(())⦉@2,6,7,8 -}@1,3,4,5,9,10⦊‸⦉@1,3,4,5,9,10@2,6,7,8⦊‸⦉@2,6,7,8@11⦊‸⦉@11 +}@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 55d7e8bfbae18..6dc893d28ff52 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -162,6 +162,6 @@ Ok(())⦉@5,9,10,11 -}@4,6,7,8,12,13⦊‸⦉@4,6,7,8,12,13@5,9,10,11⦊‸⦉@5,9,10,11@14⦊‸⦉@14 +}@14⦊‸⦉@14 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index 094dacde9868d..b51c5c84c0d6e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -128,36 +128,36 @@ 20:9-22:16: @5[1]: _6 = const ()"> = 100⦉@5 - }@4,6⦊‸⦉@4,6 + } if - @7⦊is_true⦉@7 - @8,10⦊{ - countdown - = - 10 - ; - }⦉@8,10 else - @9⦊{ - countdown - = - 100 - ; - }⦉@9@8,10⦊‸⦉@8,10 + }⦉@9 }@11⦊‸⦉@11 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 8a0b1ae8dab11..9f9933423406e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -67,7 +67,7 @@ } else { @2⦊Ok(())⦉@2 - }@1,3⦊‸⦉@1,3 -}@4⦊‸⦉@4 + } +}@4⦊‸⦉@4 From da20b6706f012c1f4d55177113bbea5a3ee59b72 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Sun, 25 Oct 2020 01:53:44 -0700 Subject: [PATCH 18/27] Added comments on remapping expression IDs, and URL to spanviews --- .../rustc_codegen_ssa/src/coverageinfo/map.rs | 20 ++++++- ...cted_export_coverage.try_error_result.json | 20 +++---- ...xpected_show_coverage.try_error_result.txt | 17 +++--- ...how_coverage_counters.try_error_result.txt | 59 +++++++++++-------- ...cted_export_coverage.try_error_result.json | 20 +++---- ...xpected_show_coverage.try_error_result.txt | 17 +++--- ...ters.partial_eq_counter_without_region.txt | 12 ++-- ...how_coverage_counters.try_error_result.txt | 59 +++++++++++-------- .../coverage-spanview-base/Makefile | 20 +++++++ .../coverage-spanview-base/escape_url.py | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#1}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#2}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#3}.-------.InstrumentCoverage.0.html | 10 ++++ ...ure.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ait.main.-------.InstrumentCoverage.0.html | 10 ++++ ...#0}-drop.-------.InstrumentCoverage.0.html | 10 ++++ ...ics.main.-------.InstrumentCoverage.0.html | 10 ++++ ...strength.-------.InstrumentCoverage.0.html | 10 ++++ ...#1}-drop.-------.InstrumentCoverage.0.html | 10 ++++ .../if.main.-------.InstrumentCoverage.0.html | 10 ++++ ...lse.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ait_func.-------.InstrumentCoverage.0.html | 10 ++++ ...-in_func.-------.InstrumentCoverage.0.html | 10 ++++ ...ait_func.-------.InstrumentCoverage.0.html | 10 ++++ ...ems.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ean.main.-------.InstrumentCoverage.0.html | 10 ++++ ...lue.main.-------.InstrumentCoverage.0.html | 10 ++++ ...hes.main.-------.InstrumentCoverage.0.html | 10 ++++ ...l#0}-fmt.-------.InstrumentCoverage.0.html | 10 ++++ ...ops.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ion.main.-------.InstrumentCoverage.0.html | 10 ++++ ...l#0}-new.-------.InstrumentCoverage.0.html | 10 ++++ ...l#1}-cmp.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-ge.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-gt.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-le.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-lt.-------.InstrumentCoverage.0.html | 10 ++++ ...tial_cmp.-------.InstrumentCoverage.0.html | 10 ++++ ...total_eq.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#6}-eq.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#6}-ne.-------.InstrumentCoverage.0.html | 10 ++++ ...l#7}-fmt.-------.InstrumentCoverage.0.html | 10 ++++ ...8}-clone.-------.InstrumentCoverage.0.html | 10 ++++ ...oop.main.-------.InstrumentCoverage.0.html | 10 ++++ ...tch.main.-------.InstrumentCoverage.0.html | 10 ++++ ...oop.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ult.call.-------.InstrumentCoverage.0.html | 10 ++++ ...ult.main.-------.InstrumentCoverage.0.html | 35 +++++++---- ...ons.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ile.main.-------.InstrumentCoverage.0.html | 10 ++++ ...urn.main.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#1}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#2}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#3}.-------.InstrumentCoverage.0.html | 10 ++++ ...ure.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ait.main.-------.InstrumentCoverage.0.html | 10 ++++ ...#0}-drop.-------.InstrumentCoverage.0.html | 10 ++++ ...ics.main.-------.InstrumentCoverage.0.html | 10 ++++ ...strength.-------.InstrumentCoverage.0.html | 10 ++++ ...#1}-drop.-------.InstrumentCoverage.0.html | 10 ++++ .../if.main.-------.InstrumentCoverage.0.html | 10 ++++ ...lse.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ait_func.-------.InstrumentCoverage.0.html | 10 ++++ ...-in_func.-------.InstrumentCoverage.0.html | 10 ++++ ...ait_func.-------.InstrumentCoverage.0.html | 10 ++++ ...ems.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ean.main.-------.InstrumentCoverage.0.html | 10 ++++ ...lue.main.-------.InstrumentCoverage.0.html | 10 ++++ ...hes.main.-------.InstrumentCoverage.0.html | 10 ++++ ...l#0}-fmt.-------.InstrumentCoverage.0.html | 10 ++++ ...ops.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ion.main.-------.InstrumentCoverage.0.html | 10 ++++ ...l#0}-new.-------.InstrumentCoverage.0.html | 10 ++++ ...l#1}-cmp.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-ge.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-gt.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-le.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...osure#0}.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#2}-lt.-------.InstrumentCoverage.0.html | 10 ++++ ...tial_cmp.-------.InstrumentCoverage.0.html | 10 ++++ ...total_eq.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#6}-eq.-------.InstrumentCoverage.0.html | 10 ++++ ...pl#6}-ne.-------.InstrumentCoverage.0.html | 10 ++++ ...l#7}-fmt.-------.InstrumentCoverage.0.html | 10 ++++ ...8}-clone.-------.InstrumentCoverage.0.html | 10 ++++ ...oop.main.-------.InstrumentCoverage.0.html | 10 ++++ ...tch.main.-------.InstrumentCoverage.0.html | 10 ++++ ...oop.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ult.call.-------.InstrumentCoverage.0.html | 10 ++++ ...ult.main.-------.InstrumentCoverage.0.html | 35 +++++++---- ...ons.main.-------.InstrumentCoverage.0.html | 10 ++++ ...ile.main.-------.InstrumentCoverage.0.html | 10 ++++ ...urn.main.-------.InstrumentCoverage.0.html | 10 ++++ .../coverage/try_error_result.rs | 1 + 111 files changed, 1188 insertions(+), 117 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 006d6662196a0..24fb107b56796 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -157,7 +157,25 @@ impl<'tcx> FunctionCoverage<'tcx> { let mut counter_expressions = Vec::with_capacity(self.expressions.len()); let mut expression_regions = Vec::with_capacity(self.expressions.len()); let mut new_indexes = IndexVec::from_elem_n(None, self.expressions.len()); - // Note that an `Expression`s at any given index can include other expressions as + + // This closure converts any `Expression` operand (`lhs` or `rhs` of the `Op::Add` or + // `Op::Subtract` operation) into its native `llvm::coverage::Counter::CounterKind` type + // and value. Operand ID value `0` maps to `CounterKind::Zero`; values in the known range + // of injected LLVM counters map to `CounterKind::CounterValueReference` (and the value + // matches the injected counter index); and any other value is converted into a + // `CounterKind::Expression` with the expression's `new_index`. + // + // Expressions will be returned from this function in a sequential vector (array) of + // `CounterExpression`, so the expression IDs must be mapped from their original, + // potentially sparse set of indexes, originally in reverse order from `u32::MAX`. + // + // An `Expression` as an operand will have already been encountered as an `Expression` with + // operands, so its new_index will already have been generated (as a 1-up index value). + // (If an `Expression` as an operand does not have a corresponding new_index, it was + // probably optimized out, after the expression was injected into the MIR, so it will + // get a `CounterKind::Zero` instead.) + // + // In other words, an `Expression`s at any given index can include other expressions as // operands, but expression operands can only come from the subset of expressions having // `expression_index`s lower than the referencing `Expression`. Therefore, it is // reasonable to look up the new index of an expression operand while the `new_indexes` diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json index 929e769b50a98..78b935b15689a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 19, + "count": 20, "covered": 18, - "percent": 94.73684210526315 + "percent": 90 }, "regions": { - "count": 17, + "count": 19, "covered": 14, - "notcovered": 3, - "percent": 82.35294117647058 + "notcovered": 5, + "percent": 73.68421052631578 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 19, + "count": 20, "covered": 18, - "percent": 94.73684210526315 + "percent": 90 }, "regions": { - "count": 17, + "count": 19, "covered": 14, - "notcovered": 3, - "percent": 82.35294117647058 + "notcovered": 5, + "percent": 73.68421052631578 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt index 94c63c9a2b906..6b3a8c39c6338 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage.try_error_result.txt @@ -25,13 +25,14 @@ 25| 6| countdown < 5 26| | { 27| 1| call(/*return_error=*/ true)?; - 28| | } - 29| | else - 30| | { - 31| 5| call(/*return_error=*/ false)?; + 28| 0| call(/*return_error=*/ false)?; + 29| | } + 30| | else + 31| | { + 32| 5| call(/*return_error=*/ false)?; ^0 - 32| 5| } - 33| 5| } - 34| 0| Ok(()) - 35| 1|} + 33| 5| } + 34| 5| } + 35| 0| Ok(()) + 36| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt index 30109a1e20020..d851fdeb745f7 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt @@ -2,16 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 13:9 -> 14:23, #1 Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) -Counter in file 0 21:9 -> 25:26, #7 -Counter in file 0 27:13 -> 27:41, #8 +Counter in file 0 21:9 -> 25:26, #8 +Counter in file 0 27:13 -> 27:41, #9 Counter in file 0 27:41 -> 27:42, #5 -Counter in file 0 31:13 -> 31:42, (#7 - #8) -Counter in file 0 31:42 -> 31:43, #6 -Counter in file 0 32:10 -> 32:11, #2 -Counter in file 0 32:10 -> 32:11, #3 -Counter in file 0 33:6 -> 33:7, (#2 + #3) -Counter in file 0 34:5 -> 34:11, #4 -Counter in file 0 35:1 -> 35:2, ((#5 + #6) + #4) +Counter in file 0 28:13 -> 28:42, (#9 - #5) +Counter in file 0 28:42 -> 28:43, #6 +Counter in file 0 32:13 -> 32:42, (#8 - #9) +Counter in file 0 32:42 -> 32:43, #7 +Counter in file 0 33:10 -> 33:11, #2 +Counter in file 0 33:10 -> 33:11, #3 +Counter in file 0 34:6 -> 34:7, (#2 + #3) +Counter in file 0 35:5 -> 35:11, #4 +Counter in file 0 36:1 -> 36:2, ((#5 + (#6 + #7)) + #4) Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 Counter in file 0 8:9 -> 8:15, (#1 - #2) @@ -28,12 +30,14 @@ Combined regions: 21:9 -> 25:26 (count=6) 27:13 -> 27:41 (count=1) 27:41 -> 27:42 (count=1) - 31:13 -> 31:42 (count=5) - 31:42 -> 31:43 (count=0) - 32:10 -> 32:11 (count=5) - 33:6 -> 33:7 (count=5) - 34:5 -> 34:11 (count=0) - 35:1 -> 35:2 (count=1) + 28:13 -> 28:42 (count=0) + 28:42 -> 28:43 (count=0) + 32:13 -> 32:42 (count=5) + 32:42 -> 32:43 (count=0) + 33:10 -> 33:11 (count=5) + 34:6 -> 34:7 (count=5) + 35:5 -> 35:11 (count=0) + 36:1 -> 36:2 (count=1) Segment at 5:8 (count = 6), RegionEntry Segment at 5:20 (count = 0), Skipped Segment at 6:9 (count = 1), RegionEntry @@ -53,14 +57,17 @@ Segment at 25:26 (count = 0), Skipped Segment at 27:13 (count = 1), RegionEntry Segment at 27:41 (count = 1), RegionEntry Segment at 27:42 (count = 0), Skipped -Segment at 31:13 (count = 5), RegionEntry -Segment at 31:42 (count = 0), RegionEntry -Segment at 31:43 (count = 0), Skipped -Segment at 32:10 (count = 5), RegionEntry -Segment at 32:11 (count = 0), Skipped -Segment at 33:6 (count = 5), RegionEntry -Segment at 33:7 (count = 0), Skipped -Segment at 34:5 (count = 0), RegionEntry -Segment at 34:11 (count = 0), Skipped -Segment at 35:1 (count = 1), RegionEntry -Segment at 35:2 (count = 0), Skipped +Segment at 28:13 (count = 0), RegionEntry +Segment at 28:42 (count = 0), RegionEntry +Segment at 28:43 (count = 0), Skipped +Segment at 32:13 (count = 5), RegionEntry +Segment at 32:42 (count = 0), RegionEntry +Segment at 32:43 (count = 0), Skipped +Segment at 33:10 (count = 5), RegionEntry +Segment at 33:11 (count = 0), Skipped +Segment at 34:6 (count = 5), RegionEntry +Segment at 34:7 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 35:11 (count = 0), Skipped +Segment at 36:1 (count = 1), RegionEntry +Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json index 929e769b50a98..78b935b15689a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_export_coverage.try_error_result.json @@ -16,15 +16,15 @@ "percent": 100 }, "lines": { - "count": 19, + "count": 20, "covered": 18, - "percent": 94.73684210526315 + "percent": 90 }, "regions": { - "count": 17, + "count": 19, "covered": 14, - "notcovered": 3, - "percent": 82.35294117647058 + "notcovered": 5, + "percent": 73.68421052631578 } } } @@ -41,15 +41,15 @@ "percent": 100 }, "lines": { - "count": 19, + "count": 20, "covered": 18, - "percent": 94.73684210526315 + "percent": 90 }, "regions": { - "count": 17, + "count": 19, "covered": 14, - "notcovered": 3, - "percent": 82.35294117647058 + "notcovered": 5, + "percent": 73.68421052631578 } } } diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt index 94c63c9a2b906..6b3a8c39c6338 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage.try_error_result.txt @@ -25,13 +25,14 @@ 25| 6| countdown < 5 26| | { 27| 1| call(/*return_error=*/ true)?; - 28| | } - 29| | else - 30| | { - 31| 5| call(/*return_error=*/ false)?; + 28| 0| call(/*return_error=*/ false)?; + 29| | } + 30| | else + 31| | { + 32| 5| call(/*return_error=*/ false)?; ^0 - 32| 5| } - 33| 5| } - 34| 0| Ok(()) - 35| 1|} + 33| 5| } + 34| 5| } + 35| 0| Ok(()) + 36| 1|} diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt index 5ab9a99d6868f..442d6ca9dfdc4 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -1,29 +1,29 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region +Counter in file 0 4:32 -> 4:33, (#3 + (#1 + #2)) Counter in file 0 4:48 -> 4:49, ((#1 + #2) + ((#3 + #4) + ((#5 + #6) + #7))) -Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 21:11 -> 26:2, #1 +Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) -Counter in file 0 7:5 -> 7:6, #1 -Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) +Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:32 -> 4:33, ((#4 + #5) + #6) Counter in file 0 4:53 -> 4:54, (#1 + (#2 + (#3 + #4))) Counter in file 0 13:9 -> 18:6, #1 -Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 4:10 -> 4:15, #1 Counter in file 0 4:35 -> 4:37, #1 Counter in file 0 7:5 -> 7:6, #1 -Counter in file 0 8:5 -> 8:17, #1 +Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 4:17 -> 4:22, #1 Counter in file 0 8:5 -> 8:17, #1 Counter in file 0 4:39 -> 4:40, #1 Counter in file 0 4:48 -> 4:49, (#1 + 0) -Counter in file 0 4:32 -> 4:33, (#3 + (#1 + #2)) +Counter in file 0 7:5 -> 7:6, #1 Emitting segments for file: ../coverage/partial_eq_counter_without_region.rs Combined regions: 4:17 -> 4:22 (count=2) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt index 9cfc05e874a51..4e9e5a6e5944f 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt @@ -2,16 +2,18 @@ Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/ Counter in file 0 13:9 -> 14:23, #1 Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) -Counter in file 0 21:9 -> 25:26, #7 -Counter in file 0 27:13 -> 27:41, #8 +Counter in file 0 21:9 -> 25:26, #8 +Counter in file 0 27:13 -> 27:41, #9 Counter in file 0 27:41 -> 27:42, #5 -Counter in file 0 31:13 -> 31:42, (#7 - #8) -Counter in file 0 31:42 -> 31:43, #6 -Counter in file 0 32:10 -> 32:11, #2 -Counter in file 0 32:10 -> 32:11, #3 -Counter in file 0 33:6 -> 33:7, (#2 + #3) -Counter in file 0 34:5 -> 34:11, #4 -Counter in file 0 35:1 -> 35:2, ((#5 + #6) + #4) +Counter in file 0 28:13 -> 28:42, (#9 - #5) +Counter in file 0 28:42 -> 28:43, #6 +Counter in file 0 32:13 -> 32:42, (#8 - #9) +Counter in file 0 32:42 -> 32:43, #7 +Counter in file 0 33:10 -> 33:11, #2 +Counter in file 0 33:10 -> 33:11, #3 +Counter in file 0 34:6 -> 34:7, (#2 + #3) +Counter in file 0 35:5 -> 35:11, #4 +Counter in file 0 36:1 -> 36:2, ((#5 + (#6 + #7)) + #4) Counter in file 0 5:8 -> 5:20, #1 Counter in file 0 6:9 -> 6:16, #2 Counter in file 0 8:9 -> 8:15, (#1 - #2) @@ -28,12 +30,14 @@ Combined regions: 21:9 -> 25:26 (count=6) 27:13 -> 27:41 (count=1) 27:41 -> 27:42 (count=1) - 31:13 -> 31:42 (count=5) - 31:42 -> 31:43 (count=0) - 32:10 -> 32:11 (count=5) - 33:6 -> 33:7 (count=5) - 34:5 -> 34:11 (count=0) - 35:1 -> 35:2 (count=1) + 28:13 -> 28:42 (count=0) + 28:42 -> 28:43 (count=0) + 32:13 -> 32:42 (count=5) + 32:42 -> 32:43 (count=0) + 33:10 -> 33:11 (count=5) + 34:6 -> 34:7 (count=5) + 35:5 -> 35:11 (count=0) + 36:1 -> 36:2 (count=1) Segment at 5:8 (count = 6), RegionEntry Segment at 5:20 (count = 0), Skipped Segment at 6:9 (count = 1), RegionEntry @@ -53,14 +57,17 @@ Segment at 25:26 (count = 0), Skipped Segment at 27:13 (count = 1), RegionEntry Segment at 27:41 (count = 1), RegionEntry Segment at 27:42 (count = 0), Skipped -Segment at 31:13 (count = 5), RegionEntry -Segment at 31:42 (count = 0), RegionEntry -Segment at 31:43 (count = 0), Skipped -Segment at 32:10 (count = 5), RegionEntry -Segment at 32:11 (count = 0), Skipped -Segment at 33:6 (count = 5), RegionEntry -Segment at 33:7 (count = 0), Skipped -Segment at 34:5 (count = 0), RegionEntry -Segment at 34:11 (count = 0), Skipped -Segment at 35:1 (count = 1), RegionEntry -Segment at 35:2 (count = 0), Skipped +Segment at 28:13 (count = 0), RegionEntry +Segment at 28:42 (count = 0), RegionEntry +Segment at 28:43 (count = 0), Skipped +Segment at 32:13 (count = 5), RegionEntry +Segment at 32:42 (count = 0), RegionEntry +Segment at 32:43 (count = 0), Skipped +Segment at 33:10 (count = 5), RegionEntry +Segment at 33:11 (count = 0), Skipped +Segment at 34:6 (count = 5), RegionEntry +Segment at 34:7 (count = 0), Skipped +Segment at 35:5 (count = 0), RegionEntry +Segment at 35:11 (count = 0), Skipped +Segment at 36:1 (count = 1), RegionEntry +Segment at 36:2 (count = 0), Skipped diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/Makefile b/src/test/run-make-fulldeps/coverage-spanview-base/Makefile index fa2f4ec394e2c..ecb5275e716fe 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/Makefile +++ b/src/test/run-make-fulldeps/coverage-spanview-base/Makefile @@ -6,6 +6,7 @@ -include ../coverage/coverage_tools.mk +BASEDIR=../coverage-spanview-base SOURCEDIR=../coverage all: $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs)) @@ -27,6 +28,25 @@ endif -Zdump-mir=InstrumentCoverage \ -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ + for path in "$(TMPDIR)"/mir_dump.$@/*; do \ + echo $$path; \ + file="$$(basename "$$path")"; \ + echo $$file; \ + urlescaped="$$("$(PYTHON)" $(BASEDIR)/escape_url.py $$file)" || exit $$?; \ + echo $$urlescaped; \ + sed -i '1a\ +' "$$path"; \ + done && true # for/done ends in non-zero status + ifdef RUSTC_BLESS_TEST mkdir -p expected_mir_dump.$@ cp "$(TMPDIR)"/mir_dump.$@/*InstrumentCoverage.0.html expected_mir_dump.$@/ diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py b/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py new file mode 100644 index 0000000000000..6d2ded697b38e --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import sys +import six + +# Support python 2 or 3 +from six.moves.urllib.parse import quote + +# Converts the input string into a valid URL parameter string. +print (quote(' '.join(sys.argv[1:]))) diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html index 0f076a93c0977..2d179aa0f1147 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html index bc78a604e311e..58e81a221d3a8 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#1} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html index b0db2311730b0..0614da6cee27f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#2} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html index ca07a8d3ce5b8..bbafb44017cf9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#3} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html index f70576ca24e94..8d1938c0922be 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 494e6f20ea763..aebeb39fd5179 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + drop_trait.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html index 9530d12fb493e..577491a4e247c 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + drop_trait.{impl#0}-drop - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 6dc893d28ff52..80a3d52fe43c9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html index e31e47b81d4fc..bfd7f6b4bb5a0 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.{impl#0}-set_strength - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html index 99a7df4a67053..58a528e341bef 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.{impl#1}-drop - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html index 0d4b940214e39..77983f8539086 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + if.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index b51c5c84c0d6e..8716ac45d5714 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + if_else.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html index 20c54d0e6b493..9b57c6a737817 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-InTrait-default_trait_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html index 7f1262a6abf0a..31bb57be81b53 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-in_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html index c9e0fe3121121..6c4ce72305e53 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-{impl#0}-trait_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html index ec3517ec9eddd..815d5efbce69f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html index cd23e4220cf17..0388ca42ac88b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + lazy_boolean.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html index dc26c796637cc..941bfca76f321 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loop_break_value.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html index a876c85822f32..169a9ca8696e9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loops_and_branches.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html index 2164a565e22b7..20950c67cbd26 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loops_and_branches.{impl#0}-fmt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html index b30a5a9f81e1f..7fbda5d0b3d2c 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + nested_loops.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html index 3ebe51bc7ec36..525e7b2818ca1 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html index ee6a5489f267b..56cb9390d3b20 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#0}-new - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html index 469a00f62060e..aba487058bca5 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#1}-cmp - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index 671cbea0ff305..93b1638db0b52 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html index 6da79c4b130cb..c472d4ab9796a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html index 5f5c31ce77591..ecdc0e5b9456a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index fbdd0f7db42b4..b2c594d1d5704 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html index 736f203433333..6a5c1139668cf 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html index 0fec7c9932f22..38bf7da6c6f8e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index ff4eba107892b..80cfc3f3ffd70 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html index ccc86a7f92fea..c0a2ccd524d58 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html index 682b9112c4cf8..c3ac0998b4f54 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index e018c96c24f22..b9b8f95b63cb6 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html index a10032059b59e..e760553aed597 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html index 89dad0f90698c..a4be452cab79b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html index feae343bbbb8a..901a27cbcc4ba 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-partial_cmp - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html index 49d73b3457b7c..fbde3f7ad6f0f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html index bc34080f10974..5e96ed208b160 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#6}-eq - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html index 376c8dd80d096..1b6ac7c46a842 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#6}-ne - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html index c3fed16a3b4ee..15b1920a3e510 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#7}-fmt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html index 6a4f11e075446..a373df86b5488 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#8}-clone - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html index 618f84513e908..914e829faa0bd 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + simple_loop.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html index 66885d0612bfc..2488ac563e77e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + simple_match.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html index cc5e54f87ce3a..b5be1f45b8e81 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + tight_infinite_loop.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 9f9933423406e..dfe2eb073aa18 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + try_error_result.call - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index c273c8c88e6f3..5c9baee5d8050 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + try_error_result.main - Coverage Spans @@ -73,7 +83,7 @@ in @2,3,4⦊0..10⦉@2,3,4 { countdown < 5⦉@9 { - @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14 @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; +27:41-27:42: @18.Call: _26 = <() as From<()>>::from(move _27) -> [return: bb19, unwind: bb40]">@16,18,19,20⦊?⦉@16,18,19,20; + @15,21,22⦊call(/*return_error=*/ false)⦉@15,21,22@24,26,27,28⦊?⦉@24,26,27,28; } else { - @11,21,22⦊call(/*return_error=*/ false)⦉@11,21,22@24,26,27,28⦊?⦉@24,26,27,28; - }@15⦊‸⦉@15@23⦊‸⦉@23 - }@29⦊‸⦉@29 - @5⦊Ok(())⦉@5 -}@30⦊‸⦉@30@31⦊‸⦉@31 + @11,29,30⦊call(/*return_error=*/ false)⦉@11,29,30@32,34,35,36⦊?⦉@32,34,35,36; + }@23⦊‸⦉@23@31⦊‸⦉@31 + }@37⦊‸⦉@37 + @5⦊Ok(())⦉@5 +}@38⦊‸⦉@38@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html index b9f6f4d7832b6..4c7b5742eb30f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + various_conditions.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html index 49b8bb5520d86..3ba5135122b93 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + while.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index 3d75e61b80055..6296c0ee15f8b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-base/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + while_early_return.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html index 0f076a93c0977..2d179aa0f1147 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html index bc78a604e311e..58e81a221d3a8 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#1}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#1} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html index b0db2311730b0..0614da6cee27f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#2}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#2} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html index ca07a8d3ce5b8..bbafb44017cf9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main-{closure#3}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main-{closure#3} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html index f70576ca24e94..8d1938c0922be 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.closure/closure.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + closure.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html index 494e6f20ea763..aebeb39fd5179 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + drop_trait.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html index 9530d12fb493e..577491a4e247c 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.drop_trait/drop_trait.{impl#0}-drop.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + drop_trait.{impl#0}-drop - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html index 6dc893d28ff52..80a3d52fe43c9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html index e31e47b81d4fc..bfd7f6b4bb5a0 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#0}-set_strength.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.{impl#0}-set_strength - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html index 99a7df4a67053..58a528e341bef 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.generics/generics.{impl#1}-drop.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + generics.{impl#1}-drop - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html index 0d4b940214e39..77983f8539086 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if/if.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + if.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html index b51c5c84c0d6e..8716ac45d5714 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.if_else/if_else.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + if_else.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html index 20c54d0e6b493..9b57c6a737817 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-InTrait-default_trait_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-InTrait-default_trait_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html index 7f1262a6abf0a..31bb57be81b53 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-in_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-in_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html index c9e0fe3121121..6c4ce72305e53 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main-{impl#0}-trait_func.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main-{impl#0}-trait_func - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html index ec3517ec9eddd..815d5efbce69f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.inner_items/inner_items.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + inner_items.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html index cd23e4220cf17..0388ca42ac88b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.lazy_boolean/lazy_boolean.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + lazy_boolean.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html index dc26c796637cc..941bfca76f321 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loop_break_value/loop_break_value.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loop_break_value.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html index a876c85822f32..169a9ca8696e9 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loops_and_branches.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html index 2164a565e22b7..20950c67cbd26 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.loops_and_branches/loops_and_branches.{impl#0}-fmt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + loops_and_branches.{impl#0}-fmt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html index b30a5a9f81e1f..7fbda5d0b3d2c 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.nested_loops/nested_loops.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + nested_loops.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html index 3ebe51bc7ec36..525e7b2818ca1 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html index ee6a5489f267b..56cb9390d3b20 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#0}-new.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#0}-new - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html index 469a00f62060e..aba487058bca5 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#1}-cmp.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#1}-cmp - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index 671cbea0ff305..93b1638db0b52 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html index 6da79c4b130cb..c472d4ab9796a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html index 5f5c31ce77591..ecdc0e5b9456a 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-ge.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-ge - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index fbdd0f7db42b4..b2c594d1d5704 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html index 736f203433333..6a5c1139668cf 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html index 0fec7c9932f22..38bf7da6c6f8e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-gt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-gt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index ff4eba107892b..80cfc3f3ffd70 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html index ccc86a7f92fea..c0a2ccd524d58 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html index 682b9112c4cf8..c3ac0998b4f54 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-le.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-le - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html index e018c96c24f22..b9b8f95b63cb6 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt-{closure#0}-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html index a10032059b59e..e760553aed597 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt-{closure#0}.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt-{closure#0} - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html index 89dad0f90698c..a4be452cab79b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-lt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-lt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html index feae343bbbb8a..901a27cbcc4ba 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#2}-partial_cmp.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#2}-partial_cmp - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html index 49d73b3457b7c..fbde3f7ad6f0f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#4}-assert_receiver_is_total_eq - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html index bc34080f10974..5e96ed208b160 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-eq.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#6}-eq - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html index 376c8dd80d096..1b6ac7c46a842 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#6}-ne.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#6}-ne - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html index c3fed16a3b4ee..15b1920a3e510 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#7}-fmt.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#7}-fmt - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html index 6a4f11e075446..a373df86b5488 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.partial_eq_counter_without_region/partial_eq_counter_without_region.{impl#8}-clone.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + partial_eq_counter_without_region.{impl#8}-clone - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html index 618f84513e908..914e829faa0bd 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_loop/simple_loop.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + simple_loop.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html index 66885d0612bfc..2488ac563e77e 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.simple_match/simple_match.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + simple_match.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html index cc5e54f87ce3a..b5be1f45b8e81 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.tight_infinite_loop/tight_infinite_loop.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + tight_infinite_loop.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html index 9f9933423406e..dfe2eb073aa18 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.call.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + try_error_result.call - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html index c273c8c88e6f3..5c9baee5d8050 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.try_error_result/try_error_result.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + try_error_result.main - Coverage Spans @@ -73,7 +83,7 @@ in @2,3,4⦊0..10⦉@2,3,4 { countdown < 5⦉@9 { - @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14 @10,12,13,14⦊call(/*return_error=*/ true)⦉@10,12,13,14@16,18,19,20⦊?⦉@16,18,19,20; +27:41-27:42: @18.Call: _26 = <() as From<()>>::from(move _27) -> [return: bb19, unwind: bb40]">@16,18,19,20⦊?⦉@16,18,19,20; + @15,21,22⦊call(/*return_error=*/ false)⦉@15,21,22@24,26,27,28⦊?⦉@24,26,27,28; } else { - @11,21,22⦊call(/*return_error=*/ false)⦉@11,21,22@24,26,27,28⦊?⦉@24,26,27,28; - }@15⦊‸⦉@15@23⦊‸⦉@23 - }@29⦊‸⦉@29 - @5⦊Ok(())⦉@5 -}@30⦊‸⦉@30@31⦊‸⦉@31 + @11,29,30⦊call(/*return_error=*/ false)⦉@11,29,30@32,34,35,36⦊?⦉@32,34,35,36; + }@23⦊‸⦉@23@31⦊‸⦉@31 + }@37⦊‸⦉@37 + @5⦊Ok(())⦉@5 +}@38⦊‸⦉@38@39⦊‸⦉@39 diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html index b9f6f4d7832b6..4c7b5742eb30f 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.various_conditions/various_conditions.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + various_conditions.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html index 49b8bb5520d86..3ba5135122b93 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while/while.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + while.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html index 3d75e61b80055..6296c0ee15f8b 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html +++ b/src/test/run-make-fulldeps/coverage-spanview-deadcode/expected_mir_dump.while_early_return/while_early_return.main.-------.InstrumentCoverage.0.html @@ -1,4 +1,14 @@ + while_early_return.main - Coverage Spans diff --git a/src/test/run-make-fulldeps/coverage/try_error_result.rs b/src/test/run-make-fulldeps/coverage/try_error_result.rs index 3a8f30e048228..13c455172dd11 100644 --- a/src/test/run-make-fulldeps/coverage/try_error_result.rs +++ b/src/test/run-make-fulldeps/coverage/try_error_result.rs @@ -25,6 +25,7 @@ fn main() -> Result<(),()> { countdown < 5 { call(/*return_error=*/ true)?; + call(/*return_error=*/ false)?; } else { From 0edf4a594717b716186983460fdfd7e29a2d9e6f Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Sun, 25 Oct 2020 11:13:16 -0700 Subject: [PATCH 19/27] Addressed all feedback to date --- .../src/coverageinfo/mod.rs | 8 +++----- .../rustc_codegen_ssa/src/coverageinfo/map.rs | 16 +++------------ .../rustc_codegen_ssa/src/mir/coverageinfo.rs | 17 ++++++++-------- .../src/traits/coverageinfo.rs | 6 +++--- compiler/rustc_middle/src/mir/coverage.rs | 14 ------------- .../src/transform/coverage/counters.rs | 11 ++++++++++ .../rustc_mir/src/transform/coverage/query.rs | 20 +++++++++---------- .../rustc_mir/src/transform/coverage/spans.rs | 6 ++---- 8 files changed, 41 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 75e8abaf2a9e9..e21e03822ebb3 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -82,21 +82,19 @@ impl CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { fn add_coverage_counter( &mut self, instance: Instance<'tcx>, - function_source_hash: u64, id: CounterValueReference, region: CodeRegion, ) -> bool { if let Some(coverage_context) = self.coverage_context() { debug!( - "adding counter to coverage_map: instance={:?}, function_source_hash={}, id={:?}, \ - at {:?}", - instance, function_source_hash, id, region, + "adding counter to coverage_map: instance={:?}, id={:?}, region={:?}", + instance, id, region, ); let mut coverage_map = coverage_context.function_coverage_map.borrow_mut(); coverage_map .entry(instance) .or_insert_with(|| FunctionCoverage::new(self.tcx, instance)) - .add_counter(function_source_hash, id, region); + .add_counter(id, region); true } else { false diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 24fb107b56796..b0d7953f511c7 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -52,11 +52,8 @@ impl<'tcx> FunctionCoverage<'tcx> { } } - /// Although every function should have at least one `Counter`, the `Counter` isn't required to - /// have a `CodeRegion`. (The `CodeRegion` may be associated only with `Expressions`.) This - /// method supports the ability to ensure the `function_source_hash` is set from `Counters` that - /// do not trigger the call to `add_counter()` because they don't have an associated - /// `CodeRegion` to add. + /// Sets the function source hash value. If called multiple times for the same function, all + /// calls should have the same hash value. pub fn set_function_source_hash(&mut self, source_hash: u64) { if self.source_hash == 0 { self.source_hash = source_hash; @@ -66,14 +63,7 @@ impl<'tcx> FunctionCoverage<'tcx> { } /// Adds a code region to be counted by an injected counter intrinsic. - /// The source_hash (computed during coverage instrumentation) should also be provided, and - /// should be the same for all counters in a given function. - pub fn add_counter(&mut self, source_hash: u64, id: CounterValueReference, region: CodeRegion) { - if self.source_hash == 0 { - self.source_hash = source_hash; - } else { - debug_assert_eq!(source_hash, self.source_hash); - } + pub fn add_counter(&mut self, id: CounterValueReference, region: CodeRegion) { self.counters[id].replace(region).expect_none("add_counter called with duplicate `id`"); } diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs index 339e0d95fdffc..a115d35866638 100644 --- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs @@ -10,15 +10,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Coverage { kind, code_region } = coverage; match kind { CoverageKind::Counter { function_source_hash, id } => { - let covmap_updated = if let Some(code_region) = code_region { - // Note: Some counters do not have code regions, but may still be referenced from - // expressions. - bx.add_coverage_counter(self.instance, function_source_hash, id, code_region) - } else { - bx.set_function_source_hash(self.instance, function_source_hash) - }; + if bx.set_function_source_hash(self.instance, function_source_hash) { + // If `set_function_source_hash()` returned true, the coverage map is enabled, + // so continue adding the counter. + if let Some(code_region) = code_region { + // Note: Some counters do not have code regions, but may still be referenced + // from expressions. In that case, don't add the counter to the coverage map, + // but do inject the counter intrinsic. + bx.add_coverage_counter(self.instance, id, code_region); + } - if covmap_updated { let coverageinfo = bx.tcx().coverageinfo(self.instance.def_id()); let fn_name = bx.create_pgo_func_name_var(self.instance); diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index 7da38880d603c..95bddfb4b41d1 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -9,8 +9,9 @@ pub trait CoverageInfoMethods: BackendTypes { pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { fn create_pgo_func_name_var(&self, instance: Instance<'tcx>) -> Self::Value; - /// Returns true if the function source hash was added to the coverage map; false if - /// `-Z instrument-coverage` is not enabled (a coverage map is not being generated). + /// Returns true if the function source hash was added to the coverage map (even if it had + /// already been added, for this instance). Returns false *only* if `-Z instrument-coverage` is + /// not enabled (a coverage map is not being generated). fn set_function_source_hash( &mut self, instance: Instance<'tcx>, @@ -22,7 +23,6 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes { fn add_coverage_counter( &mut self, instance: Instance<'tcx>, - function_source_hash: u64, index: CounterValueReference, region: CodeRegion, ) -> bool; diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index ad0ba292d0241..3a97e05a39fe8 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -85,13 +85,6 @@ impl From for ExpressionOperandId { } } -impl From<&mut CounterValueReference> for ExpressionOperandId { - #[inline] - fn from(v: &mut CounterValueReference) -> ExpressionOperandId { - ExpressionOperandId::from(v.as_u32()) - } -} - impl From for ExpressionOperandId { #[inline] fn from(v: InjectedExpressionId) -> ExpressionOperandId { @@ -99,13 +92,6 @@ impl From for ExpressionOperandId { } } -impl From<&mut InjectedExpressionId> for ExpressionOperandId { - #[inline] - fn from(v: &mut InjectedExpressionId) -> ExpressionOperandId { - ExpressionOperandId::from(v.as_u32()) - } -} - #[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, TypeFoldable)] pub enum CoverageKind { Counter { diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs index a3ae302152486..7454ec2f43877 100644 --- a/compiler/rustc_mir/src/transform/coverage/counters.rs +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -12,6 +12,16 @@ use rustc_data_structures::graph::WithNumNodes; use rustc_index::bit_set::BitSet; use rustc_middle::mir::coverage::*; +// When evaluating an expression operand to determine if it references a `Counter` or an +// `Expression`, the range of counter or expression IDs must be known in order to answer the +// question: "Does this ID fall inside the range of counters," for example. If "yes," the ID refers +// to a counter, otherwise the ID refers to an expression. +// +// But in situations where the range is not currently known, the only fallback is to assume a +// specific range limit. `MAX_COUNTER_GUARD` enforces a limit on the number of counters, and +// therefore a limit on the range of counter IDs. +pub(crate) const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; + /// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR /// `Coverage` statements. pub(crate) struct CoverageCounters { @@ -95,6 +105,7 @@ impl CoverageCounters { /// Counter IDs start from one and go up. fn next_counter(&mut self) -> CounterValueReference { assert!(self.next_counter_id < u32::MAX - self.num_expressions); + assert!(self.next_counter_id <= MAX_COUNTER_GUARD); let next = self.next_counter_id; self.next_counter_id += 1; CounterValueReference::from(next) diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs index c17221b78ddd4..2fbbc9b675a1e 100644 --- a/compiler/rustc_mir/src/transform/coverage/query.rs +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -1,3 +1,5 @@ +use super::counters; + use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{Coverage, CoverageInfo, Location}; @@ -32,21 +34,16 @@ pub(crate) fn provide(providers: &mut Providers) { /// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression /// IDs referenced by expression operands, if not already seen. /// -/// Ideally, every expression operand in the MIR will have a corresponding Counter or Expression, -/// but since current or future MIR optimizations can theoretically optimize out segments of a -/// MIR, it may not be possible to guarantee this, so the second pass ensures the `CoverageInfo` -/// counts include all referenced IDs. +/// Ideally, each operand ID in a MIR `CoverageKind::Expression` will have a separate MIR `Coverage` +/// statement for the `Counter` or `Expression` with the referenced ID. but since current or future +/// MIR optimizations can theoretically optimize out segments of a MIR, it may not be possible to +/// guarantee this, so the second pass ensures the `CoverageInfo` counts include all referenced IDs. struct CoverageVisitor { info: CoverageInfo, add_missing_operands: bool, } impl CoverageVisitor { - // If an expression operand is encountered with an ID outside the range of known counters and - // expressions, the only way to determine if the ID is a counter ID or an expression ID is to - // assume a maximum possible counter ID value. - const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; - #[inline(always)] fn update_num_counters(&mut self, counter_id: u32) { self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); @@ -62,7 +59,10 @@ impl CoverageVisitor { if operand_id >= self.info.num_counters { let operand_as_expression_index = u32::MAX - operand_id; if operand_as_expression_index >= self.info.num_expressions { - if operand_id <= Self::MAX_COUNTER_GUARD { + if operand_id <= counters::MAX_COUNTER_GUARD { + // Since the complete range of counter and expression IDs is not known here, the + // only way to determine if the ID is a counter ID or an expression ID is to + // assume a maximum possible counter ID value. self.update_num_counters(operand_id) } else { self.update_num_expressions(operand_id) diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index 61b5b1480532a..8549ac0e4afd1 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -388,8 +388,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { bcb_data .basic_blocks .iter() - .map(|bbref| { - let bb = *bbref; + .flat_map(|&bb| { let data = &self.mir_body[bb]; data.statements .iter() @@ -404,7 +403,6 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { .map(|span| CoverageSpan::for_terminator(span, bcb, bb)), ) }) - .flatten() .collect() } @@ -733,7 +731,7 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) - // However, in other cases, a visible `CoverageSpan` is not wanted, but the `Goto` // block must still be counted (for example, to contribute its count to an `Expression` // that reports the execution count for some other block). In these cases, the code region - // is set to `None`. + // is set to `None`. (See `Instrumentor::is_code_region_redundant()`.) TerminatorKind::Goto { .. } => { Some(function_source_span(terminator.source_info.span.shrink_to_hi(), body_span)) } From 36856891e230eaab0011fdb772a2f2b4e83d8a20 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Fri, 30 Oct 2020 16:09:05 -0700 Subject: [PATCH 20/27] Responded to all feedback as of 2020-10-30 --- .../src/transform/coverage/counters.rs | 297 +++++++++--------- .../rustc_mir/src/transform/coverage/debug.rs | 129 +++++++- .../rustc_mir/src/transform/coverage/graph.rs | 66 ++-- .../rustc_mir/src/transform/coverage/mod.rs | 20 +- .../rustc_mir/src/transform/coverage/query.rs | 26 +- .../rustc_mir/src/transform/coverage/spans.rs | 24 +- compiler/rustc_session/src/options.rs | 7 +- .../coverage-spanview-base/Makefile | 1 + .../coverage/coverage_tools.mk | 5 + 9 files changed, 367 insertions(+), 208 deletions(-) diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs index 7454ec2f43877..d6c2f7f7aaf1d 100644 --- a/compiler/rustc_mir/src/transform/coverage/counters.rs +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -12,16 +12,6 @@ use rustc_data_structures::graph::WithNumNodes; use rustc_index::bit_set::BitSet; use rustc_middle::mir::coverage::*; -// When evaluating an expression operand to determine if it references a `Counter` or an -// `Expression`, the range of counter or expression IDs must be known in order to answer the -// question: "Does this ID fall inside the range of counters," for example. If "yes," the ID refers -// to a counter, otherwise the ID refers to an expression. -// -// But in situations where the range is not currently known, the only fallback is to assume a -// specific range limit. `MAX_COUNTER_GUARD` enforces a limit on the number of counters, and -// therefore a limit on the range of counter IDs. -pub(crate) const MAX_COUNTER_GUARD: u32 = (u32::MAX / 2) + 1; - /// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR /// `Coverage` statements. pub(crate) struct CoverageCounters { @@ -105,7 +95,6 @@ impl CoverageCounters { /// Counter IDs start from one and go up. fn next_counter(&mut self) -> CounterValueReference { assert!(self.next_counter_id < u32::MAX - self.num_expressions); - assert!(self.next_counter_id <= MAX_COUNTER_GUARD); let next = self.next_counter_id; self.next_counter_id += 1; CounterValueReference::from(next) @@ -131,6 +120,7 @@ struct BcbCounters<'a> { basic_coverage_blocks: &'a mut CoverageGraph, } +// FIXME(richkadel): Add unit tests for `BcbCounters` functions/algorithms. impl<'a> BcbCounters<'a> { fn new( coverage_counters: &'a mut CoverageCounters, @@ -139,7 +129,7 @@ impl<'a> BcbCounters<'a> { Self { coverage_counters, basic_coverage_blocks } } - /// If two `CoverageGraph` branch from another `BasicCoverageBlock`, one of the branches + /// If two `BasicCoverageBlock`s branch from another `BasicCoverageBlock`, one of the branches /// can be counted by `Expression` by subtracting the other branch from the branching /// block. Otherwise, the `BasicCoverageBlock` executed the least should have the `Counter`. /// One way to predict which branch executes the least is by considering loops. A loop is exited @@ -162,10 +152,16 @@ impl<'a> BcbCounters<'a> { bcbs_with_coverage.insert(covspan.bcb); } - // FIXME(richkadel): Add more comments to explain the logic here and in the rest of this - // function, and refactor this function to break it up into smaller functions that are - // easier to understand. - + // Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated + // `CoverageSpan`, add a counter. If the `BasicCoverageBlock` branches, add a counter or + // expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming + // edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple + // incoming edges). + // + // The `TraverseCoverageGraphWithLoops` traversal ensures that, when a loop is encountered, + // all `BasicCoverageBlock` nodes in the loop are visited before visiting any node outside + // the loop. The `traversal` state includes a `context_stack`, providing a way to know if + // the current BCB is in one or more nested loops or not. let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks); while let Some(bcb) = traversal.next(self.basic_coverage_blocks) { if bcbs_with_coverage.contains(bcb) { @@ -220,11 +216,20 @@ impl<'a> BcbCounters<'a> { .join("\n "), ); + // Use the `traversal` state to decide if a subset of the branches exit a loop, making it + // likely that branch is executed less than branches that do not exit the same loop. In this + // case, any branch that does not exit the loop (and has not already been assigned a + // counter) should be counted by expression, if possible. (If a preferred expression branch + // is not selected based on the loop context, select any branch without an existing + // counter.) let expression_branch = self.choose_preferred_expression_branch(traversal, &branches); - // Assign a Counter or Expression to each branch, plus additional - // `Expression`s, as needed, to sum up intermediate results. + + // Assign a Counter or Expression to each branch, plus additional `Expression`s, as needed, + // to sum up intermediate results. let mut some_sumup_counter_operand = None; for branch in branches { + // Skip the selected `expression_branch`, if any. It's expression will be assigned after + // all others. if branch != expression_branch { let branch_counter_operand = if branch.is_only_path_to_target() { debug!( @@ -263,6 +268,9 @@ impl<'a> BcbCounters<'a> { } } } + + // Assign the final expression to the `expression_branch` by subtracting the total of all + // other branches from the counter of the branching BCB. let sumup_counter_operand = some_sumup_counter_operand.expect("sumup_counter_operand should have a value"); debug!( @@ -301,99 +309,99 @@ impl<'a> BcbCounters<'a> { collect_intermediate_expressions: &mut Vec, debug_indent_level: usize, ) -> Result { - Ok({ - if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() { + // If the BCB already has a counter, return it. + if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() { + debug!( + "{}{:?} already has a counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(counter_kind), + ); + return Ok(counter_kind.as_operand_id()); + } + + // A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`). + // Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the + // program results in a tight infinite loop, but it should still compile. + let one_path_to_target = self.bcb_has_one_path_to_target(bcb); + if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) { + let counter_kind = self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb))); + if one_path_to_target { debug!( - "{}{:?} already has a counter: {}", + "{}{:?} gets a new counter: {}", NESTED_INDENT.repeat(debug_indent_level), bcb, - self.format_counter(counter_kind), + self.format_counter(&counter_kind), ); - counter_kind.as_operand_id() } else { - let one_path_to_target = self.bcb_has_one_path_to_target(bcb); - if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) { - let counter_kind = - self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb))); - if one_path_to_target { - debug!( - "{}{:?} gets a new counter: {}", - NESTED_INDENT.repeat(debug_indent_level), - bcb, - self.format_counter(&counter_kind), - ); - } else { - debug!( - "{}{:?} has itself as its own predecessor. It can't be part of its own \ - Expression sum, so it will get its own new counter: {}. (Note, the \ - compiled code will generate an infinite loop.)", - NESTED_INDENT.repeat(debug_indent_level), - bcb, - self.format_counter(&counter_kind), - ); - } - self.basic_coverage_blocks[bcb].set_counter(counter_kind)? - } else { - let mut predecessors = self.bcb_predecessors(bcb).clone().into_iter(); - debug!( - "{}{:?} has multiple incoming edges and will get an expression that sums \ - them up...", - NESTED_INDENT.repeat(debug_indent_level), - bcb, - ); - let first_edge_counter_operand = self - .recursive_get_or_make_edge_counter_operand( - predecessors.next().unwrap(), - bcb, - collect_intermediate_expressions, - debug_indent_level + 1, - )?; - let mut some_sumup_edge_counter_operand = None; - for predecessor in predecessors { - let edge_counter_operand = self - .recursive_get_or_make_edge_counter_operand( - predecessor, - bcb, - collect_intermediate_expressions, - debug_indent_level + 1, - )?; - if let Some(sumup_edge_counter_operand) = - some_sumup_edge_counter_operand.replace(edge_counter_operand) - { - let intermediate_expression = self.coverage_counters.make_expression( - sumup_edge_counter_operand, - Op::Add, - edge_counter_operand, - || None, - ); - debug!( - "{}new intermediate expression: {}", - NESTED_INDENT.repeat(debug_indent_level), - self.format_counter(&intermediate_expression) - ); - let intermediate_expression_operand = - intermediate_expression.as_operand_id(); - collect_intermediate_expressions.push(intermediate_expression); - some_sumup_edge_counter_operand - .replace(intermediate_expression_operand); - } - } - let counter_kind = self.coverage_counters.make_expression( - first_edge_counter_operand, - Op::Add, - some_sumup_edge_counter_operand.unwrap(), - || Some(format!("{:?}", bcb)), - ); - debug!( - "{}{:?} gets a new counter (sum of predecessor counters): {}", - NESTED_INDENT.repeat(debug_indent_level), - bcb, - self.format_counter(&counter_kind) - ); - self.basic_coverage_blocks[bcb].set_counter(counter_kind)? - } + debug!( + "{}{:?} has itself as its own predecessor. It can't be part of its own \ + Expression sum, so it will get its own new counter: {}. (Note, the compiled \ + code will generate an infinite loop.)", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(&counter_kind), + ); } - }) + return self.basic_coverage_blocks[bcb].set_counter(counter_kind); + } + + // A BCB with multiple incoming edges can compute its count by `Expression`, summing up the + // counters and/or expressions of its incoming edges. This will recursively get or create + // counters for those incoming edges first, then call `make_expression()` to sum them up, + // with additional intermediate expressions as needed. + let mut predecessors = self.bcb_predecessors(bcb).clone().into_iter(); + debug!( + "{}{:?} has multiple incoming edges and will get an expression that sums them up...", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + ); + let first_edge_counter_operand = self.recursive_get_or_make_edge_counter_operand( + predecessors.next().unwrap(), + bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + )?; + let mut some_sumup_edge_counter_operand = None; + for predecessor in predecessors { + let edge_counter_operand = self.recursive_get_or_make_edge_counter_operand( + predecessor, + bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + )?; + if let Some(sumup_edge_counter_operand) = + some_sumup_edge_counter_operand.replace(edge_counter_operand) + { + let intermediate_expression = self.coverage_counters.make_expression( + sumup_edge_counter_operand, + Op::Add, + edge_counter_operand, + || None, + ); + debug!( + "{}new intermediate expression: {}", + NESTED_INDENT.repeat(debug_indent_level), + self.format_counter(&intermediate_expression) + ); + let intermediate_expression_operand = intermediate_expression.as_operand_id(); + collect_intermediate_expressions.push(intermediate_expression); + some_sumup_edge_counter_operand.replace(intermediate_expression_operand); + } + } + let counter_kind = self.coverage_counters.make_expression( + first_edge_counter_operand, + Op::Add, + some_sumup_edge_counter_operand.unwrap(), + || Some(format!("{:?}", bcb)), + ); + debug!( + "{}{:?} gets a new counter (sum of predecessor counters): {}", + NESTED_INDENT.repeat(debug_indent_level), + bcb, + self.format_counter(&counter_kind) + ); + self.basic_coverage_blocks[bcb].set_counter(counter_kind) } fn get_or_make_edge_counter_operand( @@ -417,46 +425,44 @@ impl<'a> BcbCounters<'a> { collect_intermediate_expressions: &mut Vec, debug_indent_level: usize, ) -> Result { - Ok({ - let successors = self.bcb_successors(from_bcb).iter(); - if successors.len() > 1 { - if let Some(counter_kind) = - self.basic_coverage_blocks[to_bcb].edge_counter_from(from_bcb) - { - debug!( - "{}Edge {:?}->{:?} already has a counter: {}", - NESTED_INDENT.repeat(debug_indent_level), - from_bcb, - to_bcb, - self.format_counter(counter_kind) - ); - counter_kind.as_operand_id() - } else { - let counter_kind = self - .coverage_counters - .make_counter(|| Some(format!("{:?}->{:?}", from_bcb, to_bcb))); - debug!( - "{}Edge {:?}->{:?} gets a new counter: {}", - NESTED_INDENT.repeat(debug_indent_level), - from_bcb, - to_bcb, - self.format_counter(&counter_kind) - ); - self.basic_coverage_blocks[to_bcb] - .set_edge_counter_from(from_bcb, counter_kind)? - } - } else { - self.recursive_get_or_make_counter_operand( - from_bcb, - collect_intermediate_expressions, - debug_indent_level + 1, - )? - } - }) + // If the source BCB has only one successor (assumed to be the given target), an edge + // counter is unnecessary. Just get or make a counter for the source BCB. + let successors = self.bcb_successors(from_bcb).iter(); + if successors.len() == 1 { + return self.recursive_get_or_make_counter_operand( + from_bcb, + collect_intermediate_expressions, + debug_indent_level + 1, + ); + } + + // If the edge already has a counter, return it. + if let Some(counter_kind) = self.basic_coverage_blocks[to_bcb].edge_counter_from(from_bcb) { + debug!( + "{}Edge {:?}->{:?} already has a counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + from_bcb, + to_bcb, + self.format_counter(counter_kind) + ); + return Ok(counter_kind.as_operand_id()); + } + + // Make a new counter to count this edge. + let counter_kind = + self.coverage_counters.make_counter(|| Some(format!("{:?}->{:?}", from_bcb, to_bcb))); + debug!( + "{}Edge {:?}->{:?} gets a new counter: {}", + NESTED_INDENT.repeat(debug_indent_level), + from_bcb, + to_bcb, + self.format_counter(&counter_kind) + ); + self.basic_coverage_blocks[to_bcb].set_edge_counter_from(from_bcb, counter_kind) } - /// Select a branch for the expression, either the recommended `reloop_branch`, or - /// if none was found, select any branch. + /// Select a branch for the expression, either the recommended `reloop_branch`, or if none was + /// found, select any branch. fn choose_preferred_expression_branch( &self, traversal: &TraverseCoverageGraphWithLoops, @@ -493,9 +499,8 @@ impl<'a> BcbCounters<'a> { } } - /// At most one of the branches (or its edge, from the branching_bcb, - /// if the branch has multiple incoming edges) can have a counter computed by - /// expression. + /// At most, one of the branches (or its edge, from the branching_bcb, if the branch has + /// multiple incoming edges) can have a counter computed by expression. /// /// If at least one of the branches leads outside of a loop (`found_loop_exit` is /// true), and at least one other branch does not exit the loop (the first of which diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 7080975aee5ce..cc697dfd7fe28 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -1,3 +1,113 @@ +//! The `InstrumentCoverage` MIR pass implementation includes debugging tools and options +//! to help developers understand and/or improve the analysis and instrumentation of a MIR. +//! +//! To enable coverage, include the rustc command line option: +//! +//! * `-Z instrument-coverage` +//! +//! MIR Dump Files, with additional `CoverageGraph` graphviz and `CoverageSpan` spanview +//! ------------------------------------------------------------------------------------ +//! +//! Additional debugging options include: +//! +//! * `-Z dump-mir=InstrumentCoverage` - Generate `.mir` files showing the state of the MIR, +//! before and after the `InstrumentCoverage` pass, for each compiled function. +//! +//! * `-Z dump-mir-graphviz` - If `-Z dump-mir` is also enabled for the current MIR node path, +//! each MIR dump is accompanied by a before-and-after graphical view of the MIR, in Graphviz +//! `.dot` file format (which can be visually rendered as a graph using any of a number of free +//! Graphviz viewers and IDE extensions). +//! +//! For the `InstrumentCoverage` pass, this option also enables generation of an additional +//! Graphviz `.dot` file for each function, rendering the `CoverageGraph`: the control flow +//! graph (CFG) of `BasicCoverageBlocks` (BCBs), as nodes, internally labeled to show the +//! `CoverageSpan`-based MIR elements each BCB represents (`BasicBlock`s, `Statement`s and +//! `Terminator`s), assigned coverage counters and/or expressions, and edge counters, as needed. +//! +//! (Note the additional option, `-Z graphviz-dark-mode`, can be added, to change the rendered +//! output from its default black-on-white background to a dark color theme, if desired.) +//! +//! * `-Z dump-mir-spanview` - If `-Z dump-mir` is also enabled for the current MIR node path, +//! each MIR dump is accompanied by a before-and-after `.html` document showing the function's +//! original source code, highlighted by it's MIR spans, at the `statement`-level (by default), +//! `terminator` only, or encompassing span for the `Terminator` plus all `Statement`s, in each +//! `block` (`BasicBlock`). +//! +//! For the `InstrumentCoverage` pass, this option also enables generation of an additional +//! spanview `.html` file for each function, showing the aggregated `CoverageSpan`s that will +//! require counters (or counter expressions) for accurate coverage analysis. +//! +//! Debug Logging +//! ------------- +//! +//! The `InstrumentCoverage` pass includes debug logging messages at various phases and decision +//! points, which can be enabled via environment variable: +//! +//! ```shell +//! RUSTC_LOG=rustc_mir::transform::coverage=debug +//! ``` +//! +//! Other module paths with coverage-related debug logs may also be of interest, particularly for +//! debugging the coverage map data, injected as global variables in the LLVM IR (during rustc's +//! code generation pass). For example: +//! +//! ```shell +//! RUSTC_LOG=rustc_mir::transform::coverage,rustc_codegen_ssa::coverageinfo,rustc_codegen_llvm::coverageinfo=debug +//! ``` +//! +//! Coverage Debug Options +//! --------------------------------- +//! +//! Additional debugging options can be enabled using the environment variable: +//! +//! ```shell +//! RUSTC_COVERAGE_DEBUG_OPTIONS= +//! ``` +//! +//! These options are comma-separated, and specified in the format `option-name=value`. For example: +//! +//! ```shell +//! $ RUSTC_COVERAGE_DEBUG_OPTIONS=counter-format=id+operation,allow-unused-expressions=yes cargo build +//! ``` +//! +//! Coverage debug options include: +//! +//! * `allow-unused-expressions=yes` or `no` (default: `no`) +//! +//! The `InstrumentCoverage` algorithms _should_ only create and assign expressions to a +//! `BasicCoverageBlock`, or an incoming edge, if that expression is either (a) required to +//! count a `CoverageSpan`, or (b) a dependency of some other required counter expression. +//! +//! If an expression is generated that does not map to a `CoverageSpan` or dependency, this +//! probably indicates there was a bug in the algorithm that creates and assigns counters +//! and expressions. +//! +//! When this kind of bug is encountered, the rustc compiler will panic by default. Setting: +//! `allow-unused-expressions=yes` will log a warning message instead of panicking (effectively +//! ignoring the unused expressions), which may be helpful when debugging the root cause of +//! the problem. +//! +//! * `counter-format=`, where `` can be any plus-separated combination of `id`, +//! `block`, and/or `operation` (default: `block+operation`) +//! +//! This option effects both the `CoverageGraph` (graphviz `.dot` files) and debug logging, when +//! generating labels for counters and expressions. +//! +//! Depending on the values and combinations, counters can be labeled by: +//! +//! * `id` - counter or expression ID (ascending counter IDs, starting at 1, or descending +//! expression IDs, starting at `u32:MAX`) +//! * `block` - the `BasicCoverageBlock` label (for example, `bcb0`) or edge label (for +//! example `bcb0->bcb1`), for counters or expressions assigned to count a +//! `BasicCoverageBlock` or edge. Intermediate expressions (not directly associated with +//! a BCB or edge) will be labeled by their expression ID, unless `operation` is also +//! specified. +//! * `operation` - applied to expressions only, labels include the left-hand-side counter +//! or expression label (lhs operand), the operator (`+` or `-`), and the right-hand-side +//! counter or expression (rhs operand). Expression operand labels are generated +//! recursively, generating labels with nested operations, enclosed in parentheses +//! (for example: `bcb2 + (bcb0 - bcb1)`). + use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph}; use super::spans::CoverageSpan; @@ -20,13 +130,11 @@ const RUSTC_COVERAGE_DEBUG_OPTIONS: &str = "RUSTC_COVERAGE_DEBUG_OPTIONS"; pub(crate) fn debug_options<'a>() -> &'a DebugOptions { static DEBUG_OPTIONS: SyncOnceCell = SyncOnceCell::new(); - &DEBUG_OPTIONS.get_or_init(|| DebugOptions::new()) + &DEBUG_OPTIONS.get_or_init(|| DebugOptions::from_env()) } /// Parses and maintains coverage-specific debug options captured from the environment variable -/// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set. Options can be set on the command line by, for example: -/// -/// $ RUSTC_COVERAGE_DEBUG_OPTIONS=counter-format=block,allow_unused_expressions=n cargo build +/// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set. #[derive(Debug, Clone)] pub(crate) struct DebugOptions { pub allow_unused_expressions: bool, @@ -34,7 +142,7 @@ pub(crate) struct DebugOptions { } impl DebugOptions { - fn new() -> Self { + fn from_env() -> Self { let mut allow_unused_expressions = true; let mut counter_format = ExpressionFormat::default(); @@ -152,10 +260,11 @@ impl DebugCounters { } pub fn enable(&mut self) { + debug_assert!(!self.is_enabled()); self.some_counters.replace(FxHashMap::default()); } - pub fn is_enabled(&mut self) -> bool { + pub fn is_enabled(&self) -> bool { self.some_counters.is_some() } @@ -294,12 +403,13 @@ impl GraphvizData { } pub fn enable(&mut self) { + debug_assert!(!self.is_enabled()); self.some_bcb_to_coverage_spans_with_counters = Some(FxHashMap::default()); self.some_bcb_to_dependency_counters = Some(FxHashMap::default()); self.some_edge_to_counter = Some(FxHashMap::default()); } - pub fn is_enabled(&mut self) -> bool { + pub fn is_enabled(&self) -> bool { self.some_bcb_to_coverage_spans_with_counters.is_some() } @@ -399,11 +509,12 @@ impl UsedExpressions { } pub fn enable(&mut self) { + debug_assert!(!self.is_enabled()); self.some_used_expression_operands = Some(FxHashMap::default()); self.some_unused_expressions = Some(Vec::new()); } - pub fn is_enabled(&mut self) -> bool { + pub fn is_enabled(&self) -> bool { self.some_used_expression_operands.is_some() } @@ -416,7 +527,7 @@ impl UsedExpressions { } } - pub fn expression_is_used(&mut self, expression: &CoverageKind) -> bool { + pub fn expression_is_used(&self, expression: &CoverageKind) -> bool { if let Some(used_expression_operands) = self.some_used_expression_operands.as_ref() { used_expression_operands.contains_key(&expression.as_operand_id()) } else { diff --git a/compiler/rustc_mir/src/transform/coverage/graph.rs b/compiler/rustc_mir/src/transform/coverage/graph.rs index 8406254170196..c2ed2cbb10002 100644 --- a/compiler/rustc_mir/src/transform/coverage/graph.rs +++ b/compiler/rustc_mir/src/transform/coverage/graph.rs @@ -82,6 +82,8 @@ impl CoverageGraph { // each block terminator's `successors()`. Coverage spans must map to actual source code, // so compiler generated blocks and paths can be ignored. To that end, the CFG traversal // intentionally omits unwind paths. + // FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and + // `catch_unwind()` handlers. let mir_cfg_without_unwind = ShortCircuitPreorder::new(&mir_body, bcb_filtered_successors); let mut basic_blocks = Vec::new(); @@ -288,7 +290,8 @@ rustc_index::newtype_index! { /// * The BCB CFG ignores (trims) branches not relevant to coverage, such as unwind-related code, /// that is injected by the Rust compiler but has no physical source code to count. This also /// means a BasicBlock with a `Call` terminator can be merged into its primary successor target -/// block, in the same BCB. +/// block, in the same BCB. (But, note: Issue #78544: "MIR InstrumentCoverage: Improve coverage +/// of `#[should_panic]` tests and `catch_unwind()` handlers") /// * Some BasicBlock terminators support Rust-specific concerns--like borrow-checking--that are /// not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as /// a `Goto`, and merged with its successor into the same BCB. @@ -329,7 +332,6 @@ impl BasicCoverageBlockData { &mir_body[self.last_bb()].terminator() } - #[inline(always)] pub fn set_counter( &mut self, counter_kind: CoverageKind, @@ -342,16 +344,15 @@ impl BasicCoverageBlockData { "attempt to add a `Counter` to a BCB target with existing incoming edge counters" ); let operand = counter_kind.as_operand_id(); - let expect_none = self.counter_kind.replace(counter_kind); - if expect_none.is_some() { - return Error::from_string(format!( + if let Some(replaced) = self.counter_kind.replace(counter_kind) { + Error::from_string(format!( "attempt to set a BasicCoverageBlock coverage counter more than once; \ {:?} already had counter {:?}", - self, - expect_none.unwrap(), - )); + self, replaced, + )) + } else { + Ok(operand) } - Ok(operand) } #[inline(always)] @@ -364,7 +365,6 @@ impl BasicCoverageBlockData { self.counter_kind.take() } - #[inline(always)] pub fn set_edge_counter_from( &mut self, from_bcb: BasicCoverageBlock, @@ -383,22 +383,22 @@ impl BasicCoverageBlockData { } } let operand = counter_kind.as_operand_id(); - let expect_none = self + if let Some(replaced) = self .edge_from_bcbs .get_or_insert_with(|| FxHashMap::default()) - .insert(from_bcb, counter_kind); - if expect_none.is_some() { - return Error::from_string(format!( + .insert(from_bcb, counter_kind) + { + Error::from_string(format!( "attempt to set an edge counter more than once; from_bcb: \ {:?} already had counter {:?}", - from_bcb, - expect_none.unwrap(), - )); + from_bcb, replaced, + )) + } else { + Ok(operand) } - Ok(operand) } - #[inline(always)] + #[inline] pub fn edge_counter_from(&self, from_bcb: BasicCoverageBlock) -> Option<&CoverageKind> { if let Some(edge_from_bcbs) = &self.edge_from_bcbs { edge_from_bcbs.get(&from_bcb) @@ -407,7 +407,7 @@ impl BasicCoverageBlockData { } } - #[inline(always)] + #[inline] pub fn take_edge_counters( &mut self, ) -> Option> { @@ -476,6 +476,9 @@ impl std::fmt::Debug for BcbBranch { } } +// Returns the `Terminator`s non-unwind successors. +// FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and +// `catch_unwind()` handlers. fn bcb_filtered_successors<'a, 'tcx>( body: &'tcx &'a mir::Body<'tcx>, term_kind: &'tcx TerminatorKind<'tcx>, @@ -495,6 +498,7 @@ fn bcb_filtered_successors<'a, 'tcx>( /// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the /// CoverageGraph outside all loops. This supports traversing the BCB CFG in a way that /// ensures a loop is completely traversed before processing Blocks after the end of the loop. +// FIXME(richkadel): Add unit tests for TraversalContext. #[derive(Debug)] pub(crate) struct TraversalContext { /// From one or more backedges returning to a loop header. @@ -644,7 +648,27 @@ fn find_loop_backedges( let num_bcbs = basic_coverage_blocks.num_nodes(); let mut backedges = IndexVec::from_elem_n(Vec::::new(), num_bcbs); - // Identify loops by their backedges + // Identify loops by their backedges. + // + // The computational complexity is bounded by: n(s) x d where `n` is the number of + // `BasicCoverageBlock` nodes (the simplified/reduced representation of the CFG derived from the + // MIR); `s` is the average number of successors per node (which is most likely less than 2, and + // independent of the size of the function, so it can be treated as a constant); + // and `d` is the average number of dominators per node. + // + // The average number of dominators depends on the size and complexity of the function, and + // nodes near the start of the function's control flow graph typically have less dominators + // than nodes near the end of the CFG. Without doing a detailed mathematical analysis, I + // think the resulting complexity has the characteristics of O(n log n). + // + // The overall complexity appears to be comparable to many other MIR transform algorithms, and I + // don't expect that this function is creating a performance hot spot, but if this becomes an + // issue, there may be ways to optimize the `is_dominated_by` algorithm (as indicated by an + // existing `FIXME` comment in that code), or possibly ways to optimize it's usage here, perhaps + // by keeping track of results for visited `BasicCoverageBlock`s if they can be used to short + // circuit downstream `is_dominated_by` checks. + // + // For now, that kind of optimization seems unnecessarily complicated. for (bcb, _) in basic_coverage_blocks.iter_enumerated() { for &successor in &basic_coverage_blocks.successors[bcb] { if basic_coverage_blocks.is_dominated_by(bcb, successor) { diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index c84ccf19213b8..c55349239b034 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -74,9 +74,6 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id()); return; } - // FIXME(richkadel): By comparison, the MIR pass `ConstProp` includes associated constants, - // with functions, methods, and closures. I assume Miri is used for associated constants as - // well. If not, we may need to include them here too. trace!("InstrumentCoverage starting for {:?}", mir_source.def_id()); Instrumentor::new(&self.name(), tcx, mir_body).inject_counters(); @@ -121,7 +118,10 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let mut graphviz_data = debug::GraphvizData::new(); let mut debug_used_expressions = debug::UsedExpressions::new(); - let dump_graphviz = tcx.sess.opts.debugging_opts.dump_mir_graphviz; + let dump_mir = pretty::dump_enabled(tcx, self.pass_name, def_id); + let dump_graphviz = dump_mir && tcx.sess.opts.debugging_opts.dump_mir_graphviz; + let dump_spanview = dump_mir && tcx.sess.opts.debugging_opts.dump_mir_spanview.is_some(); + if dump_graphviz { graphviz_data.enable(); self.coverage_counters.enable_debug(); @@ -139,7 +139,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { &self.basic_coverage_blocks, ); - if pretty::dump_enabled(tcx, self.pass_name, def_id) { + if dump_spanview { debug::dump_coverage_spanview( tcx, self.mir_body, @@ -174,6 +174,13 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { //////////////////////////////////////////////////// // Remove the counter or edge counter from of each `CoverageSpan`s associated // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR. + // + // `Coverage` statements injected from `CoverageSpan`s will include the code regions + // (source code start and end positions) to be counted by the associated counter. + // + // These `CoverageSpan`-associated counters are removed from their associated + // `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph` + // are indirect counters (to be injected next, without associated code regions). self.inject_coverage_span_counters( coverage_spans, &mut graphviz_data, @@ -262,6 +269,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { bug!("Every BasicCoverageBlock should have a Counter or Expression"); }; graphviz_data.add_bcb_coverage_span_with_counter(bcb, &covspan, &counter_kind); + // FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special + // cases? let some_code_region = if self.is_code_region_redundant(bcb, span, body_span) { None } else { @@ -280,6 +289,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { /// /// If this method returns `true`, the counter (which other `Expressions` may depend on) is /// still injected, but without an associated code region. + // FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special cases? fn is_code_region_redundant( &self, bcb: BasicCoverageBlock, diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs index 2fbbc9b675a1e..e86bb96d29c30 100644 --- a/compiler/rustc_mir/src/transform/coverage/query.rs +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -1,5 +1,3 @@ -use super::counters; - use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{Coverage, CoverageInfo, Location}; @@ -44,11 +42,16 @@ struct CoverageVisitor { } impl CoverageVisitor { + /// Updates `num_counters` to the maximum encountered zero-based counter_id plus 1. Note the + /// final computed number of counters should be the number of all `CoverageKind::Counter` + /// statements in the MIR *plus one* for the implicit `ZERO` counter. #[inline(always)] fn update_num_counters(&mut self, counter_id: u32) { self.info.num_counters = std::cmp::max(self.info.num_counters, counter_id + 1); } + /// Computes an expression index for each expression ID, and updates `num_expressions` to the + /// maximum encountered index plus 1. #[inline(always)] fn update_num_expressions(&mut self, expression_id: u32) { let expression_index = u32::MAX - expression_id; @@ -59,10 +62,18 @@ impl CoverageVisitor { if operand_id >= self.info.num_counters { let operand_as_expression_index = u32::MAX - operand_id; if operand_as_expression_index >= self.info.num_expressions { - if operand_id <= counters::MAX_COUNTER_GUARD { - // Since the complete range of counter and expression IDs is not known here, the - // only way to determine if the ID is a counter ID or an expression ID is to - // assume a maximum possible counter ID value. + // The operand ID is outside the known range of counter IDs and also outside the + // known range of expression IDs. In either case, the result of a missing operand + // (if and when used in an expression) will be zero, so from a computation + // perspective, it doesn't matter whether it is interepretted as a counter or an + // expression. + // + // However, the `num_counters` and `num_expressions` query results are used to + // allocate arrays when generating the coverage map (during codegen), so choose + // the type that grows either `num_counters` or `num_expressions` the least. + if operand_id - self.info.num_counters + < operand_as_expression_index - self.info.num_expressions + { self.update_num_counters(operand_id) } else { self.update_num_expressions(operand_id) @@ -100,7 +111,8 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo let mir_body = tcx.optimized_mir(def_id); let mut coverage_visitor = CoverageVisitor { - info: CoverageInfo { num_counters: 0, num_expressions: 0 }, + // num_counters always has at least the `ZERO` counter. + info: CoverageInfo { num_counters: 1, num_expressions: 0 }, add_missing_operands: false, }; diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index 8549ac0e4afd1..cda4fc125442f 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -656,7 +656,9 @@ fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> O // Ignore `Nop`s | StatementKind::Nop => None, - // FIXME(richkadel): Look into a possible issue assigning the span to a + // FIXME(#78546): MIR InstrumentCoverage - Can the source_info.span for `FakeRead` + // statements be more consistent? + // // FakeReadCause::ForGuardBinding, in this example: // match somenum { // x if x < 1 => { ... } @@ -669,15 +671,7 @@ fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> O // _4 = &_1; (at the span for the first `x`) // and `_1` is the `Place` for `somenum`. // - // The arm code BasicBlock already has its own assignment for `x` itself, `_3 = 1`, and I've - // decided it's reasonable for that span (even though outside the arm code) to be part of - // the counted coverage of the arm code execution, but I can't justify including the literal - // `1` in the arm code. I'm pretty sure that, if the `FakeRead(ForGuardBinding)` has a - // purpose in codegen, it's probably in the right BasicBlock, but if so, the `Statement`s - // `source_info.span` can't be right. - // - // Consider correcting the span assignment, assuming there is a better solution, and see if - // the following pattern can be removed here: + // If and when the Issue is resolved, remove this special case match pattern: StatementKind::FakeRead(cause, _) if cause == FakeReadCause::ForGuardBinding => None, // Retain spans from all other statements @@ -710,13 +704,7 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) - // `FalseEdge`. | TerminatorKind::FalseEdge { .. } => None, - // FIXME(richkadel): Note that `Goto` was initially filtered out (by returning `None`, as - // with the `TerminatorKind`s above) because its `Span` was way to broad to be beneficial, - // and, at the time, `Goto` didn't seem to provide any additional contributions to the - // coverage analysis. Upon further review, `Goto` terminated blocks do appear to benefit - // the coverage analysis, and the BCB CFG. To overcome the issues with the `Spans`, the - // coverage algorithms--and the final coverage map generation--include some exceptional - // behaviors. + // FIXME(#78542): Can spans for `TerminatorKind::Goto` be improved to avoid special cases? // // `Goto`s are often the targets of `SwitchInt` branches, and certain important // optimizations to replace some `Counter`s with `Expression`s require a separate @@ -750,7 +738,7 @@ fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) - } } -#[inline(always)] +#[inline] fn function_source_span(span: Span, body_span: Span) -> Span { let span = original_sp(span, body_span).with_ctxt(SyntaxContext::root()); if body_span.contains(span) { span } else { body_span } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 578caf2192d5f..34161ecea355b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -887,12 +887,15 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED], "exclude the pass number when dumping MIR (used in tests) (default: no)"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], - "in addition to `.mir` files, create graphviz `.dot` files (default: no)"), + "in addition to `.mir` files, create graphviz `.dot` files (and with \ + `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived \ + coverage graph) (default: no)"), dump_mir_spanview: Option = (None, parse_mir_spanview, [UNTRACKED], "in addition to `.mir` files, create `.html` files to view spans for \ all `statement`s (including terminators), only `terminator` spans, or \ computed `block` spans (one span encompassing a block's terminator and \ - all statements)."), + all statements). If `-Z instrument-coverage` is also enabled, create \ + an additional `.html` file showing the computed coverage spans."), emit_future_incompat_report: bool = (false, parse_bool, [UNTRACKED], "emits a future-incompatibility report for lints (RFC 2834)"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/Makefile b/src/test/run-make-fulldeps/coverage-spanview-base/Makefile index ecb5275e716fe..ec93ca4725e37 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/Makefile +++ b/src/test/run-make-fulldeps/coverage-spanview-base/Makefile @@ -26,6 +26,7 @@ endif -Zinstrument-coverage \ -Clink-dead-code=$(LINK_DEAD_CODE) \ -Zdump-mir=InstrumentCoverage \ + -Zdump-mir-spanview \ -Zdump-mir-dir="$(TMPDIR)"/mir_dump.$@ for path in "$(TMPDIR)"/mir_dump.$@/*; do \ diff --git a/src/test/run-make-fulldeps/coverage/coverage_tools.mk b/src/test/run-make-fulldeps/coverage/coverage_tools.mk index ad5f465c54f4a..17f7696a8cf1d 100644 --- a/src/test/run-make-fulldeps/coverage/coverage_tools.mk +++ b/src/test/run-make-fulldeps/coverage/coverage_tools.mk @@ -37,3 +37,8 @@ endif # tests can be simplified to always test with `-C link-dead-code`. UNAME = $(shell uname) + +# FIXME(richkadel): Can any of the features tested by `run-make-fulldeps/coverage-*` tests be tested +# just as completely by more focused unit tests of the code logic itself, to reduce the number of +# test result files generated and maintained, and to help identify specific test failures and root +# causes more easily? From 87f28978c532547df7e8d746ad98f863a202bab0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 1 Nov 2020 16:40:48 +0100 Subject: [PATCH 21/27] Improve code in unindent_comment a bit more --- src/librustdoc/passes/unindent_comments.rs | 43 +++++++++++----------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs index 4f7297c90c5c9..51c380f438cc9 100644 --- a/src/librustdoc/passes/unindent_comments.rs +++ b/src/librustdoc/passes/unindent_comments.rs @@ -46,7 +46,7 @@ fn unindent_fragments(docs: &mut Vec) { // #[doc = "another"] // // In this case, you want "hello! another" and not "hello! another". - let add = if !docs.windows(2).all(|arr| arr[0].kind == arr[1].kind) + let add = if docs.windows(2).any(|arr| arr[0].kind != arr[1].kind) && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) { // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to @@ -87,27 +87,28 @@ fn unindent_fragments(docs: &mut Vec) { }; for fragment in docs { - let lines: Vec<_> = fragment.doc.lines().collect(); + if fragment.doc.lines().count() == 0 { + continue; + } - if !lines.is_empty() { - let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { - min_indent - add - } else { - min_indent - }; + let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { + min_indent - add + } else { + min_indent + }; - fragment.doc = lines - .iter() - .map(|&line| { - if line.chars().all(|c| c.is_whitespace()) { - line.to_string() - } else { - assert!(line.len() >= min_indent); - line[min_indent..].to_string() - } - }) - .collect::>() - .join("\n"); - } + fragment.doc = fragment + .doc + .lines() + .map(|line| { + if line.chars().all(|c| c.is_whitespace()) { + line.to_string() + } else { + assert!(line.len() >= min_indent); + line[min_indent..].to_string() + } + }) + .collect::>() + .join("\n"); } } From c0cbf6368d3bf0620d4b7ce9cdf0c37cc31ce49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 2 Nov 2020 00:00:00 +0000 Subject: [PATCH 22/27] inliner: Remove redundant loop No functional changes intended. --- compiler/rustc_mir/src/transform/inline.rs | 137 +++++++++------------ 1 file changed, 60 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 944f41c61a2b5..010a7470ccd38 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -93,96 +93,79 @@ impl Inliner<'tcx> { return; } - let mut local_change; let mut changed = false; + while let Some(callsite) = callsites.pop_front() { + debug!("checking whether to inline callsite {:?}", callsite); - loop { - local_change = false; - while let Some(callsite) = callsites.pop_front() { - debug!("checking whether to inline callsite {:?}", callsite); - - if let InstanceDef::Item(_) = callsite.callee.def { - if !self.tcx.is_mir_available(callsite.callee.def_id()) { - debug!( - "checking whether to inline callsite {:?} - MIR unavailable", - callsite, - ); - continue; - } + if let InstanceDef::Item(_) = callsite.callee.def { + if !self.tcx.is_mir_available(callsite.callee.def_id()) { + debug!("checking whether to inline callsite {:?} - MIR unavailable", callsite,); + continue; } + } - let callee_body = if let Some(callee_def_id) = callsite.callee.def_id().as_local() { - let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id); - // Avoid a cycle here by only using `instance_mir` only if we have - // a lower `HirId` than the callee. This ensures that the callee will - // not inline us. This trick only works without incremental compilation. - // So don't do it if that is enabled. Also avoid inlining into generators, - // since their `optimized_mir` is used for layout computation, which can - // create a cycle, even when no attempt is made to inline the function - // in the other direction. - if !self.tcx.dep_graph.is_fully_enabled() - && self_hir_id < callee_hir_id - && caller_body.generator_kind.is_none() - { - self.tcx.instance_mir(callsite.callee.def) - } else { - continue; - } - } else { - // This cannot result in a cycle since the callee MIR is from another crate - // and is already optimized. + let callee_body = if let Some(callee_def_id) = callsite.callee.def_id().as_local() { + let callee_hir_id = self.tcx.hir().local_def_id_to_hir_id(callee_def_id); + // Avoid a cycle here by only using `instance_mir` only if we have + // a lower `HirId` than the callee. This ensures that the callee will + // not inline us. This trick only works without incremental compilation. + // So don't do it if that is enabled. Also avoid inlining into generators, + // since their `optimized_mir` is used for layout computation, which can + // create a cycle, even when no attempt is made to inline the function + // in the other direction. + if !self.tcx.dep_graph.is_fully_enabled() + && self_hir_id < callee_hir_id + && caller_body.generator_kind.is_none() + { self.tcx.instance_mir(callsite.callee.def) - }; - - let callee_body: &Body<'tcx> = &*callee_body; - - let callee_body = if self.consider_optimizing(callsite, callee_body) { - self.tcx.subst_and_normalize_erasing_regions( - &callsite.callee.substs, - self.param_env, - callee_body, - ) } else { continue; - }; + } + } else { + // This cannot result in a cycle since the callee MIR is from another crate + // and is already optimized. + self.tcx.instance_mir(callsite.callee.def) + }; - // Copy only unevaluated constants from the callee_body into the caller_body. - // Although we are only pushing `ConstKind::Unevaluated` consts to - // `required_consts`, here we may not only have `ConstKind::Unevaluated` - // because we are calling `subst_and_normalize_erasing_regions`. - caller_body.required_consts.extend( - callee_body.required_consts.iter().copied().filter(|&constant| { - matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)) - }), - ); + let callee_body: &Body<'tcx> = &*callee_body; - let start = caller_body.basic_blocks().len(); - debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body); - if !self.inline_call(callsite, caller_body, callee_body) { - debug!("attempting to inline callsite {:?} - failure", callsite); - continue; - } - debug!("attempting to inline callsite {:?} - success", callsite); - - // Add callsites from inlined function - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { - if let Some(new_callsite) = - self.get_valid_function_call(bb, bb_data, caller_body) - { - // Don't inline the same function multiple times. - if callsite.callee != new_callsite.callee { - callsites.push_back(new_callsite); - } + let callee_body = if self.consider_optimizing(callsite, callee_body) { + self.tcx.subst_and_normalize_erasing_regions( + &callsite.callee.substs, + self.param_env, + callee_body, + ) + } else { + continue; + }; + + // Copy only unevaluated constants from the callee_body into the caller_body. + // Although we are only pushing `ConstKind::Unevaluated` consts to + // `required_consts`, here we may not only have `ConstKind::Unevaluated` + // because we are calling `subst_and_normalize_erasing_regions`. + caller_body.required_consts.extend(callee_body.required_consts.iter().copied().filter( + |&constant| matches!(constant.literal.val, ConstKind::Unevaluated(_, _, _)), + )); + + let start = caller_body.basic_blocks().len(); + debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body); + if !self.inline_call(callsite, caller_body, callee_body) { + debug!("attempting to inline callsite {:?} - failure", callsite); + continue; + } + debug!("attempting to inline callsite {:?} - success", callsite); + + // Add callsites from inlined function + for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { + if let Some(new_callsite) = self.get_valid_function_call(bb, bb_data, caller_body) { + // Don't inline the same function multiple times. + if callsite.callee != new_callsite.callee { + callsites.push_back(new_callsite); } } - - local_change = true; - changed = true; } - if !local_change { - break; - } + changed = true; } // Simplify if we inlined anything. From a8dfb26b620c71756251d65db14ff7cbdfc7439c Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Sat, 31 Oct 2020 16:39:09 -0700 Subject: [PATCH 23/27] Document -Zinstrument-coverage --- .../compiler-flags/img/llvm-cov-show-01.png | Bin 0 -> 416748 bytes .../source-based-code-coverage.md | 160 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/img/llvm-cov-show-01.png create mode 100644 src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md diff --git a/src/doc/unstable-book/src/compiler-flags/img/llvm-cov-show-01.png b/src/doc/unstable-book/src/compiler-flags/img/llvm-cov-show-01.png new file mode 100644 index 0000000000000000000000000000000000000000..35f04594347a398ca8321faf85fa018b192fa843 GIT binary patch literal 416748 zcma&N1ymeMw>FHs4DK*MAi)X2VFnEnG`J2B+}+(L5G)Yf-3jhakPsj^!Ciy9|C4jx zE9<}Kto8Nko~|kHs$ILDE%i}ZQ5qYA90Lvx4qH}6QUwkUwGR#sSp^LR7UPgAh6e|S zv1TbDp)4yQ0aSLfH?y=cg@cp%_$3KdEq;hNVCQ*KLOdV@O$NOkeF7cGZ~^zODi{B= zs5ts-WaQSGrl7JQC|V+s7Ll@pE3ye26qzLgV~)h+y>ezGG6nN7Dz%aOisx~L`&h~k zce|rSF7s^>cQ|0UL*F`<7IJ`moIF0>>IgJa$#B&VRWdsq%T;vSq2PmtmKK_*iPuwE z+cC<|KA!=rp4ralXM?v<14&Ns0r+@|+p^6mXpM9mM4GH|@BxAmyVyxXeFQ!vMyW`$ zfVFOP#f)_hf^^{_i!ZWi#b`7kQE*-H{FJiHa4#q%#|F0x>HK7j&=#N`;&?sQcvq_! z{K6q|O@@kQW-~~*^fqC0k?_DtfEnZSkomsB!%LP2XZ{k5%u;KWlMe9`{^0m?f4hUo5(qnteXn+N;RU?q@WSK5~UvQbN-I*h1MJTA#@rMec?PKltc1*o?dn09ILfNPtM5it0&XhK527~ zOk51El2OovLg-?YH^)ejJ;wSjHK#I}9#z}L8$MLX1Bi-?Gv36D81$u{GDWFw_HW$Z zjm$~1{Qkye|CZHJD!C^!3orYpTrEA3wdvqmx;91OTranx@*HL1Pky^R{$?zS#aF8Ip6Y5W5fRNxp0MSIq1<-g9za}_27IhOfR1{BHI030ZoK6O(B7|2o zRQa_U&SAJ!c2-XOPk~*GDfFfAyKLHB>r&_UxvM+|wL%RHX2tN4ko5N{T57<$1X#&W z{Ha)8y+Ol_e%WdYD?uhWnOPxm9dM=a<_~6Rfko}RD`N#l-|C_E&;2tyCT-7dc_Hf z_D;xK+USs1#JYvdh*7-PRCQO5d2dh&$??-^Pm0b>`}ykv>rUhDwHM#xIctV?x%Pv0 zn%VSN3+N!Y-v*llyF)5aDp)G1-&`TAFw3mPEY2)`+nB8`F;t^zhO44ohonBteA29S zWP6l7+1KU@(N=3gTu9tI)a}ca>*0GU{R}v&>QVNLbHUyg7k!Q;?j`)CH!TugY9L%t z4&>vqb~_1{D@tTs_bX#P!%w@`2dMkQm)8gGyD?MFSBg-)g=$l-BOo z7V3s;RW;hx`0>nI*!3*tHXk~7{^FlEnNwR3u2ZkYuF)Af z+28T&sXn*>amA>r7bIP};WH2wZ5wTnk)H8F@lsJ@RBBXqv^B#!ncIxi`OSF^X8*SZ z)2LylB&ABlO0HSsO8+M9=7QGg7VObC83S3GpsJOnu8fV2mG;@-wYbgGJn5>Uj+XI|A!2>cPB z)t&{PCa=WM-aMFe=jbe}lP%AK60P+~oSnRld`!OXkQ^mzz3AuRhZg5V1Eimc~Gw$u}Vd=?wJ115C$s#6Siv44Gln>1oRXxwX zQJr?3a0^=)emtov!8z>=Uju&wpPk)eX_NJ-&S}rhHj@? z9YUSS&%)n81^lL*(;!#x{n##5WoA<1JG9}@s!4>&s{&scTm_M2a3)^bc?V6=Y-9U`x)JB!+U4|@0>Rhji0spY^-kU2nhNetyV|vZJ{6jd_CH_zp1ME41?Z zvaAy6vDGoLvOUzKwBGLHHi#rVa&|D7$_;1~Rd_cVHGXVxCGjMtV%A_AWjk5{`+FOs z=jCT_E=4m4RVD}~94*K$GOhg5C03bf8@8Bj&^P#wyroaHOoZK9?`}W;XoPD&cGwQ_ zKDgfd&9ZoXE4>zTeTDklzMQ*+wW3GER1;JdU1InA@m6&Nz5+26wS$_F>NkkcaaTOb zSwW$~?Qll0NfE;5!hd>FLEj;rdQh={&G(Z6BPJ;CERVxa@viw^>!iA2%(_YFkznm0xu>Mj#@hKYh+C)6e#F6-c+C{ev`PVe>$W40 z$3E-ssD>fZlPGtqoke!r;%*L^$({|@Q_WPsyN@V?vrSYX}FMMyWTqisBWfaH4Ntv0$$Qx?`|VDi3&G3Gqw~YoC+@SoUO&6%;gy0;f3iVu zDL;)ny<^Xj?4{Kb+UFcy4&n|{4<~oQL_kN!j*c#L3Q9o2eIMY zzRA`0ub3{3|%bzv2<#;KD88kp7cL5%&Ib#loIH zW&VC6ehz~}h5f^aJs#Nz|CJlHFB|c{!pJb>4F@NtDj_Qid#f5dnVQ-;TiCli#R5OT zBG4UVw4LGLh#CGo@Uki|PGI%VS*mHdXer1G8r$2l8=2UDFlG0!b@)>coUn%=ENE-$ zVg&TCwXt&+^Z?QQl|v8~{u9kX2mC9Gi#3Q&OFr-(OI~-I0$lZxVyWvyT4(#cQWUAEg&Gk!O6wJ#l;58!RG8~=VIi+X6H=* zcP0N-kEE%yv6H2Pi>19C@K3!)AM9OSKy-9}8v5_+?|zzkSpH8-cFzC#EZ7Hf{7K<> z&Cbd3-*v-^3jc`}RJQamwb7Eaw1tfstPSvM0e*hrzY6@Hr2lF1@1p9?rcM&}wy=^e z;Qtx*{}le;iU0qCf3>OozuJ7m%k{t8{9j4`DJsnI=iC3+So}TEf5pN^8jK;#@!zus z#%Rbwm4i(rrKO~j8te@tvp*L?3GC<9-)~qLkv#3gJ&7Y6oG6^Eq?noq{O=6Z1j28` zVVIImQZ=80fd~jebngI?YJ_;muLJIW+=7T|NdeBpMDnE2AcQ+fy!WEA7@rwl4hhJF zUGH-gUn$yO%a7TN9sNFAadsf`U(_ z`u9`wOZN#;@di1D5cLkx%pd#sjdK6#4Vj|h#`2@p=@rPVl_zpr^V>OPmNJc*&3wrf zwV=(i=E<`7upg4gr(U7LvghTZC$NLe)?kj>CEabWbuwEV9D3|O-lA9tObk#yDzL(1 zgJbyKS$=d;Sr`N6z^>nw&ck#Kw$%zPi~9YsZe_Z_l&Si=TTKVH?(pZS@yrzNjFhgwZVBX=V-4FQZ8d&H|XSKy`GNd&f%h zCX0-{<()e+k7hsOerr-ajnm1GW;|G|x^Awu9%+V;gfF{{DUaa4uN+Ieo}9#8FFx{R zQP^$RME$A%AMad1Hjo-wQHs51r(5_q3cGD6n+AW4$nUI6*6MbYKGWd{TN&U^@DbE$ zx&nW>o4`=`0sBzfLum=4TJr-o{$MUrg#S(ad;#b#mkecZ(RE*Te>_ZGt$Ty)7d<%( zyBs#cY;;B$3LBUXYOG9}8G1Ueb9kt8`UYeD)G7W_M7K%fvBj>H=}xIVqSPwR$H}o! z$$Z*4z4Vxguxi$O zqN>~HD=VP_{@ylnQuybJ#b!-)ij&9^{Sswx{a5SB0P7lZbQ2JQ7?NYFrst)vsp8HX z^-yt7TReYRAOpHGKq;zs!t{p?kIx>;WD4z0Mya404)r4={S~kbW4+`qQ(R1#epJUU z_@9SWrYlnP9s0WQ(|j(m?Sk!{=iB;;{gAegTNfAe<7yo7LHr>HNu%X!3tJnPXB5^+ z*ZS-vi#(2jUhYQ*g}c8Pr>A@`S-yWuR}2s>^|Mek)NH~)?|T76cJv5bP$NDe&+5Fi z=TY|lWw-3zWm)uu9y*mUOwN))mnen6Bo`3mVMR%fu|6b#1MBG7e)$)xT`3R^AG>6^Ia zwU*rrbrEiw;en9*Oko5Sz;mfS$W<(qfR4A}_@@!_`-3#1wDdD0+k?`pFYg4;(}96% z^sqVOiAF;{-K0eAD0&gjqRa3vjApO}=`%aD*V$oaTffxwR)+R!b?upHlmDV7UBIdD zkm_l+vfb(`v2(hH%6lpr5mo)ygQuDR70$ztiMI$lbxZy?UsKB#k~ygbjFWS-dAbc(USv2tcLto8?!dkw#V;pown3?B8WLZfabct;?9w1J?RZFQKlVh z+G^-tQLF7}zRD>j1b;Sni5guK)JfX#v4T_~~G$=GO#SqPOck~;tu8$s5 z9{9Yy_oorge*&kHkPBp0>nG4A9eh#{Qls*%%*?6E0NUoXU*3^!2oAVH_udJb@XpP= z`n(ddFP)(k_BdB@4;R0)RfjF)vLG}qMw}kA6Tgx5zuu@Id|KOZZCY-jL@w9 zmTLLw;&UkCwRGnFu>0ZrB0?4m7`MLb!0+ps&ytL(ZjJevXn1JiPzY@(cAv@ zYB*OR+)+vF9?kRd;O=mH3GTX%@eX$^#RKUS@$NS0I*92Gf;2YcJWRs3BW)Hk*?*2U zKz+>YdRbfczN80ZOhZrC1E&XIieft9U|&Csx$E8G-CWVCx)T0ev>>S1_#W7QE|Yof z;kVY(eNH&(7iQjhh`PUcG3j%;@qaoFtJ1rj>SAsd)Z$4@y>2wqTewF z{|rB0JL`Pw%l(b?`eQzR^TS){Jk9UN?F}!MrFxc&{C;RDHG$Z# z`)zU`XlQm=D~ zwWTC_QM6D2N_tz(5~?3OsV80rr2lw+nD;L59^mk-?ww` zKsq_(dQoY7*8;s1e|?b37W7=LG6S7FEBI3;(u^Aj*S3h$v`~%2*fH<>AM;ifREjjG zXYh0aq`mhyB4dtfu(i=`eLej^t}VnQi@YYMUapsO0!Qn`=lnBy9D;0CR7~8tALwoe z??-hjj*?Hz``m&yjeJeMf4E$yVfo=T#$8g{upfxRF(%B#LD8z^ee1W}5`8?dy<^6z znZ>SEM!XlZ;pdhCrUnT9Hbm|8;(Ov&x}3G`zN;^;(Akffw(U%*OxzVCuxpi!WRw^y zJ7Cuk*%KpnSJcWTwz(G?;UW}$)goI&;c-}=nmKH{w&1K$a{rR;OxS=^%P=3TWQ>i0 zZtVZ_&vIKLxlh}@Wt=@f12i7;-8-drTpx1QlBf%cVcYADv8(L0qhy3#NakJ>{z5^D z%A8Cr1`B3{tblS#iM>!7OROcOn=8}%;bIk6#wI@O#feEfkrf(%%EDUOM`e%Jp|_IP z15(dj?c0h}-#ap>Um>?zHuf-QKYErGc6nEvfPzEmfV^^ovq8wmXjw z?eFj`OaZBmXm~|eHU!n#4lB*JMIM}^TDEp>EfbASrVTUBTb^Qv%(Oj00Uv%%k4#Kq zmca!rRct(~(HuO<^nwnn!_@qo9xf8cpel4<)ia_n2jN*PYLD$U`Y^0Aq)@vY^Z_`4BqgcF#X5Gvo{d zL=A(tBfb~yGfV)2dwa0vkAe(Ik4x%10W67@taC-?9KqVI=+!q+U2_PhSXqv%*$wLtj8^@m zId2mdTKl!+wRs#JYkbh^e>!ec{>1Z=rp2`W)cQO$ZLkz#|HX}aQtR$wRQ6ZHf{ zt)`*rF0E{uvyz1enPqLxS@O5Gj*?zhbqwM6=+K zJ1|#i@4qy_{AYPYGC~`v1@xl~yhC&+x!z7GC2`lJY5dRPSU_n@(zP}+$pssH_=W2A zHCET7<^ao}r5h{ZlwiuX9g}6h8{X@yf{x{hOcZQQV63|d0lvq^llTM73F{BR`dvnDonK@2zsW`U z?13(r>j01&K@J}}yIjvkx2OyeanA1%!qHk*ja*ztr~_q}o|VV`MpM*qN3WZl=ZT;flWQt02J zaOdx1!W6!>xGOwN;t_dgLf(3dl2j|C8u;`L_{lnZAJen4hyyiejK1R)Uc!$o;fQyg zhBobzu&YLZ=E8_*SFx8$te6N=DQKth-osHZ!lps^u4@(N@X@+4>MC<~;6XfN@@Af9 zhaZxon&4uy%xTWJ_j2uk}uSS=!+U zAtda;?O2uXQ<`~Vo>EqNnwu!Rc<3;1dVgPt?hQJ#as;Drd-w)XpRG43CH%2v2*ab( zFO*R0Uh>hMmlwAiysfx{3Ne>>6GQ`U@mHe{Vk@`~M++_pe!(0zX)2-(JLrjP8zMaj z5?W$SlYa9o)Hy0k?+MAVGCl~$RpV4v?Ti)MiKlPOi(5Q>yz}ytSm6NRz{WqxS5$~^ zin*%MU_PWEGjHti-cNtmgHK#5d^SC6r`3if?y>vI$OtXLVt|@OzBee--U%ckMv3VD z-A8yC5B0SSO0a2p!8Li^;VR#_cZ4k>q^8MSH`oKMx*;E&iI(ayg8nL zYz%HtvrN_L;ZDM^o)OymUUO01Y>D^@RPexuJI1FGCpi8 zc{e~R?@(2b64)HR9eBa1)!?vTxAEm+ucy9L^~;1Ml4Bc5=wl`wvSXX^1_bexG%j@i zfO9MSqIKKlF>}ekn|xX)3lS2;zkJ|!@T41$NVjncXgn~eTzT`=_rmyV^hv<|mwNCW z=+xjYg$^v#zsmsVN86eQR;nQGHaD!4+-Li)py@%l`m%N#DRoI>2MxI*ABzgvHd@xDfnG_y&Y6Ue_gvSIR z&Zn22RC7aRr8+G*460&RkK8sJ}R9r`R0; zdVv@;+#}eS0hx%2+b5eI0JLGnqT%I(%r45~PA;cvMyJ>oW(l{K_Jq4ypVxKqC`D2v z?K_VvQ3eg9QPsiG?lFK)y2dp2DL1E4DDisn(VguUzKGL*55h=r^L=1shREVN)@=}T zz7Mme*h4eCA;pdYmy1MK%p5z1nxJRi0I{^p4g0DO4Yt%b!cc8oLF#T+z1@K zuF+_lFNq$^9X?gKR}<^mHd!pvlp{ zcVC#JMxv8!?`mg;hB|f(-8U|oDdV1AEUN-3XUK$y>}DjLL@N!g0fRcxHzRmP@1yGg zfcbn`4&}Bn;Ci5s8Er(Lr*wNsb*7KvklTb%l(C)$nwLkzS_eILi3AF}&JH1i9Kann z@!X5XO96MPD_elnqoQT|ckx+TM(aJ!M%gl}@hodM~rVJW5YZvvGmy~4csF3xQ0 zOlp3z+b|PiCP^usQq;5NtVrp^r*je54#fn`Gu1;is4uIERnnUm1jX*gj0hpNCw+e< z1w$U!2VeKvT`b%z`Sx5;c%$GZ4j&vG5u4|*vRfZ5bjTLNciaTttY=2wAD7(u8RfAU zZb^z4PD%(P2$}!0LJ6kx>0^M>PqB*Qc7UzF5Rhvg5eYNWa;_r!G$V;O^s_*-ZibMg z6QUTQ!{G0hWFPQp?D$;lkC?Pvel{boZ6R2fg<5QmCc?1FW~&rfyb&Z~++z3$SRzu2~g`-JsvOQdQUG_3c_3$<@8d z{94e+$3iMi#iGy03}YQa<4jAP^ssBbv*;X|zUvGqd%ddp@=T&mjLZ(6Y?iFD5f}z9 zNaSj#V_gllSnxX2#9%$al2$|Dhz~Y#s8~mAO)4<=H}U?%**V6~6)I6NnQ|9Ty4;hmm2dfg0iz=7vxFwS65r zCNq?#gzC}1&Km>eboCY~nB-t;n7qjHM+T&u4cdx22h^)0oVE=%$I9B5WRy(=vR7dW z-#6;5^k6C1_;wxZP}S$J7d!Z2%i{B! zfRTfiF0Zk@>+=EEI&ACeWtvS3hZ z6^~)2El@kVZ9A|NM%OC8D^%OEua+xmWL`A*?iHN#fIYbl=$-s=K~v z@j*AW^WIzF!*A=ndu$$oIH%Z-eYPAA)q1WaI*d_`Y;7uQflLxw^e_0^YCoiy5Gs7C zJM8kl`kfb4d(qV}d{}jF%mto6J@uo^X^)&&hq5`n6WhW#w7mN@{&jOA@;djOAfNpL zJ>}Mb0f)W$g8c(s{wed}W3yBw+WhS(sc>aEAGg!w=#fu<95VIuRzuq;YK*#YB+%tI z*keu`W!Wyq#5`vViC=rnO?S(Niv8Dc*);n=)de7Yc2<%K)HR%c{l#Dowl@ir%~}|F zg+_-2ocGR42-a~TVUdcL-o53E{UBFvY`DJApfgr6!u;bILyrWXzuv4g!8HYMiE7D;5!07eKlpF6i5pm{+ZYNs5DIUh;CHoBjjN&&;N!dTDm7+25<@iae7y=3@l%8_Q=Y z#LeY9l`EI=%a7d+i@Xxj3tghfHWXvHmUBDTx>FiWRbJYpI~0}Aaq}DM85 zWj8Z}tS51PdZ@1;0^<6HIp+qX8XYm$xe|CYtvxzCQz(UFS;h1^iVQh>4XJ4Rhd1xz zlTKd3H&fFYtJvO>nP`8O9 z#v3BjYg}ES4#~5qe78BC*-u*7jCS!fsbkZR_cI&4nch^_ZG9EP1jemre1s{UX`Tfq?{ zn0bFrvx$%Wl@bvHh~JD%SNr*fL~avjL!x$0uTcJ-*u(dIQ^K=o@05%5v-1vcV_l$kE=af0WyIuhT>HhJq5gY~Za zthK&~e?lX_v|uMw#rkKJ)yL>^gh*bvqBt<>Z_qFsbXd$`9A)RB`1}X`H#Ao5pr*DM zVGkXKOSO$sGw&n+*{HNKutC!(;Y&F{IEi4}xY3GrmFK4CH5Zu}=N8bAvJlXgku(*s5JqGfA{ z9PgI=j-P#bO8*=G>!^x!r|Yf}eZGbZAJi_)Cno%UjAg;CZiT9a<|Wkcp}4SpI@R9JkX@su z`sQ1jLg%K&>%lelZ`9WV?-rtGs|Y(xwTwd$`rV9XEsmKy-gh_r7Rvr3!N|9^KjNtn zK#os%u|5C>0H2q~dTxIHo^_M@A}7`@CtUp~YNv?R7tky*6ufP^GNNX{aozd!BVwHf zh1swxC`op0$CB;t;^(@OFiH-}Y#mYW;=%eu@IXe=4*yJGY$6nfs|kK(N#1?_1e0cQ zj0*SPpFZ;+wm_{5QZq%gi#+(>O7ET2a#nRq9y8V0bB$HAHcpZfBAyl$5a%tNCnd5p0s}`vN31Ppcgv=lBiHQ!nv$3fopK=~CIc00q6~8)krM@}Vu;tZS3~C~D zImHR2JcTeyxWj0|9^}*#pSx{J<@cbNb+Uo0r2Shm?zE*S{4|s9o4n-vZbNtu2}K9A zCC<&>%&K#vdu_TP4;YqXrZOHz$$7wA>$3kzjdUhWp}~u&^IOob^FNy?P`$Hb(8&|$ zTf78iToNE~X!rri(bKoz>p9^u7kKnG#q?jKl1p?X;yzm5cCdB95C?NFEh0Rao7P4! zM9xQ8acZ5Y@6ZiEO+@p!Rxz zr;X|Dc2xQ4#xbz=QgO;3dT`vsV|8}-ww1tGKk>Q1xMus7iSHT1m&pgQZ65By@1w<_ zO)ms-0G^0FUDmKM;CrbDLKoa9UK2g?&mf)p&z5Cp3iU4NUeL2aSA5g}A`-YAq*bU! zTHX@U7EMZ$7NRC7`HICV{GH5SI2tFCGO8<$xA}tgRi$MG=hD43VJ8cAig6K7fL*s8<})tvleujSQSUaeR#5)l^-#&GA)9duv#-< zd(?K0v|1+WzUG;*O*M)@D2yQ9_G)XU=P0so!`KetYiMSmn1o*<6iEG-sH;`eeZS;= z{-k2S`YSt@u75Zd1umFBPkS!tMg=5uA_;f`;gt?9Ks@{@M5U09NU$U9#&g&Ozt{k#PJdn7|Z@6JBuXVZGX5ic3|Qj4Iky%Kv^ zS_;cyHa_QLUg+7E%OH&PN0;agJD%ZryB8Oj_NpN;PlXS8UJ6A%u{jnZGqmfi`^u*? zivokaH#Z!|97exm4y~o0-vz$L6BGVz%{lJp(zF&nJ@Cm%n^XZQC_aEJ* zba@0Cc@w)KOaxZ$*{kNfGG97+#0b{Bv!b=VT#**n83yw(Yilj3U%$v0&8rh!j#i5! zQZdn4X2EYSN*DB~IsYBw*1=0E_zjP8DTsd*KHo6lErH8xQrsRv*iPZWmr=F6o#S6D z#sGrr6*9TI6hy{yn(1v5?&F{WO@1s4*84%)waLq5;*E_IOWo^tENG!xSSu?vc=7j^ zakOE$b4>#-caF55UBB_V%<1SbO-R!kEB=anYO2ZiW~b>;H@8#8Bbre;?@{v-xJVsO zoTBj7Tl)GOfXZPrmTHhn>%cx|pI*@)yN83W_%E&&S9E|zAiKMN)YA!$QX)*l9RWzQ z$v|PiEJ?G@Dy}Tn5TxsC(m#5_mH;H#!fa9EpPkN!6S_f0I}?;6iPaJlp(%nDX(Z2zQY*Qg?H+@iT4F zo|RzT?=8pe-H_G$dKOdB>-gc)n%l{Ur_r#BkPF5>SHWguF4; zCOmHZ`^YBARY5*nTqz572%O zKn?#aI1)>RwUcxW>A3!op+&t;Dr&jHpe$lvnZ6AUhQ9tc-=@GRhFEs7#Uo;{iGQP2 zq?h&8JLDLq#&2ib4VS&deOstX(0YJvfvo+jgw{}8T}_N-h*95`lSoxbmMhLIZ(d;< zV>_68!S?O_7l>vt$w3~~ejf{zUhid3jqd$+&m^I6+ae>#9oY8!XHZ}g1M^h~19YXT zJrb}_v%RAq9y>||&R7k}jbVTugFR%39#>yZn$`L85#>I_i_@2i^+6mJYF}CB>rZJ$ z;<#I!is|?tK4RG)S-|uSQ@WMyo!^^Yn!SlE$Dw2-gYKQG5>XK+qt+r4)fONSj z4B#KioqlJ@s=de#xqi|1YSI`+%^#_a-B$=eE1O>9!gfmwwdY0#e*sqipoj0fB!m8+ zga>B;o=A|vnL@~n*0e}YY(~^Q-}qykz}GFQv_z)dZz&l2>+cv8S^&+ggD#{yX>I-s zwh;BaPj|&zOm4g*_FC730&scJqt+t&(j1Oy7r*XM|oeD!89TK=P-@ugf7qt=XbS~`joLCN&Uj6Q1Yxd#)LT#AHKW+C+R61 zC+&#$+L>PCMVhytwjqjoZU)I%IrS?Mx4)qYpG2ppz}yBlXmFJnG}kq@`NVLS`I!pI z@z(F?auHSJw!Gh`-2FgNaQ~+am9NY^GnH(9ozfklcFg2I!xB-16lox#n4X(|`{*|e zJgoKj5!b`(HMPoc%iGtyI!8*a%ailgrL|YdrSG{r*&=Ry_hN|l*O(#|QZ#8!;Hhci zDy|2y=dCZOl4f_6bOyo4#j#OgZNl=KsEv}yjy|!ib?=y_D|^s0Gc9fc{D&I-`7;~* zXzu9Yc2i)erJO^gC1{~fPATT(Ny-E+B(`z!sLJ5|rIpG^yXBj#;yHTcFBc*5(qPN4 zp|s{l!WqMaxj{T07*D#A_@bVyVwA4=hF2BDier~(B9UI>@)%LYNhv}6;vy1+cj2E@ zCakGxreL~My{+-i856KK#~66iRK)m3Z2*(t0H)tFC>tA6BB|ghA&+h79v*%63cGW> zjDr_)KM+0x7~~JZbH952YHI81ihca`kavvbEY6^?N|z&^=GPj*ZC&5Qey4gA_gYw|7T8`#f%yv@>z!?A*sIfU zXytJ#e;dYMqVWXNi`+&Dst?)f0Ojm6S73HE&*z4FN;!aZI}Gdk@6|D>gP*_IY5XzX zhoW)L01122bi6!TU<>8T_-oE$+%d65)QV<$^cQk~fq;CK`Qd3C`JP(hF+Ix(dJ33{ zpy|h0v>F^K5<^z#%D&ngkAbf+Tk3H7UNPU-krK-zf2I9mp>~%GD$;p_$wNwYwX7^Z z#(U(^NtaaOTgo$Cj{lh5@QzdY-SOTJfmY#%-FJ&I)h|75S6Zd?l@01aB}l}#I$kTP zHNilzth9nfWtF>iR=Rh@zRF=1e6YvMu68wYWJlTHf1$)!U$hW*s4h2vd|(e(;lygW zq*weo8#!2uxC&?|a@8$_dmCVFX_PDfw8-f5yHPMd2Rkj|5L_lgM~|Abun3tYu@EDt zEjp)kPfyJi$)_!E;juwo4zRWxj?J%v)e7`r z60O#FMdgE9l5AFt&s2>$;r7?>=6sD=7DAyb zlGmu$K*`1?)o>(x&72VPkT57Va{7?Gm~grGyPemy(@AoC{NA5ja24uy9yF-nx88!3 zajr2fVbplv7OEBL4y9|3nH~FNt4Qs+pjduw-ZXb{PTITewZRp&H8wj0PG!ol> zO|J+BJYsk9I~_}rIW-ulH0L*iFHMcH5DLAsRsUk98?!Di(okI_DHi1_OSCmI)C*yL zX{g?IzucAAe2MX*zK(HDiS^MhYUXOgs2WBC8;g`R9=@qZw6pCzSc36k@b3Io&eYf- zc6vO9&k~CbQGuS5d{5^O1FfTb1rf!~y6ysFPP!zWgnbOyit+#KZhJ)=%Pl61Ckey) z)eXqB_aui)$c{g3Z!Fx0{LRV7f3(YwN)%JO%Ss@R*))bSL0cEDQjZtf5{VCoJ=xx= z!i1D)sns=Pr7A7PUJLJO1-0LCG^LaD&^)D>gT>XcJ<7FlEQFvD9%`6DdQ}~!XX#M5 zL$`DaRm1CZv|E73squGfc|X*{$Q868M?BCFL9A82lUu>zzxKsI3|G7>8%IkDZQbb} zG6`^iICzFHcmdi^yCD&lZYi@I$c`M$mcu=5f6*00TWoRk{&C$0rlAnu@LM${b(mJi ztZK!fJkz0kpNJ(!89X`x9;f3?`za4o8)#auKo?(U%N zhtFlBPDjl!&>+L~)2h!URQVnfwkyAJDauDN9TC(-!jSmS4gsPwFJlW}MiGqA*&k;a z-oh~p+1gz8zHmODn+9tC8tNVuztUdW`_RXP=5YUsTu;@*UmFct0)6%q z%>tcTHOsf6#}JzH6Dv=p$hFguzAr&H$AW}=CG*2<#k2_~JIChU5d{E2>AEs=Ve`ED zm*2`fgtH5Peo0pWJ|&jewJENx*J(a0$zsq|m@42`f&}NQoOAu&RfVvx$uqGVPp(uY zT?aSfSYiD0D&9@gqz;m+Vd3+7R63wUF&9ty$U}lUz6-&_W`CY!O{Q^5XAH%-xF8QaI`7Ja_xOK~C zy>EenrT5Fy{4#eujGB8%hQH)XyOswMJAvdkgeBPLk6q>rhSX+)4MSz{s?W-dsX`?B zc`QX@hut`%8XPid!>!*^33Ly`)Z8`gFz+rK#7USprPHdEGHrkR;oo|q2Bj=EJ?l23 zf`M#(Gk?6(HOs?Cngd9yy0`tZpkD_$dt00>#mzU@U>6JvrLes(t`n^yH5HtNz5FY{ zR1KOFr8%by7MVepDa?b+AoHGrl~EUzjci-eWlZqI+5z5Hx7Qn7YhBIyS%KMhtYgyI zJ@53k&OBsuqJX6!rwzc8Wi6{Bd%pX9$ww`qc!qQoj zW596xB6SrG>8&ms8{J{gy^E2OvVB7;|P7U+(cvF*eX2mH4yV z&Y)EBV>WRZaM^s+V7ocm7F_DQECO>j-Pv~T>0yXHdFCb}CeLvs)Sj+*9aOZ!2bMA3o!#(G?P_UZe5*E8%p^M)At!I@ zv*GdXw79Ww0?a9~f^HB6Ux2|q&y{1on==*qZ2?xrpx$7J2x(V<@;$#jUL3qX1dog> zh^McKLCB2)w;zOxOVLd(kXN<`vn6>=(b==KaXH#|51d8Zb*QK}hPt5C-Js`B@IW^{ zI*h>1NR+kvT$inTM)Ng)bIc^1GB(n(uIQXeC2;K(<*J3neUK;vVmJKwT1z=@`W9*D*GLCZfAN9b{&P=8xH@B)!knK%ZJIq23t zBYXU}>t5g#C5!vvo9jY7K_3qyU!T&wIvk%P531XnVH*=PETq6SVfLTL(r=;y8BPF2 z|ID}G&`m@TnCPK26EyIVz9%u^{S6d4$uVuea0RZRNL*O~Nx;n8_7Av!o0IWr0WrW# znR~r(q#BmMYC&>*6`F3qzQ5Bz|1Vd~W`lp0C>-PoWXQxGGMfEMV8=o@Q4t{&x|Q~h z@-(DJ!ssvJ;gC;FCQKJ#We2zd?F9Soh^d+xK{Gl`apJrD`J(Rm@sFlGBf061dC_8>H@Z5EY+O0Z0B5rN8J!~t%jn${#5q?3eb z&{c1h7?M`60^+ocD|ycHB2qtoQ;G~pBHDQQ_4&l8{(g1sMw8HbRiW|g6@C#z5}bIU zh>&lJxJ#)%D$ZLQEXdkUhMIW$a(N;1cVoQnus8oqV6jVo#wv3O=;Z%DZV$j(G*Q3j z`{KEz`zA_Ctz>P~palg>1VA4ioo@_vol3oo-zo|)9! zuYkXB7=Wjn95)D$*;vPVBb6tM$fyepJ+_BdB#abh%^dsf&c%E+71BQ^smXPc1M#GP1 z8!yibz0P*q)pjFz8?p^5o~;(Nc!Ez61DP>s6~;SV$%rPc@edxL5Rt5O z8;(D(O*b}{_UstdtQXWKdrB1hp1SW9yB}^%R&?xDdhRV*orhC!dGRR0<@ZzWdgmkx zT6+xza7<^ZGtE~o>NjV_1Xd9zU`Oyjob6Ya*3M9jbTL2;N7%0qv&cJB57m-H_6w+8I8&_E z-U~S!oX1^<=l5DVNFrjQ>ZtEY9u? zI*|m|D~PIiAX*YLO4{H)c*S^kEEhj(<8zXO#?kesX#BP`_#`gO?DDI(sQxaR$b^!0=m59v zyBYn{yl=0jB|Bv<22VkOhXWu9}`QTeVp=KX2`mYl&wEM z81Jt8fLuun8%W@{_|A+v8fo)XzT329b{yQAWoz0h?uH zV>=dza_udTbixCXJM+o%CoXz1AGT z;F%sojk61Tn?4)>Bf1!V?D3&yqohk~wk2dRT_IxNovyL14&fZ!0Whcj`-8fx#SmnVv*^ZQx5rXFRWCXZ=N*8uD#{Nux2yF5k4i z7*&_#=oP0|^VAQ?js{%A8vv0d`70DH;j#5>DOc-Dx|4}J-LD7pV?^d7JrrCz*^6EA zTpLP>0+!?_Ac@@T8LUTq9`{X>@F<`W3XxT>Qio|ME7Faa`|};)_8{orTwfcd&YWewBuRn5VYoc0{@{3(TbsK)- z1=v<^M)irF$xv6E&E~W2s~cRn=;oig$-KsFry&+EAp(5Kf>l|Ck85=nzr9g<$EEwg z3^wK5&agcAic`)oyAhK-$mvC;os420ux8JC$&u63v+SUmD(=Zja>x$-sj>vwOOz7- z37sr`N;#BzcbAT-JC;`*upR6n6rcDb>1V8yopISB_qV4_>W`O_tZ1j6Mc+Lb>1BDt4%p4Xx15^E0kRye z)i0ZAFE0)o`PZp66k!x0La5SI|BGtcyIz3(Dk0i(uENdHE#!&#@f-b;Z1C>k#GB8O z2F=IIsf8(?ONlnx-!t(^D64u}}iy#YWAp#Dl-Y_Lb z&zr3-Ced_vy5--!uvxRDmVXf-t9*m`c6~dZ{p?hzH~q$J7?a3cg|Eo_mW)d%>-@#( z_MO8g`ccZa@(r35P1yc53!wb90)N&yuHfv&)99~`jps|F-9OXh2KRcT9pm5xs#y;{ zNUneL)6RYLdwu_&0bX)nXF&;%s)FQ}Cs;)-K z@Ak1z0$jf-LSws9d=K@cMai=_|EBPS**|Oug7m6Jbv;IG8wg0%;*a6SrD1UH= zm##^^(7*a9JbHB(8sEY>cDa^YIPj7^1$EDYw{9npMN3Y!dVk1pGaWUJbDc8b;bg_n zZI=4S4*r}dL(!hR>k9nwc^aYeDMf+hx#b`4?UQmaUX_*|HM<4o~hT~ zZwsVVx}Ke6F;`k*&h^NoY#325ZA;jB(R7}^;Qp9hp#r^P@S5-8q=(ulNIP4>>e1Pm z)}PgqDB*FJ3!MsE1&+)ASXrx37*UUE(y(#3#_8d+^ za1BeK<)sB}S`G<ShKmiXEH0#Gh1IY0Wqg?vqh6}RS3#PKU~Og7PtuNE{zrS62g=bl#cn0l+`1- zgkO!97vuDWvO%~s>PXM+;{ASapPy0WX!}~~-~9!TCCCsADL;mS=(|A2+HgTd4!(9Y zbfFJ8=PSKarF>OwT&n43yGZn#?16?*%)lkdA}PLAYWj-fCWt0sv|=uqVpN}CJb24y zzLIz`p`Y}M&Drwq9$bh2G#iNrG5s@s?Nq6?I@xiXR^R20ao}dqjqY*~D@J()8fiFD z7O9&rqG69{n8iD3{+#l!l6Jtb^o^lPRfcqa^h^uz@YV&T6i{iczZZlqBtZ-#k^=*$!4KSqv-&#r#+Zh=?)=UA; zp!N+~AwG#~yE~u=6bs)KG%aq=w`^vP_G2ViAuf6Rfa*eqWPbsBTxPm~ zFPiNGU#01F<>_P7MRB*xu9%eEU|gN7_3*&$m;m>LZQHw~vg_d9ALe6VU^C1ZOWyz* zhIe?oa>D$8hUo*7*9zSF5_DqSu^)RPxt5HJ#+KTczg87*iWO~w^wF1FF*@a+h+~jM z{`C1-Vb0Mx$y5%yIDraqC)R065WJQQF0X;z&RXuH48>s6zA{@)!4(8Slm@D7-RoQf zdYIl)@*5fhs$JuJstVQ1pP$v}-jvdg2V{q%aQPrUzZz@^EY9Q-_9eEeS_cq3wqh?j z>YsXnt+!(_5hR>ypdQfrD0B4?AUYLbq->!Mo)eM0?sd3jAAY%C=r7iD3s|AMEli5k ziv)WlH9Z$MA8d;h`Q^>eQ=(_hOfr>YQEE(5J|ptai+fshO?1zuQfS=&Yh=c&$!*s1m*)bJ#8jb)G}(QI^-=5K+DHJZ5+QgMlKP-W5x<4ZZ+oiV z>SIg1iQg*Wua+5V$>F*BxM!)y{~FKoKf<_gH)AY8-^3>cQ5|Ho?10QjHz?}F^MLv9 zj^oq@N=$?}t3M&-1>X&ln~qa;C3>^hq$M+VWNC4U-B2u_RN_VUY_8ABTZ)=;H{rQ) z#=P%jyyQT6%iyOe6F^1%+oG9LALjOrJMPRhvn`b9%I#nUCz#zZr$O9h;pJ{wZFM4w z=hE%|jWZi;)^}}~{OBwLwskG^D?S<66vPROhk&YAeP_&tM&`jUqBw?TUy^-zky#Oh zaJ=;{C8kVN!WP0Q@OLrX^+L&UmrZR^uRNcRyi;QkeU}So7i535r+bI+r*=t6pUsAE z;%2HQo{R4Y4h5-Q9tJ)3x*a=@=^4THKVFQ#TMKWkt!@2WtE;RaYovJSbU1uB+JijF z_=@oa^~{2Z_eB>9qM7x;jhVB<^~N?SN@&jVwKfn4f!FNd>NY=W=qEsYLhwy{h6@Z~ z_oqKHR%9I|;IllG5gjGi&1mu z%3G_wWkmK4=}5-QtP%!-xz~!wewy2;jAac;r3Mp7gw9R5sue(hBr%+A)ov%(&B}h2 zBAA=~K=*7Fa+MRM5?~m|f>*{+7f?pFvk?lvDTa_%Y5m39aD;%zm#Zql*GE?MmVJQ= z<-Jwi{>|;8PlfjjOz@8D)(a6QnQCG#~r!4?c)BLFpo2$nETqHWs@S8rPG%C>S~x z1DyScg2!mYcGxixumy>~-&u#kc)l_ub3sF#8f4^Uh|Il-h#ADS?p~hlS>c_x@Yf!u z1Xd+Mmitv?2&M%VD#kkav02)eE+Z-$JB8i{m`WQN zQAe0Iuxa{IFKu_R_&$!TWQq+l$gJAR!ZE0OvJ(y0K7IgsF$WMz-XfzQHSPnXkz@(7 z>t-m)E_U@gzYH`Mn)l6bT;T7I;y>08fcyfOYAaO3z-!7N8&mLc=@tl;evP2=`1RI( z<)^Hy%*%FT&qazibY$x@*Ul}X?=Dq~qw#&9p;bko*q;A_*CUHmmz@z?PIjf2g_xC0 zrYsppjz!OE=V(2W3nkpmX(_>mJOO3l&+nqVlS`ChQfE7IgMj$ayaD$hd3q=A5j0u> z)iuuw1@~A>8P@M>9d6MTcIbYLTI1m#~ccWS;?yyVi1@_jwMp zu5W=+b+Tt8KH;m^L5qAd&BhX_f`|DA!adrHVu{aWC)}?X?@*Hm1q2n@c=m0IpZ#fi z&R;y?cUa6K&Mq?T?&(G;8xvA;-4`%vYoPMx%Y~7POV-bqYv<~Sd0NdMX9LRKxUYE) z9JY&}a>R*zXC+~MdqZ*3Co36Gf3Ngf9mE+r+#`#c9(wZ+fj&$Y2K+?FF^+&7=x0UE z?sT@nSSw|}D~wp`3E=Ero-IqSf$b9+_nZx(O6J@C44aYWl(PC9Ci+XAC9Jf3yYX`B zP5$GpeY&CD*g#}i%&GvEVwu;9T{^I)$DY?M%}xT!kcsXlbVb5#?aAlK%O|&9AX6r{ zVpglNQk`1xx0WorS$fXF>o}|_bdmUjw4ckV`8mOhh81OD0X^A-HUE>SNRrxN`g7E~ zf}cqmz|Dywrsk7rwv!;)>pG;(zm42!IQ!N0xzjf5!{?Lzb*lWD<&rzoKK;S&?JYLO zOIz=Nx8P;4U@8sBZyI%=YUw6|)m*K+*jxBE|5jFB_JIYRfq1s5lI(Zy+t^C3*neFs!1Wa)in?-Q@5U5`C{CD<+F zYV$6-FNdN?tLq!eiT*jI&MZ z%^Oyf^!e}pr)U(3)i^k=4PHx$*32g)PZWvtZ2B@^dVy2bpNFexYIz$hn`KvAq8-)v zXP86u75~4f7BwQ9_(A`(x+{jvY4M@FrN!~1xVhasxD^A+K3J;X-G7S^)v?`K3yCL} zr}r@45w;tmmYrM@JUsn)d;Cp5u)sv_d=`|0Ds6vy*bi!nH(c~$7G|J(@6lw9o2E)U zkMQ0H2@jpaY5&H=sC`Twk1%574JZQT--^^u(>1HTtQ4;tFMz$@-Ccf!l2zi66Sc7e zoYz3qP*evXTq9wBrSt$D5<2 zSto#URP!vWTiBvl^rE)u%}|O)-4dN%aJ>uKlf0n=D!lbim|w_0Ut0MNY6P{TT{3ma zUYd;n1<^~`XG6J0I^m~JtSNBAU^kjF@4ZPDAebW}_*=I71>8yX`kcq4Tl@(~J2xPx zIY3rlYgS8qTIH#@^s=cMWnrfIX2XVaxSjC+-_LhEcDS(iKR+y#~E{F<#?_Wpw}LB z>l=DbR5`o%E&RHzSM*UZT4XYaJ@Y6ye8LrMbWp21S!@u9NrS=oWCMWqHXRGGt}W9dMfdVb>h4(IIHU;vS)ldh z^~vdW;}00!gbCDuVO6nPY?V zpH{E=KZn6N~}X`J>%?1zL`W7(>BmwX#t z>jW^913C?_vC7 z_r%fXG3!GIv5o&D7Wn56V`72m$V7p*kPW*-hloe;c_dMwCl_59r@|of#*Kcy`t+{v z1Cgro0k+%?*ET9hp-<$ZEC%%~~%tzwf0KE83{S*$&oq5J2*5Ld= zNf0SAZZt0&EKK-xw=?TmB?*_j@D^SbFIoVy`Gp51r>Ah_%$1`!&JK`j4FIg1sCZrz zW3z{esj@Ljoe&9Rb0K5h7>RJ}lCsBetE)EA^O7$9rfg7|lUy4E{mpZpQ|SuVL-;m| zo`BwyS?6b&AMHif_IiK^RRR}x=h#_B6X+nFZ|UbG+&4hZFBkA8b3DOf!sh3q(YNJ^oR(Z4k?Jz*zbOwTM^2c#Ke^QnCkpIwFdd&~7g_Fv-J8^>!UHVtA~D<@nc#5|Z)qQAon zxe@Y?BSmm?e&(wafbGh0o^K;rEVkl6wKJm^cLD2m1VF;t0>@N^eG($UIf4FnK+L5G z({rE}vPeFMKWyPT1boy3*TS#9B<7-slyMY+tSgBeM{t6KMH?YYlljybU?iU*(#Aat zO_0kir|z9^IgKMCXNY>7jpF;BIM_U6nyPV-3y#^EtW7fCX>osT4^~%rJT_KsLu8k` z=2s`z50l<>1^eRT8}lG*o&f??2akxJ@3_D+nEV-G&-}P!<6Y)we)85vg3zz*50bNS zZ_s8!Kgm^4sl8Chc9!(8Cvq9*jv54^D2+`$CC}LZ+)a~S3kvGV1^{%ac-NINP5k&+`Y+@>UqvPcj}fLLPwEnL^UYi6)i8#%-y`3d@zifJyEii)Wx zmY95#6-aGltntD_<5kWX@9#LKe9JHd!mDLfsOR9%j5vevo8HjC?y z<8JBX>ERwSZ!W>6n5P9>!ZM<(wplXW(hwniI^9^T&`5aryngU9T^|z0?E^wu#(~t` z_I8lVw#CsKtSWH{%gjiiD+yaMrMvTWhm0J8#FbzXp-tim>-Bz?oOF=y5Pf4xIOdXW z*#IQJSHm^i_sy>c?`cd=^kVgZAJY{sxMvBtJmSIB{Mc4m4 zp%gGM0!hFM^IZyyzd~JB5*NlJ0s_IFJXpC7RV?E`q}4&#c(*8)vdN2|2Lgy|6;ZOh z#_&zS0_zFVzbpOd;b0u)*B)$wIZnS98kyd}IItj7M0eBa73oKq-z&zWjM_+!>&kLL z5GcwgP+I=x%4F?f@r_V#^}lfokb<|Cg*MyS#>R2>7cu%p4Aim9q8V~vm1!gU2us=h zUajzVbRaCi6ubi7{9D^{4wN35eIA>QrDIbFO(-B~LM|p;tmCxtMX@8@%=Y75Z(QKGDPz<9VkxtnE{rmZAYUf}S zDpwj)ag3E%M&vxo2wm&V2(#m~zBdC2F!4Xv_T6d5vs!96-O>a(iJA6qU-4fTL39b^ zLFpy+t5}#j@c;5BVB;Q`ZF(SCFv0cz_78yK^#9=@%J^9G?a{i8=LbovU21nGGYKfU z6G+d^*-NAXXaudYK`2aQSRE_Ry`}kCb!hqv`D75#e{xA!6th9G{Z~PC+pr@0?07F1 z!yDT~kKX>{+dm2eyXUW$xiGNs?ag3=@2OUU&#~5gTcl=5^oG_FnO?1XzCo2!+Nv@r zd9}a2W)*DI+_;J#)5NcC`cDN|qt;_v2U7w9_!b@I$%YM0y3$Q2Icy5Vi$ezaVz2$D zZr@nr6TJRa^L`h)3{f$is`Fd}`hi+M2evaIGVPCAyi5*RM_k|$5P=8FZ2RdCjuH$$ z-KVgYT0sM@HIh2=1c!k9A)ua7)oU2#6QjifFfa&A7Fs{v3u}K6chg$ze5VcS7K?)I z0w*BT)9}*&_V0*+Z+%Txk7)vkYYq4@ zl`bIWD1=R$uJnft8+)sPi1)ox0(ft90E!dr;-6uTU9NVVH!_7x`0V{y0~h2@KeSom z`O3%p@jUiZx?`1&>i7Rx)5QG3F8Ktz0QyzV#rdhk&g`HIAa2C=WZBq2a@wk1X3WC) zB`iWig7JP}xM#`PWQynqGH*cvR(Skk#hB7QB@ihjzRMeg+z0v;xR;7zT#sva1+Ns@c$PFcCVgxS2W!M(b zr@5cjZ&W?>+D`eWus`a2r*uNf?B^6PRH!y43E8I8iabkjIRyiX33F`5%Dy-<&E9iR z&{u@-e0{rvRaZJAS$qJ}dp214QT;!&KQeK!m`&_mAOvP(pdpqYkaQ8X?rQ`0>_>{4 zZQ0{sQg%b!Zs+^M68rURGr|zrD|5()88F7TTED%h^LGAaR#E%<5%jv^A@gJ*hb6GU zBd`M6Jt=nwS9&w*-#c~2SX24SMg}4uYUC+lt+Kyx>IUl9OQfQ_9fhaIeD$`H9T(T_ zH&e41f%55Kj<(L4U&ZD+##F-Svm;yTe`mres0N6ZnhqxOB%|)nXAfvyY;{G|UmCyz}17_g}oRo6^i(_lFGfEd4&tz^d2TTy>r-!+~btN&? z(lJZ8?UEPta}_Exs|INmppzP^VAzbu?0R#YFW`sUSjG$8p|U=^b6*v&?Acvg1a=k3 znrLI*B!HVa0C}(pT>_7aDxJGNccG{u@jp8(WL)rNRD-i2t>@Q*be$ODIUXV4?^?hi zQAN&zQ#>t66{R3c|3ziztmTRzU!ampilpajZ_^Pk7}n?`XeyssV9nu__m2y?x^hl= ztgB|9vavB2j;Ha=MKg@?=+Pr*_#aZQ3<1W+Q$6F#LWoY0O)LDAR(o^7jylb z7{!K)W{}X?U+HZfXbtlZeiKX;DLl&783@U8e@rkJCqLH+iM;^eG6~no2P%7|{UAzW z%c&C(`b=)uI`${)y*;wJaj1+;mkO)q2(q|4oHs{`GY|!4)XW4E?&J2|Czq$wm#Y7E zvv4dZ-Y^HYrHAGWq{`9(z+0B<+H-f<7Lx9Pai4gKU42B|3xmZicg3sobRP8oN_jqN z8Baqz^{la9{|R1c2F!1!>8k5v^DDT7y`}_IJjn`C%1=Es3FcINW5(LU>;Ghj*kO;c z$9AUaBVo1#p_f5@102~FeG}Io!UV^{z$0S*D?l2c`A}maK(&4IKi}8Y?BTlH3uE%j zKKZ>mPmhBv&M=08vmdPSTO61-b1s0xO%rOh6HDKI)X7yS#D%y?d<$i9o?F;p@Zovi zJ*!E@NLn#E&|+Gv;Fc^1oG=puB&VOd`arski?P7BU z0NM*|auv8+OZz`(BR9*3wSbR>InMhBJ+WtxAW-VJs(s0wW+gF!esrJ7uB!dcc=W za9V8L!?;(VQSD;sI$?QNEOHP13vmproddw=XP-0Uy9#K}*uft{Rh`S47}5ST@@!I6 zJw^k&M9Mry%B=w%pA*1wIp|EC05!h_p9^5T z%s_jXE;Y7Ra6>s<^c>r{vJy5Xqxakn^1&NO_G9{c5z$|#{V#px6Q>DroTUYtyPRLa zv}PuXKx<%>(^=9T$Eck%B}3qk5lGzv%s3f|IDQWyAd4NM&Y+*1Ol4Q-`m_Z#SGixcjSv#foBrMKOw=rdV8qZ$|$J zd%wfudKe9*hj_bh zAJ#?~;q}lvl_xKju&KRIaAh5PagETRN#vP4d9@V!86iw=fJyJ6tk2QTEWvsUbZ%U6 ziyw#c#PRsoVh%u@Ry!)o-5&;l<%em-;9JLJ8Z0HYtolzCUBDBP4$44LsS4?{oz~D; z3g{x<3=D+70urLrFIg!X0_>ks|MCV6mfPu;+M{j&O7hKoekkz>q$`s6mqXCZ72-TS z0MaSb&~fcts8f4Z5HiyVB=<~rQr^xES$|JRbEw;G6H1aD{c&eH`SZkM;N4UU-oyCx zcf2ZM<%&XpD@f-Zx4uAHB(TMdmMya0>ck~^hc%Zk#EI(qrPseR5ZYcb4lTw)xaKt& z0hi`luM$(_E#_A5YH+=+$ds7^Pc@;}Z^6c|I@t)u!H9}UY*o()nFS8Mb$x#Dfi`xi zW})a~St12FC-S(v(8X<*d`d*3Hh zKxXq!^b$X*2h)>$GMANq>Wq7*`#)p#2Do2sh$rwaJ7zQhdQ;EhzpP;bjB;}HAnoD+?6VV_9%_#MHOEX)x>VHibt-HQQss8 z!jr(2|M{owRfgq~bo>ew{bd?O&EMh_Kij#eG!A5jv+S1>MMLu#pVly_Ak+3@Y0PTI zD;*uBH0Cq-T80oZMTn3MyRtW-n2PEpZx?VQGL`2a4OTju41ScoR(g%eXD5I~1U|uq z*dH${G)@}?BwI=tIl3NF{0h5;<;v{X?XeF&zrHC_2N#7IO@bH^Q6tOgf;d8OxN>^I zH$+n$Mc7LWSKbCz`LxOARWSAnJQI=(<2NP5jU^4t5>E7{VO)UVZ+A1@XeLSlJy1K) zZ)fSr9Yw!(eugf4LNTtjhIHwUG>024Tq*fOMf5$kw!c!sjkcJ4e?OAvu#ZYJ zEB7$;B0U=Ag(WxQk{mWPl&4P?i;KPd1c0;+^N`;+QBAPI!jEDry{K1Xffgt`F8zZ+ zT@zMrqS`|1Iy&I}Hb_&G(33l$gYWXo5Fu*3Uj*b)9SC)A1CCB27Rp!D<~18uf4f5I zkAwyAd3*x14}3z~DG3=LKscY?&W1Gr_(H}520YDN4JDojj(C9|*d%D6oxAP>^WgiF zBU5~SQnnB;ALTIRz@ogJfk2#nWID{jDda+(0J0NEC++8h7>{9^#v^8YCV8u#7D0~X zbEOiOw+aA0>S*!x55vH5<7%wDeINBq0I%rr^f}j8I)XU|@nrS@C;X-i+Bv>07C+ow z0tBqUl~<1X`TD)<+m_#JZ}eQJ>84{Amwaoc0S)_T@9M3>Py0n)+lSUV z_)B-5f)Z&1Xv{jL_J$Llza2>OE;EVVGhz0;c_xIUvNyxz z35QcBl*VzVC}O0~lN=kIaVthFkG___giwgKS$4jSjX)%}nZ`nHk=GI11W5?V4Q960q13%?Y$3Nhbtnt@kOHE|5#FOQ%R(S7|{>biF(pT8L;N0?!ZlU667T78a9j=Z8mEbP&^AqkxH%o8TZ%~CAj z)Bl*AZxr^CZ@)qq%$g!%|DLl=%&5Rf3^-CXt`ahRw8zHQoY{*GtRkkSd?WK3GV?xk zCNzLghwsxP?6grQSjwfTkZ2Kg z1hVr;PMK9rn=j!7X!g*9*z&Z zz6VjIO!o!SGbNVNuCsx`L)Yjhu3bLy-=!~3nWBCX7J&3)>j^>Pa?gC|T2gJ7xkfnR zLf1`3JysqH-4wZbw#CiXePg-G*DC**b8)>Bi^=|-X*k36tdNL zf5GzpTFa$jh3&1I4_|n^0nCe1-pgj6s^~KNaS`T0ggk5apM5>yfBAaQcELCy_jpCS zFrjeIUk+JemSax`u;Ov?Sm^umveH&y{W{KMQcH3qAaJHD40mNyz8B7i5_=V5w|yb-wgmvQ60>b2f{!#i%v zA3VHp}7snm?Z@Y`hQ z++BwNc1b3z0rZsM^wQuGv!WullEZ(ol*EULN;*QZ21EG{fBn3Uxd>fH50L;FNX*Ji zGC5mP>(U8G3?-UNZ_Q=!NNx4Cz+-3vt9~Pctm)-BgV)+UuQ^J26SZdSf|~P=#I4pH zrEyn+x!x5g8vG~pSB?6SJaxbOR37-*F7SuOXVteYp0mdxj}OKjC8ioslI9uF%Cm+< zMX!5qBA?DDV!sh^!(CE@@)5?4<|@pYqd?X@$;B=Q^@td7Ptt%YMY%4B zS5|;-F?M;cGGGmSIXO-MzER{3y{4W}^wVSyFc{?klqg4Dd!4Q~v%`*nGg%w-quB2` zpWg>=p#F~mHt-*ozZnl}waOy90<5bP@4w|B$@hxWtMEJbdSgOA{La_9oPpR7n0=YC z+JJ~j!OS@`Wv0fcV)(}yx`6X1z^pRQo;wRV_w35kv{p?=z$aQ!GL_|X0Ovd2o1XCx z85&+;qaq-k%?Fn%Cg%5pRL*X)4(uWY4h_dvwc&f?034!<-hhrW4NOZ_Tx);UlW(uP z>!yRxk*c8oTh-6@2q(E-l`M)!6x+`~p4w(1W&8+(QyQJ%H$0#w9y;mJT{C9Yj`6@Cw%_s$FaEM}LpP zSpVyr=$W%*eiE9SK{`gF=zW$bzt~Hsw=y^N^U*q_S4UP#pYkN0JZ5mJXvZT-SSa2 zQ#D{^QzX-L6_6+=(%#lsh3(HTc3DVc@8`jX6a&$W8VZ|2;py&aHjiq@LJSPXG>SC` zbkGfsUsDZo240Vt-$RYOiILwZzFBday8Tix#bfJxo#6KA)Wp~AW1lTw>uwQiKS9?e z@QsCCUhDbs-=D5X-Dl!>7eyo3R+&U4(U69xV}X!?K(4}J*ugKLP^|y+KRz}?%DfSE z+>FfvJoixXw(V`ZH&fU$KT$w*j6NB5-Q>2XsMG9 zK!$T{8OL?~UT{+-or@G@THj>ru@qn6);U#Xe5u}0uM}>8V$Yx528{18@XfvFV&!oA zsEop(<-|G@ZJ zPXhzLT5{X1!O`}rT6xI8eb1Gjpa*F9dwI57(D^*m<;bVo?x80Ky1`Wn8P4PRvZ(Q@ znq>T`8%{yfz$0;l)`PasT|cZ;7C3M+;wy$DB(I{}LuBY=n!G|F+bKV9tBe_}@5V6s z6?gamm)KbWYXhAn+`%FuzIch~yz8Vqt_d0jxG5W*UeR;VZs#^27iaL4b6Z2ATZoRb zHV%e<6F042P+3eg1$nWx;*alFGz?@tv+am5Gn@5Bo3a|8X+^y{Xhje%u)SB&UfKL&<=-*9=7~hBGH*EVcMcDKt!W*SK&fT$PMlIgB4Xz z;A@^OkyhT(fgT)(90gvHE6PKsPmnH2u`H%ScF7;Uy@_pbC1ABbOX4DrZl$bMHA&_(0qB^TE zKOk(-$F0kTlg@=PxF;Mc%G9U3weUYZUL3_|gmn&?fK>(eK>HhRG_hz~7#Ov}omfqLz zHmD+*9_W+Ief){Ey@5zBE!r}F$<$d-3Sp|dVLBK}=l29S!ky`jQ)BjerYwMn_Edp> zF!^aGDHh`6O)TK8eeW+)e6d7>aSbJv?*PUHS;D8+q5)fVKP{-;3csgf1SbaYUiLLk zfGVpG)=(WJMJ;fj>l7@!ZC4vf`@22B4JO|^$|ws;?@kM2yg#T~OxcBYvogBHJo`au zG)*o{r;6tiEZZdTFKo?QgjE=XLzRke7(vM=tE6=B0~5xo3W*4a->Q(#We$2vP2dIF z;>Wex@+aprQ?%EC7RU(#uDm9z9KFM}nDsj88jtN1gCRDycQp?rHp{+K525$03WBV! zY)!%d@sh&c-+BS)@);d{%XdZVRc+95*?^c=%nKE6CMJrB+)_?l_BUHsXI|6WIq|Im zfsboH=T{LknrruG${&xs%&ELgFtXc?>pp6J$qQ^U>ZK~Bg~ybqwd1*<*KeCfQ3fJS zkqdJ@)pm2@uDkc_Au_6F`czNm&@UZ;+uW>@CO~y!3rJ$^$IqN@!xi#Oo2jvxzr7}i zk!e16S-9^vK`bMxD%GUBY2 zSo*ilT)@O9-d6!C+{MA{XEeO`##0%#cgqUf%>2A5-Osd4$;3)sC5&K8fcdk(e8` zbI~%0gwB-;-bt{p7(Mg;9vXA+)`MX2gLv;~5yWM&%#r~hXuI6DCPt}nT(`bv8a?k- zh-!rCh3^$yqvD&tU?&ne`^sC>B zWaO>OU*eIjhXlJs-bC9HtF!B6;=O)b#?6U9X;PUd6%&d9o%`{7JDXJ73lepj5)qZ1 zysM)`?#e18b7l7PxuvP(-0hnZ(toYBjH%p#K=<-D<_PY&dPpY8=r=D8*BdkfHxuc% znOwi~r`(JtYZ!+aHG#mPFKffzHF7S5I0FrCPN4D7G(_Wleyhk$-zutzI^x|C=+;X^ z$NE9C-`_;aP3W+OP8eG*ro6ZF^WlRaUi>=&{I{YdA0-pUitdrV^zi^PJkrK467KN0 zfv0>xgNRvBU2nm%_as({@e2p8C!ftvm=e7PcTFb>vMXR?8LvQcwW~Be5NDz(;2Kvr zdwwmKfTnv98@f|K4MY5RfJEAM{UVJp<%$zN=0JvKA{v>|*PAmDh>s4~POGm<$b;uF zO{=4fPdF*3LBqds!MerUFHr#TTj>-F5gwx@SkZ$Oc%}2P429e;?Z8)LA?NUw@?36m z<+WI+`YvU^`6P+1eHL^>WXFF!uQY1&!J3Htm{pSf(qy>Y(3DHpZD$l}fMA+63Yd=# zZ|prNZ{aU~8=7}xXwNoSG_E2*RgL9~?H&g4gO{stl;TnpP1N@_%frnDWsQh?Qi@w% zo=A8~^!AhA(TBL5TDAn_Gq2dO3LZUb9%G_E`ucjhqRTh_x0Ct!qF+nj_$}-aAMS=- zROvUiq|CM^HhD;U(|H5MmS+mylF6`Y}meVr=7S!_H@J=F+tv#^jEz4z1h(lf>kcpKB# z`#wb&`W-KFnGeK?Ns!E0{?yQi|D?u-wX>_eUqD3=CU%TOkK10r4*K$1N~2!Y+Jdi% zbnyZ$!@FCZwi&|M*PlTwC&XN%00iC3WaICq$?b%sNj(r-Bscj)`|asCj!IMy^|xK; z*~dC*-z#)`M37F85ebpNzuSAe>?fk(p7N&5O>2@l@@E6bLc+pgbMYXhuU}Ms=Y80~ z;r)26xpio90{-=p@r-eEiFY#&75ByoojE-sWf{fCnyiwz9NJ)N&q#jrA+5|YqE8Qd zhtZ7U#m+zzvWeQQ=_;Pkf$3AVKNjIKkg_XS%xJ?a1BxP?h`LxC_lXL5l*fc!t{@rK zCe76eUovTiKJxU}BYp4(Zr)ObKM&J`ksO87ZOl8M^Py_eef-BA%ytU4g#n4q5>nZBCzVcw_Il>;T=Ox^l{^%iE#J z8%$$*AikQpece{&?>_n?%sc44PFBN;kc6d8OJaf~CiwuoBGUzfA?hrhv~&L)4KTk6 zP-F)GU#v}qjNxC)NHmfO*(E|ga=QBtv#Z{K!yH$9byk z$mi<8NV;n1S|~W-(j3?=67S#mfktS*hsyv z@?)@9fB)VJ8b{iC#GIT2}hbD+Rr_)Ke z=SiQHbn&b&0lYV~79Pcg&6OZF@vm6`;6tED62#qd=80E<0FwmDiMhHGI$+Q%2Ogc* zAV>GiOLvGlEI>bk2aDpX9cv%(x7zCEl-jjXfEy;aqW#Y@cs(|X+iO7ORPvO8 z;=kp~|GnZe-U=V(Nay-LtGTL69Y66=qtt&wGF<66jcis zx#E-?dR0o|ZfgrVdS)RlZuZS4XLD3rAeZl)Hv%=}SzN`s%tw;pu&+~~aJ;>RGbCzB z=?i$jIbf4mG)B(im^gy9@i_YdWOC;ug*zA9mlr+ftLpy0zJewWtx6DJsq%AN{yO)R zax=he=MFqEg^rlw-J|PvrO~PdW{$-cSRRjP=?i3O4QR?KIRz@<6n8xfD<9P;SUnAO z+ke5xr^e-I(DvLm36^*ZxaQq3m|nq|{DwpIVqADx+(dJY8)!*64ATQ4Z9?Dr!{F;M zyWI+jvE#Qm8^r!cK|ya73K~w<5JQ~`(avDpO%3phj8I_`!6c~)_oK3>VYd%ESfZ=I z5{#ryr+9Cz9)NNMvD`^r1VV5%urZ3gHBC@Sf5JlYAIJP3S4>7p9g~md@e##u~SZfD+J9B{7UQW zi)pm;z%;}Hmsd`pJVy;*7uEu3OFA#n_b!nQAxTDS2_F749HNIf z12bbA(kOGzq19r1g?%xd-l|L#nYtcpI@@>$;r4jy)gPZ>Wi}yxxn8$|{ZyC!! z1+9-Cn19YfoF~G!%K9Hr#Ak5BqdpB(j61APhJ}Xakj!DK0TaE89{&rn95krCEI178 zGf0NlKs%v^aT6$^{7>#Vz(6#`e#?KdKqoBOuZ#(g?!ubSAvg4r` z66UN*CDoI78{GH;-9lrBIDM<#tbncsV8HRPO3}!r?=oe#@9UL)^}%T#zsF)!+>V!B(%TDJh;o|~3tQeQp@8t8KQ(vfts3~c26biu*F!pIUt`~W?RJDk3IHVVf$GLU`sY7o zr%qx;cQF%uG9qCZ-e!{4E|0|B)gQpPmJC&p+6?dm+8MpS%g!K7FMq{1zQP|)pFE!2 z_5%oGOU#76hu-((H>W{)Yn(S&8S{uf1AOQ8PzLj}V6q1`+I3RL3uK4D9Xft^m1@Ki zF;MojU65$1x0`)lNbrr}YpAuPsj93~p@~XD;`gYY%vXwl1G^tauC#L`v+|*&#Ya#t z?{bmXf7iloR7A`8Pua$vA%I8$WmrNIaot>y#S-Go{gN{pbOgYRQ9UeZ=U7Z%+NpTV zv|hI6;bG&YZ!%l_Dr30L@i1y#E^qs>$E5I4Ul>vpENUkph%;~~ zBknmNI)gpcExdDv{IVfsH^J9~^4XKa9ohpGDD~01MtIvamQILRBv`cr?Hxjrj$Hx! z?7Tk}#be@F4584<2t>@=s?+P&#TD?KC-mo|_Q9wnXV5XV@BBMTbPnQwBbQ_j&|<|P zBTi0;j6a*t*S2A)5_%VcT$jRy&g~ng%Aj0*^@WU{6@NXumtWF(YxkQr3tEmY4J+2oV ztw9f!mo($jp=)j7_rS2I*l{bP>h4HPDW{e!+6y@TZyV_E7m&C8}JlfWU>XXru&9~gk$qh`ZKUE zb?r+=If2y|Ht_q%(blH%%P(~0dGHtz*!D(Wx&%&@O<9~(LcStmh{le!DOG| zUZZ@$jf}4RCnH^?POZzb2^70PgxTBY-OJR&7}4W=WBe=FH_bPs$pr)>uxzl~IF#V6 z0I=vJ`lA8E#@My{?hJ3aPfkz$4RXJ}S(DY>K9Cg+{S{gr?XnCMr(b7FAz17`M0Ey% zCH}>+897(xf7ngrB6Ri>j8@%6~O-6xQDg5d&v345d~(hO!@Kh1uw2@_a%A&nA$Q#0k> z2a7zv5s|zG>zN0DXg}z{@nL%=b`O7pRbD66A8hs6Y>+eqTVAjl~W;l7IfCKZWOuI6>$yR^I^>k54O9iP)3;$+uAI~c+{ z{cGggWd2R28CfGiVL8RLF6>jVdA?SDI^Pa*|sOzu16A&_=Zear)L zYqwI03c_}wgOK#QK0kB>m*mJ{2`BrJ50ZSnkGEpOA7n@d-bND1a_|dnYeqmQxy++{ zf%ts$N{U3+bDKsk{w4SjR@`dxvmhubyNKbTbQA;Lw>I$e%Y#1y)pDywGVIOE2;l|R z58)6eg_WKNwJ%%TKXtrJKV;HFVi22_dC3fe57}D}BpV002G$6Vy}3gny)~DBsQfUK zu7`y*EEi~0^={sV!RzBy>=+7fKnxM?1(0d<@rRxBU4kGU~)* z$^^ar`~g$QwjPuoFO{e2UMW2_q7+u>2lg||dv{{X;dgODiZ}|P8gY<(05%{CajECO zV~Q*imDrnT?R(lGjqqMa%xRFKwd&mwgmSml6@QK2?Vdr2R0g-!>ZxE1q|puUvd{O$ zy!+&dzbwjMjq8Yg8S5)B#W7UZd=maPupazQ?mha75DcF_Y4aGi2J4MisAp3$eHUMi zrj093K>Eu=ZBTwpw#x8e%3!!`X|nf$=56owptF9Qo$X^1F+X@ad#k2?7Nqjbj}=BS z{7S5{?z^HRAdqjxuPzK!|3?rWk1@V!?`m_Wyc6L5pOafb8p9hG16q0)*c)cis%*h%ud;aujvcjh7(B8- z>eddp1K~>0$9T|GfRg@b)P0GZDZM#eyglXL|Cnz~J5=91B7a?b_So^M{*0*o%E8Q^ zwz`ly=q&98xx?bO58;~lp+xbr5HY49D|$N2No1^?SiD=!9jz>QW5ZsORAynfaK)#t zi!d%mX^GZVI#fYG(}GIefv83kxpJjoOSA&~;ip(rA7{!5=_e<);26k?!cqLAL7VD& zSg*R#55UsAYsr~4nm$$lMGLX9NjTw(*_$wl*dI&9*_*aN;EO*dtv9(+$zHn8PM939=BYP2x>&!Do@{w6ztbNp*5{4EJ=0jyV>shdZD z&pVyJ9Ip&mAHnNRDiqH-js?Mx4PVNUnAniE@cxE}{oL{4 z`}wkUL^I=+|N3s-zq6YK2?Pu29MB3@tCgD#SQVp?qiG95_tT?wY^nq%o7}7xi!lxx zT(kMwC_P}+6mPqeNxiXZSuM?o2~kTsfi@x7qSMktV&^q-j}P@P+5u$N=|>AtagKz^ z5`$-;j{45-Ye;X%G1&8DV#y|&6uxr|4^C0Bdqs7`S_mLKv!>3zfo5fgz3qIZ&eSCf z!)3E80TpXj53~ExSLjp~!WA!M5r2iTPJ)U7jeiR{=d8K_pp}&iry2v%E04XLai>&q zQ0Ua^bl`4Vvi>U9krZJm{0s)T=0PkfiFWAM@ThWn3yedsi;MKug+I1Jq&&+iJ-7A8 zy@;bilxxV-YTAE$Y=6jO)agr-5hWwwU3#J2OsrbSy6AjnO6HRY*5RLi z0^GeeqwhXI<$7QhIa`H_7^Ff}vxgkubawLHe*`Z9oFaoi*BMfD+hNPsIgp9g`xyl} zbN-nRZjr--;8VpYsY_j=VV%vrPiG74L)1K2t{aSycNmT(qh)>SX_94jUQz4@kHOK& zE}Qd%$j*sV8q&8dbC^0>hFF#4c6mo3ne&(_ObNJy({bTkv_9|9=t7sW$W?i@m=F|L z9Q+;bJ|u!ppm2=k##K!LQZ)Bzd{7BlsX&HSUL9AM*SkE4xjOW9=^m6z!vvlXNUx&U zAmM<{l+_6-+A=o(+~eU2KAdi}df2~pBOW2*Ep!N2rOSF$VN*P-WR(8)edtX{_LlRm zbQC(R(8B&8JwoEEUJ9Vb*B69DSgmU@M7<7P;Qj&=4*LR*Uh1Wkcq`=l6ywC0!SO-j zzI2F=1-3;?BWdGSoQl>_w57K@7 zugy|%tCSttK14#SZfyyFbPC1-HGCIHoB`<&*1(GaV@a*90AzFAdyS#c?9hnbq2d$e zn>#_I^oK74z(Ai?LgOxXPec8q1S~o};FZSt-2*$_3uFU-o|gmWu#7IKzm;pWfCnhw zdxN+UXc!l(&=dO9$uF1>>ES?1`A+mfPMv4}QUAmLzO{vk+fjdI$2~mqxqzxv_F3<@X!l|ECNkv8Xm*1H2Ul={gS3pXiIf5q-F#qf7zBLSX&oDTU*IkAipF zq^&BPb$!4#r;Uaf511tBt3;JxtH1KS;t8heJ)*GN%49o%tmsPDft#6;DaE4)igxlR z90l_tL>m)&{-1+T_L7y@Km3TMLx3?Y$+MLF>q6=$J30f~KvQb$)RbgQxn@(0;y)s; zJLYHY9&Ht+y~=D{#E_g@F!O7Fj9VsW1R&?e0rr-2`hyoQfnGBL1BIWB2;$CZgNr2pR2>|Birn_C`r-sFzOO#T5s75)K9JD1lgiy=bO2vqg z+j;5pM=jPkYJ+M6t7?9hduBBwGaM1(?$>%_~Y)lD;w~GtKPnY+mn*~*SL$){?r)e#YLt*CtqjsS{vD$_d*XElwDgGVGDg$U-4J84P3&t z&6Q6}2Los@T-vb9l&*XXbIec@LNG(NeR_EQ)nO6BM;2BbzMPWE2wIp?aW3fiddS_! z)SI4@$iTts9p1DtC~KI{6((>t2yUtNx6Qh#Y@h;^wScbQuL&g5^{N+VML{Yf5|4m# zY>kaNBMfuoq**uvrrbJJp4uQ5g(aig<;kC1rL*QKD#1vv!etjphBTAcjEwUCCP#lwf>@`A31H=d ztXx@@Nf^SiEE4h?h-KS=AqkpW<&Sm-iWipKP-a}S7_wH4){7x+C9MjYMlv}fI-d=l zKAo(DU%$ly29_BHav2pTm3%{kw*u8N)sadTy**zQ^9DgRo!*h6|{*c!8BQCOyij!%iKRz7W?aXBnKCA~AMSngjCSA$w3>Nvwk3tMw^EJXdaH67>wD${IGz*4?+xNLUFqna7b9C|!RQn}s;=ca z8#T0ai?C2YY5iZW+#At9>m0SXK7TA+)~cYSj4{GX7crxH0Z1?g<%}igX-e85+pTaS zBWF<6WOGRR>9O{+nNV!e0}1M%#>W9AI9@R-bQf7Tf%`9jd#t7JupSRO{ri1vx@f`v zotO;I)+U?H*o?hZMZn-*1(=;F$|_BVwEry5&g!mmR09{(wMU;F~glAnDCSXqK(gh}Er6xfZ$+HZ5 zuNWSdsY3iQKx=J?1{Lx`O-&xw3PLPw)+Mv*{m@o{;w5BGcdtlv!q%pSBdj)+VdtO?WZo;{Q8L*s!VG^f_wCrO8;~#z z%T;8BAnBiS;t(_;r#OCzAShO_>@sCjWdYC~I|nOjyO|Ft-n@51uC>5OO&Zcb=JF%< zX6>HGF9&r+;wBgtRsz?C*LRtD+?(*X&^*32kL1-ix`DvJPXS{$wb>;~1@K$8hG>E}tu7@8C=%jvsu)GmQ!a?@Q zstdL%n@)_L1SeyRbFl%263VpMVs%4Y+7!K(05lzAVlj3I_i z_$3fdO==~b?+zJ5Si8OXSsSKI9cSun9D#DM2hhSZXk9APR@+>Ub1?Hxdn%7q4d#u@?EhV-A}rfl2Oa?@sDW5;1J-Sfpbq!JnRGEr1a zhA>bzZo#E{g|gtw6U-!~zd(+R*tGIi0I_7wJ(80LK;BIutoTkmfTZ$%&$(}neL?yz z@%s@V^JsAw==6JuQaB2`f%0{SqYCeEMs|R%wim++UkV8~=+kF82lse@{ zaTdPxH;-pe|5fEBM!{PV)Gm1d3jj~c7209W26IhxPb~q=2t|KLI1Vnx>RQvM|Ey+3 zS&y2!w7e!JiyBdz_^cVc7~EJWrhEy++{I(dNZ+EIt(LhSO;V)P2_`xuB(kQGFE)=X zE^vreWeOQ#ID(kOf*|pH%yL9v^+9BjRoc{<+BdVAhAo%Or#UM%CiYa6NNp016%0vu z=*ou_TOwCvloV)&d-0P&sFE()1?6QNeh1*vwmhrVHl}SbVYfnsZuM5g+ty($lokAWm!CQ7c%-Uu-qPAaX7qAUtry{-bpUS}N}$ zd)S*tUA#;*z}C#v2a#L;ga#Au>_;{FX)G>_YW}T(vF5o$o(2J$X8Vs6jztrM51AOXC@crfF!hFLoT-6xORfk9Yi7025KW#`E<>JI=fezL z1eJq?r9;gZ`tTLTQT99;aD{{-OOkIQA zHY36Wa;;J^`T+{rdr7)~7hc~h>XY^274Gy*rEz=RPDBy!ieK65eb9rhm#?Le=jetB z^ma!hjo0CvNeZOZ@s@bt2TwKXZ)EhE;X8)ck_VSTTs@#q%$kt4)YFv|;Td~x1*yb| z)z|H3Oq|n+=gu#s53^kINdO0mByhvng--%bN{zi6cgAO^0)c_*u2V%LlI`_|k(rE= zPPs7c081v}-5*!-zio%s4yZz`u!Wh=d|T(#2-0x#S$iuGw6q7p8D0YY_Ha)Un0v!n zLd=q_^i$6ikgtInAqqh{n3P>xy@NbRA+Kr=gz4)84b7Bj{W>PetZ<-y_S_(mzm zT1xNL%zycu|M>;HF`^(NQYF}HuOLo$i3-SHN`!d{!{xXB;dJVlk!d-e`VRHa=l!i& z!o1{!DSb_b|H0j+3cY;65+Co^q?7>r_OG&Qm^dN$RN5%->ubSfJtefJ>?MLNh*hNc zF#TP=l*fDq@ij)C=v1cQPz?i5;W+Cz?{ZZ?uOXvUkx=%OJCa{80Q>JevTyeQ4H{o) z;GBfR|K9okccH4YL0-w91FLh1Fex$@l&h2N&3KWczJCae&*j!tg+gGAd!B26byUyr zo6CQHApUcq{`39Cvn4=@kljSE74_eqp#T3D{PUpk;DgO3PFm9en8N?Hvi-l%7b>)1 zt9v-g3T*j22bos=+8Wr%FZzu82z-+#OEHz2z+(BozTm(8!4d~xHC8yoLea?Ilm|AJ<9M;wVw?JY;zK(yTZBWD|K3Ofx87extiA2r2x} zwX3Io4Cv!CK&cdIfeGiLd9c!DW@+=_Q6uFpH}IO87!+BJy>(0l6 z+^Rzk?uF6Fd_yyrhk_u)U>-oOMq9u1>>O`^;^>7R2poMEFty1tzG)i{6cp^<2z>XvQmT1@NEm& z-2A_hI>I|nK=O%veKZ%6=$QoykKYU^4|kAbCehbx@&Ef243eP=(Zb?oKBuUP5!1l? zsAI-{ajo7Z#^y8!&5-k5w-w*29~a;-D_@OdTq@|HPNM1en22fS(y|quDMps|^KK3@ z%GTCcZzd&@(9d<4qjPmGqkd+!gF-RccJ)n){MRSF#x1IHfh3dL)f%|`+XdOx zSVIA64zixe+EVHPF&6@xLIiFS*#go&=ZLLxmS=^x-oHbd>Z4T+vvyL9Z>u1$kg0=) z0B|o-Evny`Ktj33h@!5J<_|A7xtR|{qpyF+J#p1hz4_YBZeaGs9VkEzr1Ct)b-PO4 zo`Pl=cZlyY(OfLUf+W|#X*EAo$z%qQg%t#&oO7RfjFS-PG=Bvnwb4C5-yDeE^gg*& zpQ?&=zcvOCO&i5xU7co34v3f81IE$m^U}EAx?$(&>buo=fkDh{fn^X5$PF9C4I86`rF?-ZvHEN6UJR$7IR`-Ozm(1S&2~04=CtBd8fP%%Zd}pKl2=@rJ(qFQ1NV&h^l-ACR4ET$ zxGh@PsPeISUN6Suxp48HuI@nPW0t9R1Up zc(YMCz>Im!yKCoYg*0051BogCSmy9tkC`ud z8hd;b72s3lbJWh*mJ(`lfvFWNI~hwk7y@|uwr3!(#y7kG9D&rO eb{ffNh(JNO) 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�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ℑ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%0Arl<=>f7dzSI3d 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 A5C8xG literal 0 HcmV?d00001 diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md new file mode 100644 index 0000000000000..f04b014bb3042 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md @@ -0,0 +1,160 @@ +# `source-based-code-coverage` + +The feature request for this feature is: [#34701] + +The Major Change Proposal (MCP) for this feature is: [#278](https://github.com/rust-lang/compiler-team/issues/278) + +------------------------ + +## Introduction + +The Rust compiler includes two code coverage implementations: + +* A GCC-compatible, gcov-based coverage implementation, enabled with [`-Zprofile`](profile.md), which operates on DebugInfo. +* A source-based code coverage implementation, enabled with `-Zinstrument-coverage`, which uses LLVM's native coverage instrumentation to generate very precise coverage data. + +This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-Zinstrument-coverage` compiler flag. + +## How it works + +When `-Zinstrument-coverage` is enabled, the Rust compiler enhances rust-based libraries and binaries by: + +* Automatically injecting calls to an LLVM intrinsic ([`llvm.instrprof.increment`]), at functions and branches in compiled code, to increment counters when conditional sections of code are executed. +* Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format]), to define the code regions (start and end positions in the source code) being counted. + +When running a coverage-instrumented program, the counter values are written to a `profraw` file at program termination. LLVM bundles tools that read the counter results, combine those results with the coverage map (embedded in the program binary), and generate coverage reports in multiple formats. + +## Enable coverage profiling in the Rust compiler + +*IMPORTANT:* Rust's coverage profiling features may not be enabled, by default. To enable them, you may need to build a version of the Rust compiler with the `profiler` feature enabled. + +First, edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`: + +```toml +# Build the profiler runtime (required when compiling with options that depend +# on this runtime, such as `-C profile-generate` or `-Z instrument-coverage`). +profiler = true +``` + +Then rebuild the Rust compiler (see [rustc-dev-guide-how-to-build-and-run]). + +### Building the demangler + +LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler. Rust's symbol name demangler can be built with: + +```shell +$ ./x.py build rust-demangler +``` + +## Compiling with coverage enabled + +Set the `-Zinstrument-coverage` compiler flag in order to enable LLVM source-based code coverage profiling. + +With `cargo`, you can instrument your program binary *and* dependencies at the same time. + +For example (if your project's Cargo.toml builds a binary by default): + +```shell +$ cd your-project +$ cargo clean +$ RUSTFLAGS="-Zinstrument-coverage" cargo build +``` + +If `cargo` is not configured to use your `profiler`-enabled version of `rustc`, set the path explicitly via the `RUSTC` environment variable. Here is another example, using a `stage1` build of `rustc` to compile an `example` binary (from the [`json5format`](https://crates.io/crates/json5format) crate): + +```shell +$ RUSTC=$HOME/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc \ + RUSTFLAGS="-Zinstrument-coverage" \ + cargo build --example formatjson5 +``` + +## Running the instrumented binary to generate raw coverage profiling data + +In the previous example, `cargo` generated the coverage-instrumented binary `formatjson5`: + +```shell +$ echo "{some: 'thing'}" | target/debug/examples/formatjson5 - +``` +```json5 +{ + some: 'thing', +} +``` + +After running this program, a new file, `default.profraw`, should be in the current working directory. It's often preferable to set a specific file name or path. You can change the output file using the environment variable `LLVM_PROFILE_FILE`: + + +```shell +$ echo "{some: 'thing'}" \ + | LLVM_PROFILE_FILE="formatjson5.profraw" target/debug/examples/formatjson5 - +... +$ ls formatjson5.profraw +formatjson5.profraw +``` + +If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing directory structure will be created. Additionally, the following special pattern strings are rewritten: + +* `%p` - The process ID. +* `%h` - The hostname of the machine running the program. +* `%t` - The value of the TMPDIR environment variable. +* `%Nm` - the instrumented binary’s signature: The runtime creates a pool of N raw profiles, used for on-line profile merging. The runtime takes care of selecting a raw profile from the pool, locking it, and updating it before the program exits. `N` must be between `1` and `9`, and defaults to `1` if omitted (with simply `%m`). +* `%c` - Does not add anything to the filename, but enables a mode (on some platforms, including Darwin) in which profile counter updates are continuously synced to a file. This means that if the instrumented program crashes, or is killed by a signal, perfect coverage information can still be recovered. + +## Creating coverage reports + +LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools, or use the LLVM tools bundled with the same Rust distrubition used to rebuild the Rust compiler (as shown in the following examples). + +Raw profiles have to be indexed before they can be used to generate coverage reports. This is done using [`llvm-profdata merge`] (which can combine multiple raw profiles and index them at the same time): + +```shell +$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-profdata merge \ + -sparse formatjson5.profraw -o formatjson5.profdata +``` + +Finally, the `.profdata` file is used, in combination with the coverage map (from the program binary) to generate coverage reports using [`llvm-cov report`]--for a coverage summaries--and [`llvm-cov show`]--to see detailed coverage of lines and regions (character ranges), overlaid on the original source code. + +These commands have several display and filtering options. For example: + +```shell +$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show \ + -instr-profile=formatjson5.profdata \ + target/debug/examples/formatjson5 \ + -show-line-counts-or-regions \ + -Xdemangler=$HOME/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler \ + -show-instantiations \ + -name=add_quoted_string +``` + +Screenshot of sample `llvm-cov show` result, for function add_quoted_string +
+
+ +Some of the more notable options in this example include: + +* `--instr-profile=.profdata` - the location of the `.profdata` file created by `llvm-profdata merge` +* `target/debug/examples/formatjson5` - the binary that generated the coverage profiling data (originally as a `.profraw` file) +* `--Xdemangler=/rust-demangler` - the location of the `rust-demangler` tool +* `--name=` - to show coverage for a specific function (or, consider using another filter option, such as `--name-regex=`) + +## Interpreting reports + +There are four statistics tracked in a coverage summary: + +* Function coverage is the percentage of functions that have been executed at least once. A function is considered to be executed if any of its instantiations are executed. +* Instantiation coverage is the percentage of function instantiations that have been executed at least once. Generic functions and functions generated from macros are two kinds of functions that may have multiple instantiations. +* Line coverage is the percentage of code lines that have been executed at least once. Only executable lines within function bodies are considered to be code lines. +* Region coverage is the percentage of code regions that have been executed at least once. A code region may span multiple lines: for example, in a large function body with no control flow. In other cases, a single line can contain multiple code regions: `return x || (y && z)` has countable code regions for `x` (which may resolve the expression, if `x` is `true`), `|| (y && z)` (executed only if `x` was `false`), and `return` (executed in either situation). + +Of these four statistics, function coverage is usually the least granular while region coverage is the most granular. The project-wide totals for each statistic are listed in the summary. + +## Other references + +Rust's implementation and workflow for source-based code coverage is based on the same library and tools used to implement [source-based code coverage in Clang](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html). (This document is partially based on the Clang guide.) + +[#34701]: https://github.com/rust-lang/rust/issues/34701 +[`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic +[LLVM Code Coverage Mapping Format]: https://llvm.org/docs/CoverageMappingFormat.html +[rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html +[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge +[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report +[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show From c83c6357512f809a92556f9198314d87a5d3a965 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 2 Nov 2020 16:03:23 +0800 Subject: [PATCH 24/27] Fix intrinsic size_of stable link I noticed that it is pointing to the same link when I was reading https://github.com/rust-lang/rust-clippy/issues/2997 --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index dbc7921a62a67..3e5d7caa2fe5d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -764,7 +764,7 @@ extern "rust-intrinsic" { /// More specifically, this is the offset in bytes between successive /// items of the same type, including alignment padding. /// - /// The stabilized version of this intrinsic is [`size_of`]. + /// The stabilized version of this intrinsic is [`crate::mem::size_of`]. #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] pub fn size_of() -> usize; From e78e9d4a06192cfbb9e1417fdd7a0753d51684a3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 25 Oct 2020 17:14:19 -0400 Subject: [PATCH 25/27] Treat trailing semicolon as a statement in macro call See https://github.com/rust-lang/rust/issues/61733#issuecomment-716188981 We now preserve the trailing semicolon in a macro invocation, even if the macro expands to nothing. As a result, the following code no longer compiles: ```rust macro_rules! empty { () => { } } fn foo() -> bool { //~ ERROR mismatched { true } //~ ERROR mismatched empty!(); } ``` Previously, `{ true }` would be considered the trailing expression, even though there's a semicolon in `empty!();` This makes macro expansion more token-based. --- compiler/rustc_ast/src/ast.rs | 7 ++++ compiler/rustc_expand/src/placeholders.rs | 38 ++++++++++++++++++- .../rustc_lint/src/redundant_semicolon.rs | 5 +++ src/test/ui/macros/empty-trailing-stmt.rs | 10 +++++ src/test/ui/macros/empty-trailing-stmt.stderr | 17 +++++++++ .../ui/proc-macro/meta-macro-hygiene.stdout | 2 +- 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/macros/empty-trailing-stmt.rs create mode 100644 src/test/ui/macros/empty-trailing-stmt.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7d5e235c88526..f13d67b9c1584 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -905,6 +905,13 @@ pub struct Stmt { } impl Stmt { + pub fn has_trailing_semicolon(&self) -> bool { + match &self.kind { + StmtKind::Semi(_) => true, + StmtKind::MacCall(mac) => matches!(mac.style, MacStmtStyle::Semicolon), + _ => false, + } + } pub fn add_trailing_semicolon(mut self) -> Self { self.kind = match self.kind { StmtKind::Expr(expr) => StmtKind::Semi(expr), diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 1bc14ae41bf29..0cffca1727124 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -310,8 +310,44 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { }; if style == ast::MacStmtStyle::Semicolon { + // Implement the proposal described in + // https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449 + // + // The macro invocation expands to the list of statements. + // If the list of statements is empty, then 'parse' + // the trailing semicolon on the original invocation + // as an empty statement. That is: + // + // `empty();` is parsed as a single `StmtKind::Empty` + // + // If the list of statements is non-empty, see if the + // final statement alreayd has a trailing semicolon. + // + // If it doesn't have a semicolon, then 'parse' the trailing semicolon + // from the invocation as part of the final statement, + // using `stmt.add_trailing_semicolon()` + // + // If it does have a semicolon, then 'parse' the trailing semicolon + // from the invocation as a new StmtKind::Empty + + // FIXME: We will need to preserve the original + // semicolon token and span as part of #15701 + let empty_stmt = ast::Stmt { + id: ast::DUMMY_NODE_ID, + kind: ast::StmtKind::Empty, + span: DUMMY_SP, + tokens: None, + }; + if let Some(stmt) = stmts.pop() { - stmts.push(stmt.add_trailing_semicolon()); + if stmt.has_trailing_semicolon() { + stmts.push(stmt); + stmts.push(empty_stmt); + } else { + stmts.push(stmt.add_trailing_semicolon()); + } + } else { + stmts.push(empty_stmt); } } diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index a31deb87ff0d0..84cc7b68d4ca9 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -42,6 +42,11 @@ impl EarlyLintPass for RedundantSemicolons { fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, bool)>) { if let Some((span, multiple)) = seq.take() { + // FIXME: Find a better way of ignoring the trailing + // semicolon from macro expansion + if span == rustc_span::DUMMY_SP { + return; + } cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| { let (msg, rem) = if multiple { ("unnecessary trailing semicolons", "remove these semicolons") diff --git a/src/test/ui/macros/empty-trailing-stmt.rs b/src/test/ui/macros/empty-trailing-stmt.rs new file mode 100644 index 0000000000000..3d78ed4a4759a --- /dev/null +++ b/src/test/ui/macros/empty-trailing-stmt.rs @@ -0,0 +1,10 @@ +macro_rules! empty { + () => { } +} + +fn foo() -> bool { //~ ERROR mismatched + { true } //~ ERROR mismatched + empty!(); +} + +fn main() {} diff --git a/src/test/ui/macros/empty-trailing-stmt.stderr b/src/test/ui/macros/empty-trailing-stmt.stderr new file mode 100644 index 0000000000000..e88b12712fb8c --- /dev/null +++ b/src/test/ui/macros/empty-trailing-stmt.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/empty-trailing-stmt.rs:6:7 + | +LL | { true } + | ^^^^ expected `()`, found `bool` + +error[E0308]: mismatched types + --> $DIR/empty-trailing-stmt.rs:5:13 + | +LL | fn foo() -> bool { + | --- ^^^^ expected `bool`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.stdout b/src/test/ui/proc-macro/meta-macro-hygiene.stdout index 81cebae17aeba..a067b7b5411dd 100644 --- a/src/test/ui/proc-macro/meta-macro-hygiene.stdout +++ b/src/test/ui/proc-macro/meta-macro-hygiene.stdout @@ -40,7 +40,7 @@ macro_rules! produce_it } } -fn main /* 0#0 */() { } +fn main /* 0#0 */() { ; } /* Expansions: From 6d949112f624616db58ecf12b8acb08b82d22758 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 2 Nov 2020 11:59:24 -0800 Subject: [PATCH 26/27] addressed feedback --- .../source-based-code-coverage.md | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md index f04b014bb3042..1dd7272e0f92a 100644 --- a/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md +++ b/src/doc/unstable-book/src/compiler-flags/source-based-code-coverage.md @@ -26,9 +26,11 @@ When running a coverage-instrumented program, the counter values are written to ## Enable coverage profiling in the Rust compiler -*IMPORTANT:* Rust's coverage profiling features may not be enabled, by default. To enable them, you may need to build a version of the Rust compiler with the `profiler` feature enabled. +Rust's source-based code coverage requires the Rust "profiler runtime". Without it, compiling with `-Zinstrument-coverage` generates an error that the profiler runtime is missing. -First, edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`: +The Rust `nightly` distribution channel should include the profiler runtime, by default. + +*IMPORTANT:* If you are building the Rust compiler from the source distribution, the profiler runtime is *not* enabled in the default `config.toml.example`, and may not be enabled in your `config.toml`. Edit the `config.toml` file, and find the `profiler` feature entry. Uncomment it and set it to `true`: ```toml # Build the profiler runtime (required when compiling with options that depend @@ -40,7 +42,15 @@ Then rebuild the Rust compiler (see [rustc-dev-guide-how-to-build-and-run]). ### Building the demangler -LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler. Rust's symbol name demangler can be built with: +LLVM coverage reporting tools generate results that can include function names and other symbol references, and the raw coverage results report symbols using the compiler's "mangled" version of the symbol names, which can be difficult to interpret. To work around this issue, LLVM coverage tools also support a user-specified symbol name demangler. + +One option for a Rust demangler is [`rustfilt`](https://crates.io/crates/rustfilt), which can be installed with: + +```shell +cargo install rustfilt +``` + +Another option, if you are building from the Rust compiler source distribution, is to use the `rust-demangler` tool included in the Rust source distribution, which can be built with: ```shell $ ./x.py build rust-demangler @@ -102,13 +112,14 @@ If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing ## Creating coverage reports -LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools, or use the LLVM tools bundled with the same Rust distrubition used to rebuild the Rust compiler (as shown in the following examples). +LLVM's tools to process coverage data and coverage maps have some version dependencies. If you encounter a version mismatch, try updating your LLVM tools. + +If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`. (Look for `llvm-profdata` and `llvm-cov`.) Raw profiles have to be indexed before they can be used to generate coverage reports. This is done using [`llvm-profdata merge`] (which can combine multiple raw profiles and index them at the same time): ```shell -$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-profdata merge \ - -sparse formatjson5.profraw -o formatjson5.profdata +$ llvm-profdata merge -sparse formatjson5.profraw -o formatjson5.profdata ``` Finally, the `.profdata` file is used, in combination with the coverage map (from the program binary) to generate coverage reports using [`llvm-cov report`]--for a coverage summaries--and [`llvm-cov show`]--to see detailed coverage of lines and regions (character ranges), overlaid on the original source code. @@ -116,11 +127,9 @@ Finally, the `.profdata` file is used, in combination with the coverage map (fro These commands have several display and filtering options. For example: ```shell -$ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show \ +$ llvm-cov show -Xdemangler=rustfilt target/debug/examples/formatjson5 \ -instr-profile=formatjson5.profdata \ - target/debug/examples/formatjson5 \ -show-line-counts-or-regions \ - -Xdemangler=$HOME/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler \ -show-instantiations \ -name=add_quoted_string ``` @@ -131,9 +140,9 @@ $ $HOME/rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-cov show \ Some of the more notable options in this example include: -* `--instr-profile=.profdata` - the location of the `.profdata` file created by `llvm-profdata merge` -* `target/debug/examples/formatjson5` - the binary that generated the coverage profiling data (originally as a `.profraw` file) -* `--Xdemangler=/rust-demangler` - the location of the `rust-demangler` tool +* `--Xdemangler=rustfilt` - the command name or path used to demangle Rust symbols (`rustfilt` in the example, but this could also be a path to the `rust-demangler` tool) +* `target/debug/examples/formatjson5` - the instrumented binary (from which to extract the coverage map) +* `--instr-profile=.profdata` - the location of the `.profdata` file created by `llvm-profdata merge` (from the `.profraw` file generated by the instrumented binary) * `--name=` - to show coverage for a specific function (or, consider using another filter option, such as `--name-regex=`) ## Interpreting reports @@ -155,6 +164,6 @@ Rust's implementation and workflow for source-based code coverage is based on th [`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic [LLVM Code Coverage Mapping Format]: https://llvm.org/docs/CoverageMappingFormat.html [rustc-dev-guide-how-to-build-and-run]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html -[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge -[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report -[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show +[`llvm-profdata merge`]: https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge +[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report +[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show From 3d7baee7378526cbb15c160a73624224d605d713 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 2 Nov 2020 15:01:30 -0800 Subject: [PATCH 27/27] fix cross-platform test bugs More portable way to make python 2/3 portable. Strip Args line (with hardcoded paths) from debug counters output. --- src/test/run-make-fulldeps/coverage-reports-base/Makefile | 8 +++++++- .../expected_show_coverage_counters.closure.txt | 1 - .../expected_show_coverage_counters.drop_trait.txt | 1 - .../expected_show_coverage_counters.generics.txt | 1 - .../expected_show_coverage_counters.if.txt | 1 - .../expected_show_coverage_counters.if_else.txt | 1 - .../expected_show_coverage_counters.inner_items.txt | 1 - .../expected_show_coverage_counters.lazy_boolean.txt | 1 - .../expected_show_coverage_counters.loop_break_value.txt | 1 - ...expected_show_coverage_counters.loops_and_branches.txt | 1 - .../expected_show_coverage_counters.nested_loops.txt | 1 - ...overage_counters.partial_eq_counter_without_region.txt | 1 - .../expected_show_coverage_counters.simple_loop.txt | 1 - .../expected_show_coverage_counters.simple_match.txt | 1 - ...xpected_show_coverage_counters.tight_infinite_loop.txt | 1 - .../expected_show_coverage_counters.try_error_result.txt | 1 - ...expected_show_coverage_counters.various_conditions.txt | 1 - .../expected_show_coverage_counters.while.txt | 1 - ...expected_show_coverage_counters.while_early_return.txt | 1 - .../expected_show_coverage_counters.closure.txt | 1 - .../expected_show_coverage_counters.drop_trait.txt | 1 - .../expected_show_coverage_counters.generics.txt | 1 - .../expected_show_coverage_counters.if.txt | 1 - .../expected_show_coverage_counters.if_else.txt | 1 - .../expected_show_coverage_counters.inner_items.txt | 1 - .../expected_show_coverage_counters.lazy_boolean.txt | 1 - .../expected_show_coverage_counters.loop_break_value.txt | 1 - ...expected_show_coverage_counters.loops_and_branches.txt | 1 - .../expected_show_coverage_counters.nested_loops.txt | 1 - ...overage_counters.partial_eq_counter_without_region.txt | 1 - .../expected_show_coverage_counters.simple_loop.txt | 1 - .../expected_show_coverage_counters.simple_match.txt | 1 - ...xpected_show_coverage_counters.tight_infinite_loop.txt | 1 - .../expected_show_coverage_counters.try_error_result.txt | 1 - ...expected_show_coverage_counters.various_conditions.txt | 1 - .../expected_show_coverage_counters.while.txt | 1 - ...expected_show_coverage_counters.while_early_return.txt | 1 - .../coverage-spanview-base/escape_url.py | 6 ++++-- 38 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/Makefile b/src/test/run-make-fulldeps/coverage-reports-base/Makefile index bfecc5fd7f557..d35fa87f702ee 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/Makefile +++ b/src/test/run-make-fulldeps/coverage-reports-base/Makefile @@ -61,7 +61,13 @@ endif --instr-profile="$(TMPDIR)"/$@.profdata \ $(call BIN,"$(TMPDIR)"/$@) \ > "$(TMPDIR)"/actual_show_coverage.$@.txt \ - 2> "$(TMPDIR)"/actual_show_coverage_counters.$@.txt + 2> "$(TMPDIR)"/show_coverage_stderr.$@.txt + + # The first line (beginning with "Args:" contains hard-coded, build-specific + # file paths. Strip that line and keep the remaining lines with counter debug + # data. + tail -n +2 "$(TMPDIR)"/show_coverage_stderr.$@.txt \ + > "$(TMPDIR)"/actual_show_coverage_counters.$@.txt ifdef RUSTC_BLESS_TEST cp "$(TMPDIR)"/actual_show_coverage.$@.txt \ diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt index ef43bbd78a6b5..fb797796e4e7d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.closure.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/closure.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/closure Counter in file 0 20:21 -> 20:38, #1 Counter in file 0 21:20 -> 21:28, (#1 + 0) Counter in file 0 21:29 -> 23:18, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt index 9716284f52521..375025fe8bcc2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.drop_trait.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/drop_trait.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/drop_trait Counter in file 0 9:24 -> 11:6, #1 Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt index 5fbfe69b891c0..013a69ed3983a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.generics.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/generics.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/generics Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 23:9 -> 28:28, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt index 48c9278a23917..c2bef365ea9d8 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if Counter in file 0 8:5 -> 18:10, #1 Counter in file 0 21:9 -> 21:16, (#1 + 0) Counter in file 0 22:5 -> 27:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt index 1adf92300bfbd..faf5c094bbaaa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.if_else.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/if_else Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 Counter in file 0 20:9 -> 22:16, (#1 - #2) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt index 0678be30dc341..65cd6481af4cc 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.inner_items.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/inner_items.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/inner_items Counter in file 0 19:13 -> 19:18, #1 Counter in file 0 20:13 -> 20:14, #2 Counter in file 0 20:17 -> 20:22, (#1 + 0) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt index e955fcd8ba05e..8e56d79d9d2aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.lazy_boolean.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/lazy_boolean.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/lazy_boolean Counter in file 0 7:9 -> 9:42, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 14:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt index df16c54617c43..a6144b8072ace 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loop_break_value.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loop_break_value.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loop_break_value Counter in file 0 3:11 -> 13:2, #1 Emitting segments for file: ../coverage/loop_break_value.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt index 171b77c9cc749..071598672f722 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.loops_and_branches.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/loops_and_branches Counter in file 0 10:12 -> 10:16, #1 Counter in file 0 11:16 -> 11:21, #2 Counter in file 0 14:14 -> 14:15, (#2 - #5) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt index ac376c4f36a40..f503007353319 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.nested_loops.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/nested_loops Counter in file 0 2:9 -> 3:27, #1 Counter in file 0 5:19 -> 5:32, (#1 + #2) Counter in file 0 6:13 -> 7:24, ((#1 + #2) - #3) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt index d2a68ab32022d..133ed05c41d6d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/partial_eq_counter_without_region Counter in file 0 7:5 -> 7:6, #1 Counter in file 0 21:11 -> 26:2, #1 Counter in file 0 4:17 -> 4:22, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt index 148768f423ba0..255173e5534d1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_loop.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_loop Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 12:9 -> 12:16, (#1 + 0) Counter in file 0 13:5 -> 18:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt index 2a3c004fa7abe..1682a379bc0ff 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.simple_match.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_match.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/simple_match Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt index 5180ddd7de669..57b42528840ca 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.tight_infinite_loop.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/tight_infinite_loop Counter in file 0 2:8 -> 2:13, #1 Counter in file 0 5:1 -> 5:2, (#1 - #2) Emitting segments for file: ../coverage/tight_infinite_loop.rs diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt index d851fdeb745f7..a317cd792910d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.try_error_result.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/try_error_result Counter in file 0 13:9 -> 14:23, #1 Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt index b229410a495a3..3b583a978a961 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.various_conditions.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/various_conditions.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/various_conditions Counter in file 0 4:9 -> 4:26, #1 Counter in file 0 5:8 -> 5:12, (#1 + 0) Counter in file 0 5:13 -> 7:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt index d496805955f78..b0e881da7c8cb 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while Counter in file 0 2:9 -> 2:16, #1 Counter in file 0 3:11 -> 3:20, (#1 + #2) Counter in file 0 3:21 -> 4:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt index a343f5056ac29..723341c43d9ab 100644 --- a/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-base/expected_show_coverage_counters.while_early_return.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-base/coverage-reports-base/while_early_return Counter in file 0 5:9 -> 5:27, #1 Counter in file 0 7:9 -> 9:10, (#1 + #2) Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt index d443ba0aba3a0..fb797796e4e7d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.closure.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/closure.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/closure Counter in file 0 20:21 -> 20:38, #1 Counter in file 0 21:20 -> 21:28, (#1 + 0) Counter in file 0 21:29 -> 23:18, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt index 08fbbd13adbe1..375025fe8bcc2 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.drop_trait.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/drop_trait.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/drop_trait Counter in file 0 9:24 -> 11:6, #1 Counter in file 0 15:9 -> 17:42, #1 Counter in file 0 19:8 -> 19:12, (#1 + 0) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt index eb707c5e7acc2..013a69ed3983a 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.generics.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/generics.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/generics Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 17:24 -> 19:6, #1 Counter in file 0 23:9 -> 28:28, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt index d186f440ddb1f..c2bef365ea9d8 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if Counter in file 0 8:5 -> 18:10, #1 Counter in file 0 21:9 -> 21:16, (#1 + 0) Counter in file 0 22:5 -> 27:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt index 8220060f26ff2..faf5c094bbaaa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.if_else.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/if_else Counter in file 0 7:9 -> 11:16, #1 Counter in file 0 12:5 -> 17:6, #2 Counter in file 0 20:9 -> 22:16, (#1 - #2) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt index c173cc20f815a..65cd6481af4cc 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.inner_items.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/inner_items.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/inner_items Counter in file 0 19:13 -> 19:18, #1 Counter in file 0 20:13 -> 20:14, #2 Counter in file 0 20:17 -> 20:22, (#1 + 0) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt index 191a3a58355d2..8e56d79d9d2aa 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.lazy_boolean.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/lazy_boolean.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/lazy_boolean Counter in file 0 7:9 -> 9:42, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 14:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt index 3f5fc4a440164..a6144b8072ace 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loop_break_value.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loop_break_value.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loop_break_value Counter in file 0 3:11 -> 13:2, #1 Emitting segments for file: ../coverage/loop_break_value.rs Combined regions: diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt index 235557ba3495c..071598672f722 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.loops_and_branches.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/loops_and_branches Counter in file 0 10:12 -> 10:16, #1 Counter in file 0 11:16 -> 11:21, #2 Counter in file 0 14:14 -> 14:15, (#2 - #5) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt index 6bc26f94ac7c0..f503007353319 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.nested_loops.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/nested_loops Counter in file 0 2:9 -> 3:27, #1 Counter in file 0 5:19 -> 5:32, (#1 + #2) Counter in file 0 6:13 -> 7:24, ((#1 + #2) - #3) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt index 442d6ca9dfdc4..69a772c30f650 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.partial_eq_counter_without_region.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/partial_eq_counter_without_region Counter in file 0 4:32 -> 4:33, (#3 + (#1 + #2)) Counter in file 0 4:48 -> 4:49, ((#1 + #2) + ((#3 + #4) + ((#5 + #6) + #7))) Counter in file 0 21:11 -> 26:2, #1 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt index 60d861e9d2e15..255173e5534d1 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_loop.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_loop Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 12:9 -> 12:16, (#1 + 0) Counter in file 0 13:5 -> 18:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt index 1683b68e96641..1682a379bc0ff 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.simple_match.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_match.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/simple_match Counter in file 0 7:9 -> 9:26, #1 Counter in file 0 10:8 -> 10:15, (#1 + 0) Counter in file 0 10:16 -> 12:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt index 39a3cf5458c64..57b42528840ca 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.tight_infinite_loop.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/tight_infinite_loop Counter in file 0 2:8 -> 2:13, #1 Counter in file 0 5:1 -> 5:2, (#1 - #2) Emitting segments for file: ../coverage/tight_infinite_loop.rs diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt index 4e9e5a6e5944f..a317cd792910d 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.try_error_result.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/try_error_result Counter in file 0 13:9 -> 14:23, #1 Counter in file 0 17:9 -> 17:10, ((#1 + (#2 + #3)) - #4) Counter in file 0 19:9 -> 19:14, (#1 + (#2 + #3)) diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt index ba80cadbd3c8a..3b583a978a961 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.various_conditions.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/various_conditions.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/various_conditions Counter in file 0 4:9 -> 4:26, #1 Counter in file 0 5:8 -> 5:12, (#1 + 0) Counter in file 0 5:13 -> 7:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt index 76cf1e92ecd3b..b0e881da7c8cb 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while Counter in file 0 2:9 -> 2:16, #1 Counter in file 0 3:11 -> 3:20, (#1 + #2) Counter in file 0 3:21 -> 4:6, #2 diff --git a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt index 60f389fc9d467..723341c43d9ab 100644 --- a/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt +++ b/src/test/run-make-fulldeps/coverage-reports-deadcode/expected_show_coverage_counters.while_early_return.txt @@ -1,4 +1,3 @@ -Args: /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/llvm/build/bin/llvm-cov show --debug --Xdemangler=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/stage0-tools-bin/rust-demangler --show-line-counts-or-regions --instr-profile=/usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return.profdata /usr/local/google/home/richkadel/rust/build/x86_64-unknown-linux-gnu/test/run-make-fulldeps/coverage-reports-deadcode/coverage-reports-deadcode/while_early_return Counter in file 0 5:9 -> 5:27, #1 Counter in file 0 7:9 -> 9:10, (#1 + #2) Counter in file 0 12:13 -> 14:14, ((#1 + #2) - #3) diff --git a/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py b/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py index 6d2ded697b38e..b725ed4630302 100644 --- a/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py +++ b/src/test/run-make-fulldeps/coverage-spanview-base/escape_url.py @@ -1,10 +1,12 @@ #!/usr/bin/env python import sys -import six # Support python 2 or 3 -from six.moves.urllib.parse import quote +try: + from urllib.parse import quote +except ImportError: + from urllib import quote # Converts the input string into a valid URL parameter string. print (quote(' '.join(sys.argv[1:])))