summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_incremental/src/assert_module_sources.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_incremental/src/assert_module_sources.rs')
-rw-r--r--compiler/rustc_incremental/src/assert_module_sources.rs171
1 files changed, 0 insertions, 171 deletions
diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs
deleted file mode 100644
index 8e22ab408..000000000
--- a/compiler/rustc_incremental/src/assert_module_sources.rs
+++ /dev/null
@@ -1,171 +0,0 @@
-//! This pass is only used for UNIT TESTS related to incremental
-//! compilation. It tests whether a particular `.o` file will be re-used
-//! from a previous compilation or whether it must be regenerated.
-//!
-//! The user adds annotations to the crate of the following form:
-//!
-//! ```
-//! # #![feature(rustc_attrs)]
-//! # #![allow(internal_features)]
-//! #![rustc_partition_reused(module="spike", cfg="rpass2")]
-//! #![rustc_partition_codegened(module="spike-x", cfg="rpass2")]
-//! ```
-//!
-//! The first indicates (in the cfg `rpass2`) that `spike.o` will be
-//! reused, the second that `spike-x.o` will be recreated. If these
-//! annotations are inaccurate, errors are reported.
-//!
-//! The reason that we use `cfg=...` and not `#[cfg_attr]` is so that
-//! the HIR doesn't change as a result of the annotations, which might
-//! perturb the reuse results.
-//!
-//! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]`
-//! allows for doing a more fine-grained check to see if pre- or post-lto data
-//! was re-used.
-
-use crate::errors;
-use rustc_ast as ast;
-use rustc_data_structures::unord::UnordSet;
-use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_middle::mir::mono::CodegenUnitNameBuilder;
-use rustc_middle::ty::TyCtxt;
-use rustc_session::cgu_reuse_tracker::*;
-use rustc_span::symbol::{sym, Symbol};
-use thin_vec::ThinVec;
-
-#[allow(missing_docs)]
-pub fn assert_module_sources(tcx: TyCtxt<'_>) {
- tcx.dep_graph.with_ignore(|| {
- if tcx.sess.opts.incremental.is_none() {
- return;
- }
-
- let available_cgus =
- tcx.collect_and_partition_mono_items(()).1.iter().map(|cgu| cgu.name()).collect();
-
- let ams = AssertModuleSource { tcx, available_cgus };
-
- for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) {
- ams.check_attr(attr);
- }
- })
-}
-
-struct AssertModuleSource<'tcx> {
- tcx: TyCtxt<'tcx>,
- available_cgus: UnordSet<Symbol>,
-}
-
-impl<'tcx> AssertModuleSource<'tcx> {
- fn check_attr(&self, attr: &ast::Attribute) {
- let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) {
- (CguReuse::PreLto, ComparisonKind::AtLeast)
- } else if attr.has_name(sym::rustc_partition_codegened) {
- (CguReuse::No, ComparisonKind::Exact)
- } else if attr.has_name(sym::rustc_expected_cgu_reuse) {
- match self.field(attr, sym::kind) {
- sym::no => (CguReuse::No, ComparisonKind::Exact),
- sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact),
- sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
- sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
- other => {
- self.tcx
- .sess
- .emit_fatal(errors::UnknownReuseKind { span: attr.span, kind: other });
- }
- }
- } else {
- return;
- };
-
- if !self.tcx.sess.opts.unstable_opts.query_dep_graph {
- self.tcx.sess.emit_fatal(errors::MissingQueryDepGraph { span: attr.span });
- }
-
- if !self.check_config(attr) {
- debug!("check_attr: config does not match, ignoring attr");
- return;
- }
-
- let user_path = self.field(attr, sym::module).to_string();
- let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string();
-
- if !user_path.starts_with(&crate_name) {
- self.tcx.sess.emit_fatal(errors::MalformedCguName {
- span: attr.span,
- user_path,
- crate_name,
- });
- }
-
- // Split of the "special suffix" if there is one.
- let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') {
- (&user_path[..index], Some(&user_path[index + 1..]))
- } else {
- (&user_path[..], None)
- };
-
- let mut iter = user_path.split('-');
-
- // Remove the crate name
- assert_eq!(iter.next().unwrap(), crate_name);
-
- let cgu_path_components = iter.collect::<Vec<_>>();
-
- let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx);
- let cgu_name =
- cgu_name_builder.build_cgu_name(LOCAL_CRATE, cgu_path_components, cgu_special_suffix);
-
- debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name);
-
- if !self.available_cgus.contains(&cgu_name) {
- let cgu_names: Vec<&str> =
- self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord();
- self.tcx.sess.emit_err(errors::NoModuleNamed {
- span: attr.span,
- user_path,
- cgu_name,
- cgu_names: cgu_names.join(", "),
- });
- }
-
- self.tcx.sess.cgu_reuse_tracker.set_expectation(
- cgu_name,
- &user_path,
- attr.span,
- expected_reuse,
- comp_kind,
- );
- }
-
- fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
- for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
- if item.has_name(name) {
- if let Some(value) = item.value_str() {
- return value;
- } else {
- self.tcx.sess.emit_fatal(errors::FieldAssociatedValueExpected {
- span: item.span(),
- name,
- });
- }
- }
- }
-
- self.tcx.sess.emit_fatal(errors::NoField { span: attr.span, name });
- }
-
- /// Scan for a `cfg="foo"` attribute and check whether we have a
- /// cfg flag called `foo`.
- fn check_config(&self, attr: &ast::Attribute) -> bool {
- let config = &self.tcx.sess.parse_sess.config;
- let value = self.field(attr, sym::cfg);
- debug!("check_config(config={:?}, value={:?})", config, value);
- if config.iter().any(|&(name, _)| name == value) {
- debug!("check_config: matched");
- return true;
- }
- debug!("check_config: no match found");
- false
- }
-}