Importing rustc-1.53.0
Bug: 194400612
Change-Id: Id2f38eeabc8325fff960e46b89b1cc7216f5227c
diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs
index aabfee5..4836148 100644
--- a/compiler/rustc_mir/src/transform/coverage/debug.rs
+++ b/compiler/rustc_mir/src/transform/coverage/debug.rs
@@ -121,6 +121,7 @@
use rustc_middle::mir::{self, BasicBlock, TerminatorKind};
use rustc_middle::ty::TyCtxt;
+use std::iter;
use std::lazy::SyncOnceCell;
pub const NESTED_INDENT: &str = " ";
@@ -703,9 +704,7 @@
let edge_counters = from_terminator
.successors()
.map(|&successor_bb| graphviz_data.get_edge_counter(from_bcb, successor_bb));
- edge_labels
- .iter()
- .zip(edge_counters)
+ iter::zip(&edge_labels, edge_counters)
.map(|(label, some_counter)| {
if let Some(counter) = some_counter {
format!("{}\n{}", label, debug_counters.format_counter(counter))
@@ -817,7 +816,7 @@
sections
}
-/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any
+/// Returns a simple string representation of a `TerminatorKind` variant, independent of any
/// values it might hold.
pub(super) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
match kind {
diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs
index 93133e9..eaeb442 100644
--- a/compiler/rustc_mir/src/transform/coverage/mod.rs
+++ b/compiler/rustc_mir/src/transform/coverage/mod.rs
@@ -23,6 +23,7 @@
use rustc_middle::hir;
use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::ich::StableHashingContext;
+use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::{
self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator,
@@ -87,6 +88,11 @@
_ => {}
}
+ let codegen_fn_attrs = tcx.codegen_fn_attrs(mir_source.def_id());
+ if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
+ return;
+ }
+
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());
@@ -111,7 +117,8 @@
let body_span = hir_body.value.span;
let source_file = source_map.lookup_source_file(body_span.lo());
let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
- Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.hi()))
+ fn_sig.span.ctxt() == body_span.ctxt()
+ && Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo()))
}) {
Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
None => body_span.shrink_to_lo(),
diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs
index de8447f..2ba9d1b 100644
--- a/compiler/rustc_mir/src/transform/coverage/query.rs
+++ b/compiler/rustc_mir/src/transform/coverage/query.rs
@@ -6,10 +6,9 @@
use rustc_middle::ty::{self, 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).
+/// A `query` provider for retrieving coverage information injected into MIR.
pub(crate) fn provide(providers: &mut Providers) {
- providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id);
+ providers.coverageinfo = |tcx, def_id| coverageinfo(tcx, def_id);
providers.covered_file_name = |tcx, def_id| covered_file_name(tcx, def_id);
providers.covered_code_regions = |tcx, def_id| covered_code_regions(tcx, def_id);
}
@@ -121,7 +120,7 @@
}
}
-fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo {
+fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo {
let mir_body = mir_body(tcx, def_id);
let mut coverage_visitor = CoverageVisitor {
@@ -139,29 +138,22 @@
}
fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> {
- let body = mir_body(tcx, def_id);
- for bb_data in body.basic_blocks().iter() {
- for statement in bb_data.statements.iter() {
- if let StatementKind::Coverage(box ref coverage) = statement.kind {
- if let Some(code_region) = coverage.code_region.as_ref() {
- if is_inlined(body, statement) {
- continue;
+ if tcx.is_mir_available(def_id) {
+ let body = mir_body(tcx, def_id);
+ for bb_data in body.basic_blocks().iter() {
+ for statement in bb_data.statements.iter() {
+ if let StatementKind::Coverage(box ref coverage) = statement.kind {
+ if let Some(code_region) = coverage.code_region.as_ref() {
+ if is_inlined(body, statement) {
+ continue;
+ }
+ return Some(code_region.file_name);
}
- return Some(code_region.file_name);
}
}
}
}
- None
-}
-
-/// This function ensures we obtain the correct MIR for the given item irrespective of
-/// whether that means const mir or runtime mir. For `const fn` this opts for runtime
-/// mir.
-fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> {
- let id = ty::WithOptConstParam::unknown(def_id);
- let def = ty::InstanceDef::Item(id);
- tcx.instance_mir(def)
+ return None;
}
fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
@@ -188,3 +180,12 @@
let scope_data = &body.source_scopes[statement.source_info.scope];
scope_data.inlined.is_some() || scope_data.inlined_parent_scope.is_some()
}
+
+/// This function ensures we obtain the correct MIR for the given item irrespective of
+/// whether that means const mir or runtime mir. For `const fn` this opts for runtime
+/// mir.
+fn mir_body<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx mir::Body<'tcx> {
+ let id = ty::WithOptConstParam::unknown(def_id);
+ let def = ty::InstanceDef::Item(id);
+ tcx.instance_mir(def)
+}
diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs
index e7097ce..2041109 100644
--- a/compiler/rustc_mir/src/transform/coverage/spans.rs
+++ b/compiler/rustc_mir/src/transform/coverage/spans.rs
@@ -11,7 +11,7 @@
use rustc_middle::ty::TyCtxt;
use rustc_span::source_map::original_sp;
-use rustc_span::{BytePos, Span, SyntaxContext};
+use rustc_span::{BytePos, Span};
use std::cmp::Ordering;
@@ -240,7 +240,7 @@
/// to be).
pub(super) fn generate_coverage_spans(
mir_body: &'a mir::Body<'tcx>,
- fn_sig_span: Span,
+ fn_sig_span: Span, // Ensured to be same SourceFile and SyntaxContext as `body_span`
body_span: Span,
basic_coverage_blocks: &'a CoverageGraph,
) -> Vec<CoverageSpan> {
@@ -683,10 +683,10 @@
// and `_1` is the `Place` for `somenum`.
//
// If and when the Issue is resolved, remove this special case match pattern:
- StatementKind::FakeRead(cause, _) if cause == FakeReadCause::ForGuardBinding => None,
+ StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None,
// Retain spans from all other statements
- StatementKind::FakeRead(_, _) // Not including `ForGuardBinding`
+ StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
| StatementKind::CopyNonOverlapping(..)
| StatementKind::Assign(_)
| StatementKind::SetDiscriminant { .. }
@@ -717,11 +717,21 @@
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::Goto { .. } => None,
+ // Call `func` operand can have a more specific span when part of a chain of calls
+ | TerminatorKind::Call { ref func, .. } => {
+ let mut span = terminator.source_info.span;
+ if let mir::Operand::Constant(box constant) = func {
+ if constant.span.lo() > span.lo() {
+ span = span.with_lo(constant.span.lo());
+ }
+ }
+ Some(function_source_span(span, body_span))
+ }
+
// Retain spans from all other terminators
TerminatorKind::Resume
| TerminatorKind::Abort
| TerminatorKind::Return
- | TerminatorKind::Call { .. }
| TerminatorKind::Yield { .. }
| TerminatorKind::GeneratorDrop
| TerminatorKind::FalseUnwind { .. }
@@ -733,6 +743,6 @@
#[inline]
fn function_source_span(span: Span, body_span: Span) -> Span {
- let span = original_sp(span, body_span).with_ctxt(SyntaxContext::root());
+ let span = original_sp(span, body_span).with_ctxt(body_span.ctxt());
if body_span.contains(span) { span } else { body_span }
}
diff --git a/compiler/rustc_mir/src/transform/coverage/tests.rs b/compiler/rustc_mir/src/transform/coverage/tests.rs
index 7a9bfaa..dee1124 100644
--- a/compiler/rustc_mir/src/transform/coverage/tests.rs
+++ b/compiler/rustc_mir/src/transform/coverage/tests.rs
@@ -17,7 +17,7 @@
//! Also note, some basic features of `Span` also rely on the `Span`s own "session globals", which
//! are unrelated to the `TyCtxt` global. Without initializing the `Span` session globals, some
//! basic, coverage-specific features would be impossible to test, but thankfully initializing these
-//! globals is comparitively simpler. The easiest way is to wrap the test in a closure argument
+//! globals is comparatively simpler. The easiest way is to wrap the test in a closure argument
//! to: `rustc_span::with_default_session_globals(|| { test_here(); })`.
use super::counters;