diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-12-06 16:54:55 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-06 16:54:55 +0100 |
| commit | c699b0530604105d0ceaa391453b89765ddfb75d (patch) | |
| tree | 4e776903974848b06ab2c92b093abb1ed1475dbb | |
| parent | 967085ecdf589ec92f528c71cfb9ace723cbabb1 (diff) | |
| parent | d595884302240f07576239288c771b0e9717fc19 (diff) | |
| download | rust-c699b0530604105d0ceaa391453b89765ddfb75d.tar.gz rust-c699b0530604105d0ceaa391453b89765ddfb75d.zip | |
Rollup merge of #105286 - willcrichton:maximal-hir-to-mir-coverage, r=cjgillot
Add -Z maximal-hir-to-mir-coverage flag This PR adds a new unstable flag `-Z maximal-hir-to-mir-coverage` that changes the behavior of `maybe_lint_level_root_bounded`, pursuant to [a discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Mapping.20MIR.20to.20HIR). When enabled, this function will not search upwards for a lint root, but rather immediately return the provided HIR node ID. This change increases the granularity of the mapping between MIR locations and HIR nodes inside the `SourceScopeLocalData` data structures. This increase in granularity is useful for rustc consumers like [Flowistry](https://github.com/willcrichton/flowistry) that rely on getting source-mapping information about the MIR CFG that is as precise as possible. A test `maximal_mir_to_hir_coverage.rs` has been added to verify that this flag does not break anything. r? `@cjgillot` cc `@gavinleroy`
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/mod.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/scope.rs | 56 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 3 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/z-help.stdout | 1 | ||||
| -rw-r--r-- | src/test/ui/maximal_mir_to_hir_coverage.rs | 10 |
6 files changed, 59 insertions, 32 deletions
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a6205f4d3a5..2b8f6557c82 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -747,6 +747,7 @@ fn test_unstable_options_tracking_hash() { tracked!(link_only, true); tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); + tracked!(maximal_hir_to_mir_coverage, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index b456e2aa37a..007f3b55ec8 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -948,20 +948,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { original_source_scope: SourceScope, pattern_span: Span, ) { - let tcx = self.tcx; - let current_root = tcx.maybe_lint_level_root_bounded(arg_hir_id, self.hir_id); - let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scopes[original_source_scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root, - self.hir_id, - ); - if current_root != parent_root { - self.source_scope = - self.new_source_scope(pattern_span, LintLevel::Explicit(current_root), None); - } + let parent_id = self.source_scopes[original_source_scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; + self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id); } fn get_unit_temp(&mut self) -> Place<'tcx> { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 5ddae5f5300..33f49ffdaf6 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -85,6 +85,7 @@ use std::mem; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG}; use rustc_data_structures::fx::FxHashMap; +use rustc_hir::HirId; use rustc_index::vec::IndexVec; use rustc_middle::middle::region; use rustc_middle::mir::*; @@ -567,25 +568,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>, { let source_scope = self.source_scope; - let tcx = self.tcx; if let LintLevel::Explicit(current_hir_id) = lint_level { - // Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound - // to avoid adding Hir dependencies on our parents. - // We estimate the true lint roots here to avoid creating a lot of source scopes. - - let parent_root = tcx.maybe_lint_level_root_bounded( - self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root, - self.hir_id, - ); - let current_root = tcx.maybe_lint_level_root_bounded(current_hir_id, self.hir_id); - - if parent_root != current_root { - self.source_scope = self.new_source_scope( - region_scope.1.span, - LintLevel::Explicit(current_root), - None, - ); - } + let parent_id = + self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root; + self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id); } self.push_scope(region_scope); let mut block; @@ -758,6 +744,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { )) } + /// Possibly creates a new source scope if `current_root` and `parent_root` + /// are different, or if -Zmaximal-hir-to-mir-coverage is enabled. + pub(crate) fn maybe_new_source_scope( + &mut self, + span: Span, + safety: Option<Safety>, + current_id: HirId, + parent_id: HirId, + ) { + let (current_root, parent_root) = + if self.tcx.sess.opts.unstable_opts.maximal_hir_to_mir_coverage { + // Some consumers of rustc need to map MIR locations back to HIR nodes. Currently the + // the only part of rustc that tracks MIR -> HIR is the `SourceScopeLocalData::lint_root` + // field that tracks lint levels for MIR locations. Normally the number of source scopes + // is limited to the set of nodes with lint annotations. The -Zmaximal-hir-to-mir-coverage + // flag changes this behavior to maximize the number of source scopes, increasing the + // granularity of the MIR->HIR mapping. + (current_id, parent_id) + } else { + // Use `maybe_lint_level_root_bounded` with `self.hir_id` as a bound + // to avoid adding Hir dependencies on our parents. + // We estimate the true lint roots here to avoid creating a lot of source scopes. + ( + self.tcx.maybe_lint_level_root_bounded(current_id, self.hir_id), + self.tcx.maybe_lint_level_root_bounded(parent_id, self.hir_id), + ) + }; + + if current_root != parent_root { + let lint_level = LintLevel::Explicit(current_root); + self.source_scope = self.new_source_scope(span, lint_level, safety); + } + } + /// Creates a new source scope, nested in the current one. pub(crate) fn new_source_scope( &mut self, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 01a9361e786..8e9198b79df 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1382,6 +1382,9 @@ options! { "list the symbols defined by a library crate (default: no)"), macro_backtrace: bool = (false, parse_bool, [UNTRACKED], "show macro backtraces (default: no)"), + maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED], + "save as much information as possible about the correspondence between MIR and HIR \ + as source scopes (default: no)"), merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED], "control the operation of the MergeFunctions LLVM pass, taking \ the same values as the target option of the same name"), diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 55154803098..94cf7b94241 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -77,6 +77,7 @@ -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) -Z ls=val -- list the symbols defined by a library crate (default: no) -Z macro-backtrace=val -- show macro backtraces (default: no) + -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name -Z meta-stats=val -- gather metadata statistics (default: no) -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) diff --git a/src/test/ui/maximal_mir_to_hir_coverage.rs b/src/test/ui/maximal_mir_to_hir_coverage.rs new file mode 100644 index 00000000000..5ca54633f21 --- /dev/null +++ b/src/test/ui/maximal_mir_to_hir_coverage.rs @@ -0,0 +1,10 @@ +// compile-flags: -Zmaximal-hir-to-mir-coverage +// run-pass + +// Just making sure this flag is accepted and doesn't crash the compiler + +fn main() { + let x = 1; + let y = x + 1; + println!("{y}"); +} |
