diff options
Diffstat (limited to 'compiler/rustc_mir/src')
9 files changed, 93 insertions, 97 deletions
diff --git a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index 994b403abf3..1bfbb843114 100644 --- a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs @@ -137,10 +137,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.loc, InteriorOfSliceOrArray { ty: place_ty, - is_index: match elem { - ProjectionElem::Index(..) => true, - _ => false, - }, + is_index: matches!(elem, ProjectionElem::Index(..)), }, )); } diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index 48361483099..2397d627880 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -120,6 +120,7 @@ use rustc_index::vec::Idx; use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, BasicBlock, TerminatorKind}; use rustc_middle::ty::TyCtxt; +use rustc_span::Span; use std::iter; use std::lazy::SyncOnceCell; @@ -636,6 +637,7 @@ pub(super) fn dump_coverage_spanview( mir_body: &mir::Body<'tcx>, basic_coverage_blocks: &CoverageGraph, pass_name: &str, + body_span: Span, coverage_spans: &Vec<CoverageSpan>, ) { let mir_source = mir_body.source; @@ -647,7 +649,7 @@ pub(super) fn dump_coverage_spanview( 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) + spanview::write_document(tcx, body_span, span_viewables, &title, &mut file) .expect("Unexpected IO error dumping coverage spans as HTML"); } diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs index 918d6ee4b0c..71c244fdd4a 100644 --- a/compiler/rustc_mir/src/transform/coverage/mod.rs +++ b/compiler/rustc_mir/src/transform/coverage/mod.rs @@ -95,7 +95,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage { 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()); + trace!("InstrumentCoverage done for {:?}", mir_source.def_id()); } } @@ -116,25 +116,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { let def_id = mir_body.source.def_id(); let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id); - let mut body_span = hir_body.value.span; - - if tcx.is_closure(def_id) { - // If the MIR function is a closure, and if the closure body span - // starts from a macro, but it's content is not in that macro, try - // to find a non-macro callsite, and instrument the spans there - // instead. - loop { - let expn_data = body_span.ctxt().outer_expn_data(); - if expn_data.is_root() { - break; - } - if let ExpnKind::Macro { .. } = expn_data.kind { - body_span = expn_data.call_site; - } else { - break; - } - } - } + let body_span = get_body_span(tcx, hir_body, mir_body); let source_file = source_map.lookup_source_file(body_span.lo()); let fn_sig_span = match some_fn_sig.filter(|fn_sig| { @@ -144,6 +126,15 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()), None => body_span.shrink_to_lo(), }; + + debug!( + "instrumenting {}: {:?}, fn sig span: {:?}, body span: {:?}", + if tcx.is_closure(def_id) { "closure" } else { "function" }, + def_id, + fn_sig_span, + body_span + ); + let function_source_hash = hash_mir_source(tcx, hir_body); let basic_coverage_blocks = CoverageGraph::from_mir(mir_body); Self { @@ -160,19 +151,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { 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 fn_sig_span = self.fn_sig_span; let body_span = self.body_span; - debug!( - "instrumenting {:?}, fn sig span: {}, body span: {}", - def_id, - source_map.span_to_diagnostic_string(fn_sig_span), - source_map.span_to_diagnostic_string(body_span) - ); - let mut graphviz_data = debug::GraphvizData::new(); let mut debug_used_expressions = debug::UsedExpressions::new(); @@ -204,6 +187,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> { self.mir_body, &self.basic_coverage_blocks, self.pass_name, + body_span, &coverage_spans, ); } @@ -560,6 +544,35 @@ fn fn_sig_and_body<'tcx>( (hir::map::fn_sig(hir_node), tcx.hir().body(fn_body_id)) } +fn get_body_span<'tcx>( + tcx: TyCtxt<'tcx>, + hir_body: &rustc_hir::Body<'tcx>, + mir_body: &mut mir::Body<'tcx>, +) -> Span { + let mut body_span = hir_body.value.span; + let def_id = mir_body.source.def_id(); + + if tcx.is_closure(def_id) { + // If the MIR function is a closure, and if the closure body span + // starts from a macro, but it's content is not in that macro, try + // to find a non-macro callsite, and instrument the spans there + // instead. + loop { + let expn_data = body_span.ctxt().outer_expn_data(); + if expn_data.is_root() { + break; + } + if let ExpnKind::Macro { .. } = expn_data.kind { + body_span = expn_data.call_site; + } else { + break; + } + } + } + + body_span +} + 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() diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs index 2ba9d1bdc0c..760f16eae6b 100644 --- a/compiler/rustc_mir/src/transform/coverage/query.rs +++ b/compiler/rustc_mir/src/transform/coverage/query.rs @@ -120,8 +120,8 @@ impl CoverageVisitor { } } -fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo { - let mir_body = mir_body(tcx, def_id); +fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> CoverageInfo { + let mir_body = tcx.instance_mir(instance_def); let mut coverage_visitor = CoverageVisitor { // num_counters always has at least the `ZERO` counter. diff --git a/compiler/rustc_mir/src/transform/coverage/spans.rs b/compiler/rustc_mir/src/transform/coverage/spans.rs index 444b4e2ca19..f62171b3c53 100644 --- a/compiler/rustc_mir/src/transform/coverage/spans.rs +++ b/compiler/rustc_mir/src/transform/coverage/spans.rs @@ -530,17 +530,25 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { .iter() .enumerate() .filter_map(move |(index, statement)| { - filtered_statement_span(statement, self.body_span).map( - |(span, expn_span)| { - CoverageSpan::for_statement( - statement, span, expn_span, bcb, bb, index, - ) - }, - ) + filtered_statement_span(statement).map(|span| { + CoverageSpan::for_statement( + statement, + function_source_span(span, self.body_span), + span, + bcb, + bb, + index, + ) + }) }) - .chain(filtered_terminator_span(data.terminator(), self.body_span).map( - |(span, expn_span)| CoverageSpan::for_terminator(span, expn_span, bcb, bb), - )) + .chain(filtered_terminator_span(data.terminator()).map(|span| { + CoverageSpan::for_terminator( + function_source_span(span, self.body_span), + span, + bcb, + bb, + ) + })) }) .collect() } @@ -795,13 +803,9 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> { } } -/// See `function_source_span()` for a description of the two returned spans. -/// If the MIR `Statement` is not contributive to computing coverage spans, -/// returns `None`. -pub(super) fn filtered_statement_span( - statement: &'a Statement<'tcx>, - body_span: Span, -) -> Option<(Span, Span)> { +/// If the MIR `Statement` has a span contributive to computing coverage spans, +/// return it; otherwise return `None`. +pub(super) fn filtered_statement_span(statement: &'a Statement<'tcx>) -> Option<Span> { match statement.kind { // These statements have spans that are often outside the scope of the executed source code // for their parent `BasicBlock`. @@ -838,18 +842,14 @@ pub(super) fn filtered_statement_span( | StatementKind::LlvmInlineAsm(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) => { - Some(function_source_span(statement.source_info.span, body_span)) + Some(statement.source_info.span) } } } -/// See `function_source_span()` for a description of the two returned spans. -/// If the MIR `Terminator` is not contributive to computing coverage spans, -/// returns `None`. -pub(super) fn filtered_terminator_span( - terminator: &'a Terminator<'tcx>, - body_span: Span, -) -> Option<(Span, Span)> { +/// If the MIR `Terminator` has a span contributive to computing coverage spans, +/// return it; otherwise return `None`. +pub(super) fn filtered_terminator_span(terminator: &'a Terminator<'tcx>) -> Option<Span> { match terminator.kind { // These terminators have spans that don't positively contribute to computing a reasonable // span of actually executed source code. (For example, SwitchInt terminators extracted from @@ -873,7 +873,7 @@ pub(super) fn filtered_terminator_span( span = span.with_lo(constant.span.lo()); } } - Some(function_source_span(span, body_span)) + Some(span) } // Retain spans from all other terminators @@ -884,28 +884,20 @@ pub(super) fn filtered_terminator_span( | TerminatorKind::GeneratorDrop | TerminatorKind::FalseUnwind { .. } | TerminatorKind::InlineAsm { .. } => { - Some(function_source_span(terminator.source_info.span, body_span)) + Some(terminator.source_info.span) } } } -/// Returns two spans from the given span (the span associated with a -/// `Statement` or `Terminator`): -/// -/// 1. An extrapolated span (pre-expansion[^1]) corresponding to a range within -/// the function's body source. This span is guaranteed to be contained -/// within, or equal to, the `body_span`. If the extrapolated span is not -/// contained within the `body_span`, the `body_span` is returned. -/// 2. The actual `span` value from the `Statement`, before expansion. -/// -/// Only the first span is used when computing coverage code regions. The second -/// span is useful if additional expansion data is needed (such as to look up -/// the macro name for a composed span within that macro).) +/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range +/// within the function's body source. This span is guaranteed to be contained +/// within, or equal to, the `body_span`. If the extrapolated span is not +/// contained within the `body_span`, the `body_span` is returned. /// -/// [^1]Expansions result from Rust syntax including macros, syntactic -/// sugar, etc.). +/// [^1]Expansions result from Rust syntax including macros, syntactic sugar, +/// etc.). #[inline] -fn function_source_span(span: Span, body_span: Span) -> (Span, Span) { +pub(super) fn function_source_span(span: Span, body_span: Span) -> Span { let original_span = original_sp(span, body_span).with_ctxt(body_span.ctxt()); - (if body_span.contains(original_span) { original_span } else { body_span }, span) + if body_span.contains(original_span) { original_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 9b84173c8a2..b04c2d542d4 100644 --- a/compiler/rustc_mir/src/transform/coverage/tests.rs +++ b/compiler/rustc_mir/src/transform/coverage/tests.rs @@ -683,12 +683,10 @@ fn test_make_bcb_counters() { let mut basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body); let mut coverage_spans = Vec::new(); for (bcb, data) in basic_coverage_blocks.iter_enumerated() { - if let Some((span, expn_span)) = - spans::filtered_terminator_span(data.terminator(&mir_body), body_span) - { + if let Some(span) = spans::filtered_terminator_span(data.terminator(&mir_body)) { coverage_spans.push(spans::CoverageSpan::for_terminator( + spans::function_source_span(span, body_span), span, - expn_span, bcb, data.last_bb(), )); diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f7ea9faec47..7934d4ba849 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -170,10 +170,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { } fn is_switch<'tcx>(terminator: &Terminator<'tcx>) -> bool { - match terminator.kind { - TerminatorKind::SwitchInt { .. } => true, - _ => false, - } + matches!(terminator.kind, TerminatorKind::SwitchInt { .. }) } struct Helper<'a, 'tcx> { diff --git a/compiler/rustc_mir/src/transform/simplify_try.rs b/compiler/rustc_mir/src/transform/simplify_try.rs index b42543c04eb..89fddc95c98 100644 --- a/compiler/rustc_mir/src/transform/simplify_try.rs +++ b/compiler/rustc_mir/src/transform/simplify_try.rs @@ -628,10 +628,7 @@ impl<'a, 'tcx> SimplifyBranchSameOptimizationFinder<'a, 'tcx> { // But `asm!(...)` could abort the program, // so we cannot assume that the `unreachable` terminator itself is reachable. // FIXME(Centril): use a normalization pass instead of a check. - || bb.statements.iter().any(|stmt| match stmt.kind { - StatementKind::LlvmInlineAsm(..) => true, - _ => false, - }) + || bb.statements.iter().any(|stmt| matches!(stmt.kind, StatementKind::LlvmInlineAsm(..))) }) .peekable(); diff --git a/compiler/rustc_mir/src/util/spanview.rs b/compiler/rustc_mir/src/util/spanview.rs index 2103f2f0934..42683dac426 100644 --- a/compiler/rustc_mir/src/util/spanview.rs +++ b/compiler/rustc_mir/src/util/spanview.rs @@ -131,7 +131,7 @@ where } } } - write_document(tcx, def_id, span_viewables, title, w)?; + write_document(tcx, fn_span(tcx, def_id), span_viewables, title, w)?; Ok(()) } @@ -139,7 +139,7 @@ where /// list `SpanViewable`s. pub fn write_document<'tcx, W>( tcx: TyCtxt<'tcx>, - def_id: DefId, + spanview_span: Span, mut span_viewables: Vec<SpanViewable>, title: &str, w: &mut W, @@ -147,16 +147,16 @@ pub fn write_document<'tcx, W>( where W: Write, { - let fn_span = fn_span(tcx, def_id); - let mut from_pos = fn_span.lo(); - let end_pos = fn_span.hi(); + let mut from_pos = spanview_span.lo(); + let end_pos = spanview_span.hi(); let source_map = tcx.sess.source_map(); let start = source_map.lookup_char_pos(from_pos); let indent_to_initial_start_col = " ".repeat(start.col.to_usize()); debug!( - "fn_span source is:\n{}{}", + "spanview_span={:?}; source is:\n{}{}", + spanview_span, indent_to_initial_start_col, - source_map.span_to_snippet(fn_span).expect("function should have printable source") + source_map.span_to_snippet(spanview_span).expect("function should have printable source") ); writeln!(w, "{}", HEADER)?; writeln!(w, "<title>{}</title>", title)?; |
