incremental: migrate diagnostics
Migrate the `rustc_incremental` crate's diagnostics to translatable diagnostic structs. Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
parent
2575b1abc9
commit
2ff46641a9
13 changed files with 617 additions and 253 deletions
118
compiler/rustc_error_messages/locales/en-US/incremental.ftl
Normal file
118
compiler/rustc_error_messages/locales/en-US/incremental.ftl
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
|
||||||
|
|
||||||
|
incremental_missing_depnode = missing `DepNode` variant
|
||||||
|
|
||||||
|
incremental_missing_if_this_changed = no `#[rustc_if_this_changed]` annotation detected
|
||||||
|
|
||||||
|
incremental_no_path = no path from `{$source}` to `{$target}`
|
||||||
|
|
||||||
|
incremental_ok = OK
|
||||||
|
|
||||||
|
incremental_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
|
||||||
|
|
||||||
|
incremental_missing_query_depgraph =
|
||||||
|
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
|
||||||
|
|
||||||
|
incremental_malformed_cgu_name =
|
||||||
|
found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case).
|
||||||
|
|
||||||
|
incremental_no_module_named =
|
||||||
|
no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}
|
||||||
|
|
||||||
|
incremental_field_associated_value_expected = associated value expected for `{$name}`
|
||||||
|
|
||||||
|
incremental_no_field = no field `{$name}`
|
||||||
|
|
||||||
|
incremental_assertion_auto =
|
||||||
|
`except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\"
|
||||||
|
|
||||||
|
incremental_undefined_clean_dirty_assertions_item =
|
||||||
|
clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}
|
||||||
|
|
||||||
|
incremental_undefined_clean_dirty_assertions =
|
||||||
|
clean/dirty auto-assertions not yet defined for {$kind}
|
||||||
|
|
||||||
|
incremental_repeated_depnode_label = dep-node label `{$label}` is repeated
|
||||||
|
|
||||||
|
incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized
|
||||||
|
|
||||||
|
incremental_not_dirty = `{$dep_node_str}` should be dirty but is not
|
||||||
|
|
||||||
|
incremental_not_clean = `{$dep_node_str}` should be clean but is not
|
||||||
|
|
||||||
|
incremental_not_loaded = `{$dep_node_str}` should have been loaded from disk but it was not
|
||||||
|
|
||||||
|
incremental_unknown_item = unknown item `{$name}`
|
||||||
|
|
||||||
|
incremental_no_cfg = no cfg attribute
|
||||||
|
|
||||||
|
incremental_associated_value_expected_for = associated value expected for `{$ident}`
|
||||||
|
|
||||||
|
incremental_associated_value_expected = expected an associated value
|
||||||
|
|
||||||
|
incremental_unchecked_clean = found unchecked `#[rustc_clean]` attribute
|
||||||
|
|
||||||
|
incremental_delete_old = unable to delete old {$name} at `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_create_new = failed to create {$name} at `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_write_new = failed to write {$name} to `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_canonicalize_path = incremental compilation: error canonicalizing path `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_create_incr_comp_dir =
|
||||||
|
could not create incremental compilation {$tag} directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_create_lock =
|
||||||
|
incremental compilation: could not create session directory lock file: {$lock_err}
|
||||||
|
incremental_lock_unsupported =
|
||||||
|
the filesystem for the incremental path at {$session_dir} does not appear to support locking, consider changing the incremental path to a filesystem that supports locking or disable incremental compilation
|
||||||
|
incremental_cargo_help_1 =
|
||||||
|
incremental compilation can be disabled by setting the environment variable CARGO_INCREMENTAL=0 (see https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)
|
||||||
|
incremental_cargo_help_2 =
|
||||||
|
the entire build directory can be changed to a different filesystem by setting the environment variable CARGO_TARGET_DIR to a different path (see https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir)
|
||||||
|
|
||||||
|
incremental_delete_lock =
|
||||||
|
error deleting lock file for incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_hard_link_failed =
|
||||||
|
hard linking files in the incremental compilation cache failed. copying files instead. consider moving the cache directory to a file system which supports hard linking in session dir `{$path}`
|
||||||
|
|
||||||
|
incremental_delete_partial = failed to delete partly initialized session dir `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_delete_full = error deleting incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_finalize = error finalizing incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_invalid_gc_failed =
|
||||||
|
failed to garbage collect invalid incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_finalized_gc_failed =
|
||||||
|
failed to garbage collect finalized incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_session_gc_failed =
|
||||||
|
failed to garbage collect incremental compilation session directory `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_assert_not_loaded =
|
||||||
|
we asserted that the incremental cache should not be loaded, but it was loaded
|
||||||
|
|
||||||
|
incremental_assert_loaded =
|
||||||
|
we asserted that an existing incremental cache directory should be successfully loaded, but it was not
|
||||||
|
|
||||||
|
incremental_delete_incompatible =
|
||||||
|
failed to delete invalidated or incompatible incremental compilation session directory contents `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_load_dep_graph = could not load dep-graph from `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_decode_incr_cache = could not decode incremental cache: {$err}
|
||||||
|
|
||||||
|
incremental_write_dep_graph = failed to write dependency graph to `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_move_dep_graph = failed to move dependency graph from `{$from}` to `{$to}`: {$err}
|
||||||
|
|
||||||
|
incremental_create_dep_graph = failed to create dependency graph at `{$path}`: {$err}
|
||||||
|
|
||||||
|
incremental_copy_workproduct_to_cache =
|
||||||
|
error copying object file `{$from}` to incremental directory as `{$to}`: {$err}
|
||||||
|
|
||||||
|
incremental_delete_workproduct = file-system error deleting outdated file `{$path}`: {$err}
|
|
@ -52,6 +52,7 @@ fluent_messages! {
|
||||||
expand => "../locales/en-US/expand.ftl",
|
expand => "../locales/en-US/expand.ftl",
|
||||||
hir_analysis => "../locales/en-US/hir_analysis.ftl",
|
hir_analysis => "../locales/en-US/hir_analysis.ftl",
|
||||||
hir_typeck => "../locales/en-US/hir_typeck.ftl",
|
hir_typeck => "../locales/en-US/hir_typeck.ftl",
|
||||||
|
incremental => "../locales/en-US/incremental.ftl",
|
||||||
infer => "../locales/en-US/infer.ftl",
|
infer => "../locales/en-US/infer.ftl",
|
||||||
interface => "../locales/en-US/interface.ftl",
|
interface => "../locales/en-US/interface.ftl",
|
||||||
lint => "../locales/en-US/lint.ftl",
|
lint => "../locales/en-US/lint.ftl",
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
//! fn baz() { foo(); }
|
//! fn baz() { foo(); }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
|
use rustc_data_structures::graph::implementation::{Direction, NodeIndex, INCOMING, OUTGOING};
|
||||||
|
@ -133,12 +134,10 @@ impl<'tcx> IfThisChanged<'tcx> {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
|
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(()) => {
|
Err(()) => self.tcx.sess.emit_fatal(errors::UnrecognizedDepNode {
|
||||||
self.tcx.sess.span_fatal(
|
span: attr.span,
|
||||||
attr.span,
|
name: n,
|
||||||
&format!("unrecognized DepNode variant {:?}", n),
|
}),
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -149,16 +148,14 @@ impl<'tcx> IfThisChanged<'tcx> {
|
||||||
Some(n) => {
|
Some(n) => {
|
||||||
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
|
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
Err(()) => {
|
Err(()) => self.tcx.sess.emit_fatal(errors::UnrecognizedDepNode {
|
||||||
self.tcx.sess.span_fatal(
|
span: attr.span,
|
||||||
attr.span,
|
name: n,
|
||||||
&format!("unrecognized DepNode variant {:?}", n),
|
}),
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.tcx.sess.span_fatal(attr.span, "missing DepNode variant");
|
self.tcx.sess.emit_fatal(errors::MissingDepNode { span: attr.span });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.then_this_would_need.push((
|
self.then_this_would_need.push((
|
||||||
|
@ -204,7 +201,7 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
|
||||||
// Return early here so as not to construct the query, which is not cheap.
|
// Return early here so as not to construct the query, which is not cheap.
|
||||||
if if_this_changed.is_empty() {
|
if if_this_changed.is_empty() {
|
||||||
for &(target_span, _, _, _) in then_this_would_need {
|
for &(target_span, _, _, _) in then_this_would_need {
|
||||||
tcx.sess.span_err(target_span, "no `#[rustc_if_this_changed]` annotation detected");
|
tcx.sess.emit_err(errors::MissingIfThisChanged { span: target_span });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -213,16 +210,13 @@ fn check_paths<'tcx>(tcx: TyCtxt<'tcx>, if_this_changed: &Sources, then_this_wou
|
||||||
let dependents = query.transitive_predecessors(source_dep_node);
|
let dependents = query.transitive_predecessors(source_dep_node);
|
||||||
for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need {
|
for &(target_span, ref target_pass, _, ref target_dep_node) in then_this_would_need {
|
||||||
if !dependents.contains(&target_dep_node) {
|
if !dependents.contains(&target_dep_node) {
|
||||||
tcx.sess.span_err(
|
tcx.sess.emit_err(errors::NoPath {
|
||||||
target_span,
|
span: target_span,
|
||||||
&format!(
|
source: tcx.def_path_str(source_def_id),
|
||||||
"no path from `{}` to `{}`",
|
target: *target_pass,
|
||||||
tcx.def_path_str(source_def_id),
|
});
|
||||||
target_pass
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
tcx.sess.span_err(target_span, "OK");
|
tcx.sess.emit_err(errors::Ok { span: target_span });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
//! allows for doing a more fine-grained check to see if pre- or post-lto data
|
//! allows for doing a more fine-grained check to see if pre- or post-lto data
|
||||||
//! was re-used.
|
//! was re-used.
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir::def_id::LOCAL_CRATE;
|
use rustc_hir::def_id::LOCAL_CRATE;
|
||||||
|
@ -66,10 +67,9 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
||||||
sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
|
sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact),
|
||||||
sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
|
sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast),
|
||||||
other => {
|
other => {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx
|
||||||
attr.span,
|
.sess
|
||||||
&format!("unknown cgu-reuse-kind `{}` specified", other),
|
.emit_fatal(errors::UnknownReuseKind { span: attr.span, kind: other });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -77,10 +77,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.tcx.sess.opts.unstable_opts.query_dep_graph {
|
if !self.tcx.sess.opts.unstable_opts.query_dep_graph {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx.sess.emit_fatal(errors::MissingQueryDepGraph { span: attr.span });
|
||||||
attr.span,
|
|
||||||
"found CGU-reuse attribute but `-Zquery-dep-graph` was not specified",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.check_config(attr) {
|
if !self.check_config(attr) {
|
||||||
|
@ -92,13 +89,11 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
||||||
let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string();
|
let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string();
|
||||||
|
|
||||||
if !user_path.starts_with(&crate_name) {
|
if !user_path.starts_with(&crate_name) {
|
||||||
let msg = format!(
|
self.tcx.sess.emit_fatal(errors::MalformedCguName {
|
||||||
"Found malformed codegen unit name `{}`. \
|
span: attr.span,
|
||||||
Codegen units names must always start with the name of the \
|
user_path,
|
||||||
crate (`{}` in this case).",
|
crate_name,
|
||||||
user_path, crate_name
|
});
|
||||||
);
|
|
||||||
self.tcx.sess.span_fatal(attr.span, &msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split of the "special suffix" if there is one.
|
// Split of the "special suffix" if there is one.
|
||||||
|
@ -125,15 +120,12 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
||||||
let mut cgu_names: Vec<&str> =
|
let mut cgu_names: Vec<&str> =
|
||||||
self.available_cgus.iter().map(|cgu| cgu.as_str()).collect();
|
self.available_cgus.iter().map(|cgu| cgu.as_str()).collect();
|
||||||
cgu_names.sort();
|
cgu_names.sort();
|
||||||
self.tcx.sess.span_err(
|
self.tcx.sess.emit_err(errors::NoModuleNamed {
|
||||||
attr.span,
|
span: attr.span,
|
||||||
&format!(
|
user_path,
|
||||||
"no module named `{}` (mangled: {}). Available modules: {}",
|
cgu_name,
|
||||||
user_path,
|
cgu_names: cgu_names.join(", "),
|
||||||
cgu_name,
|
});
|
||||||
cgu_names.join(", ")
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tcx.sess.cgu_reuse_tracker.set_expectation(
|
self.tcx.sess.cgu_reuse_tracker.set_expectation(
|
||||||
|
@ -151,15 +143,15 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
||||||
if let Some(value) = item.value_str() {
|
if let Some(value) = item.value_str() {
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx.sess.emit_fatal(errors::FieldAssociatedValueExpected {
|
||||||
item.span(),
|
span: item.span(),
|
||||||
&format!("associated value expected for `{}`", name),
|
name,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tcx.sess.span_fatal(attr.span, &format!("no field `{}`", name));
|
self.tcx.sess.emit_fatal(errors::NoField { span: attr.span, name });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan for a `cfg="foo"` attribute and check whether we have a
|
/// Scan for a `cfg="foo"` attribute and check whether we have a
|
||||||
|
|
364
compiler/rustc_incremental/src/errors.rs
Normal file
364
compiler/rustc_incremental/src/errors.rs
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
use rustc_macros::Diagnostic;
|
||||||
|
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_unrecognized_depnode)]
|
||||||
|
pub struct UnrecognizedDepNode {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_missing_depnode)]
|
||||||
|
pub struct MissingDepNode {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_missing_if_this_changed)]
|
||||||
|
pub struct MissingIfThisChanged {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_ok)]
|
||||||
|
pub struct Ok {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_no_path)]
|
||||||
|
pub struct NoPath {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub target: Symbol,
|
||||||
|
pub source: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_unknown_reuse_kind)]
|
||||||
|
pub struct UnknownReuseKind {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub kind: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_missing_query_depgraph)]
|
||||||
|
pub struct MissingQueryDepGraph {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_malformed_cgu_name)]
|
||||||
|
pub struct MalformedCguName {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub user_path: String,
|
||||||
|
pub crate_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_no_module_named)]
|
||||||
|
pub struct NoModuleNamed<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub user_path: &'a str,
|
||||||
|
pub cgu_name: Symbol,
|
||||||
|
pub cgu_names: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_field_associated_value_expected)]
|
||||||
|
pub struct FieldAssociatedValueExpected {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_no_field)]
|
||||||
|
pub struct NoField {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_assertion_auto)]
|
||||||
|
pub struct AssertionAuto<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: &'a str,
|
||||||
|
pub e: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_undefined_clean_dirty_assertions_item)]
|
||||||
|
pub struct UndefinedCleanDirtyItem {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub kind: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_undefined_clean_dirty_assertions)]
|
||||||
|
pub struct UndefinedCleanDirty {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub kind: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_repeated_depnode_label)]
|
||||||
|
pub struct RepeatedDepNodeLabel<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub label: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_unrecognized_depnode_label)]
|
||||||
|
pub struct UnrecognizedDepNodeLabel<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub label: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_not_dirty)]
|
||||||
|
pub struct NotDirty<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub dep_node_str: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_not_clean)]
|
||||||
|
pub struct NotClean<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub dep_node_str: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_not_loaded)]
|
||||||
|
pub struct NotLoaded<'a> {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub dep_node_str: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_unknown_item)]
|
||||||
|
pub struct UnknownItem {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub name: Symbol,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_no_cfg)]
|
||||||
|
pub struct NoCfg {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_associated_value_expected_for)]
|
||||||
|
pub struct AssociatedValueExpectedFor {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub ident: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_associated_value_expected)]
|
||||||
|
pub struct AssociatedValueExpected {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_unchecked_clean)]
|
||||||
|
pub struct UncheckedClean {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_old)]
|
||||||
|
pub struct DeleteOld<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_create_new)]
|
||||||
|
pub struct CreateNew<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_write_new)]
|
||||||
|
pub struct WriteNew<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_canonicalize_path)]
|
||||||
|
pub struct CanonicalizePath {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_create_incr_comp_dir)]
|
||||||
|
pub struct CreateIncrCompDir<'a> {
|
||||||
|
pub tag: &'a str,
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_create_lock)]
|
||||||
|
pub struct CreateLock<'a> {
|
||||||
|
pub lock_err: std::io::Error,
|
||||||
|
pub session_dir: &'a Path,
|
||||||
|
#[note(incremental_lock_unsupported)]
|
||||||
|
pub is_unsupported_lock: Option<()>,
|
||||||
|
#[help(incremental_cargo_help_1)]
|
||||||
|
#[help(incremental_cargo_help_2)]
|
||||||
|
pub is_cargo: Option<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_lock)]
|
||||||
|
pub struct DeleteLock<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_hard_link_failed)]
|
||||||
|
pub struct HardLinkFailed<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_partial)]
|
||||||
|
pub struct DeletePartial<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_full)]
|
||||||
|
pub struct DeleteFull<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_finalize)]
|
||||||
|
pub struct Finalize<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_invalid_gc_failed)]
|
||||||
|
pub struct InvalidGcFailed<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_finalized_gc_failed)]
|
||||||
|
pub struct FinalizedGcFailed<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_session_gc_failed)]
|
||||||
|
pub struct SessionGcFailed<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_assert_not_loaded)]
|
||||||
|
pub struct AssertNotLoaded;
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_assert_loaded)]
|
||||||
|
pub struct AssertLoaded;
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_incompatible)]
|
||||||
|
pub struct DeleteIncompatible {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_load_dep_graph)]
|
||||||
|
pub struct LoadDepGraph {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_decode_incr_cache)]
|
||||||
|
pub struct DecodeIncrCache {
|
||||||
|
pub err: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_write_dep_graph)]
|
||||||
|
pub struct WriteDepGraph<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_move_dep_graph)]
|
||||||
|
pub struct MoveDepGraph<'a> {
|
||||||
|
pub from: &'a Path,
|
||||||
|
pub to: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_create_dep_graph)]
|
||||||
|
pub struct CreateDepGraph<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_copy_workproduct_to_cache)]
|
||||||
|
pub struct CopyWorkProductToCache<'a> {
|
||||||
|
pub from: &'a Path,
|
||||||
|
pub to: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(incremental_delete_workproduct)]
|
||||||
|
pub struct DeleteWorkProduct<'a> {
|
||||||
|
pub path: &'a Path,
|
||||||
|
pub err: std::io::Error,
|
||||||
|
}
|
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_middle;
|
extern crate rustc_middle;
|
||||||
|
@ -12,6 +15,7 @@ extern crate tracing;
|
||||||
|
|
||||||
mod assert_dep_graph;
|
mod assert_dep_graph;
|
||||||
pub mod assert_module_sources;
|
pub mod assert_module_sources;
|
||||||
|
mod errors;
|
||||||
mod persist;
|
mod persist;
|
||||||
|
|
||||||
use assert_dep_graph::assert_dep_graph;
|
use assert_dep_graph::assert_dep_graph;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
//! Errors are reported if we are in the suitable configuration but
|
//! Errors are reported if we are in the suitable configuration but
|
||||||
//! the required condition is not met.
|
//! the required condition is not met.
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use rustc_ast::{self as ast, Attribute, NestedMetaItem};
|
use rustc_ast::{self as ast, Attribute, NestedMetaItem};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
|
@ -196,11 +197,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
let loaded_from_disk = self.loaded_from_disk(attr);
|
let loaded_from_disk = self.loaded_from_disk(attr);
|
||||||
for e in except.iter() {
|
for e in except.iter() {
|
||||||
if !auto.remove(e) {
|
if !auto.remove(e) {
|
||||||
let msg = format!(
|
self.tcx.sess.emit_fatal(errors::AssertionAuto { span: attr.span, name, e });
|
||||||
"`except` specified DepNodes that can not be affected for \"{}\": \"{}\"",
|
|
||||||
name, e
|
|
||||||
);
|
|
||||||
self.tcx.sess.span_fatal(attr.span, &msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assertion { clean: auto, dirty: except, loaded_from_disk }
|
Assertion { clean: auto, dirty: except, loaded_from_disk }
|
||||||
|
@ -282,14 +279,10 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
// An implementation, eg `impl<A> Trait for Foo { .. }`
|
// An implementation, eg `impl<A> Trait for Foo { .. }`
|
||||||
HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
|
HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
|
||||||
|
|
||||||
_ => self.tcx.sess.span_fatal(
|
_ => self.tcx.sess.emit_fatal(errors::UndefinedCleanDirtyItem {
|
||||||
attr.span,
|
span: attr.span,
|
||||||
&format!(
|
kind: format!("{:?}", item.kind),
|
||||||
"clean/dirty auto-assertions not yet defined \
|
}),
|
||||||
for Node::Item.node={:?}",
|
|
||||||
item.kind
|
|
||||||
),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HirNode::TraitItem(item) => match item.kind {
|
HirNode::TraitItem(item) => match item.kind {
|
||||||
|
@ -302,10 +295,10 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL),
|
ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL),
|
||||||
ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
|
ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
|
||||||
},
|
},
|
||||||
_ => self.tcx.sess.span_fatal(
|
_ => self.tcx.sess.emit_fatal(errors::UndefinedCleanDirty {
|
||||||
attr.span,
|
span: attr.span,
|
||||||
&format!("clean/dirty auto-assertions not yet defined for {:?}", node),
|
kind: format!("{:?}", node),
|
||||||
),
|
}),
|
||||||
};
|
};
|
||||||
let labels =
|
let labels =
|
||||||
Labels::from_iter(labels.iter().flat_map(|s| s.iter().map(|l| (*l).to_string())));
|
Labels::from_iter(labels.iter().flat_map(|s| s.iter().map(|l| (*l).to_string())));
|
||||||
|
@ -318,16 +311,15 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
let label = label.trim();
|
let label = label.trim();
|
||||||
if DepNode::has_label_string(label) {
|
if DepNode::has_label_string(label) {
|
||||||
if out.contains(label) {
|
if out.contains(label) {
|
||||||
self.tcx.sess.span_fatal(
|
self.tcx
|
||||||
item.span(),
|
.sess
|
||||||
&format!("dep-node label `{}` is repeated", label),
|
.emit_fatal(errors::RepeatedDepNodeLabel { span: item.span(), label });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
out.insert(label.to_string());
|
out.insert(label.to_string());
|
||||||
} else {
|
} else {
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.span_fatal(item.span(), &format!("dep-node label `{}` not recognized", label));
|
.emit_fatal(errors::UnrecognizedDepNodeLabel { span: item.span(), label });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
@ -348,7 +340,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
let dep_node_str = self.dep_node_str(&dep_node);
|
let dep_node_str = self.dep_node_str(&dep_node);
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.span_err(item_span, &format!("`{}` should be dirty but is not", dep_node_str));
|
.emit_err(errors::NotDirty { span: item_span, dep_node_str: &dep_node_str });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +351,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
let dep_node_str = self.dep_node_str(&dep_node);
|
let dep_node_str = self.dep_node_str(&dep_node);
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.span_err(item_span, &format!("`{}` should be clean but is not", dep_node_str));
|
.emit_err(errors::NotClean { span: item_span, dep_node_str: &dep_node_str });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,10 +360,9 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
|
||||||
|
|
||||||
if !self.tcx.dep_graph.debug_was_loaded_from_disk(dep_node) {
|
if !self.tcx.dep_graph.debug_was_loaded_from_disk(dep_node) {
|
||||||
let dep_node_str = self.dep_node_str(&dep_node);
|
let dep_node_str = self.dep_node_str(&dep_node);
|
||||||
self.tcx.sess.span_err(
|
self.tcx
|
||||||
item_span,
|
.sess
|
||||||
&format!("`{}` should have been loaded from disk but it was not", dep_node_str),
|
.emit_err(errors::NotLoaded { span: item_span, dep_node_str: &dep_node_str });
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,12 +403,12 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
|
||||||
debug!("check_config: searching for cfg {:?}", value);
|
debug!("check_config: searching for cfg {:?}", value);
|
||||||
cfg = Some(config.contains(&(value, None)));
|
cfg = Some(config.contains(&(value, None)));
|
||||||
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
|
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
|
||||||
tcx.sess.span_err(attr.span, &format!("unknown item `{}`", item.name_or_empty()));
|
tcx.sess.emit_err(errors::UnknownItem { span: attr.span, name: item.name_or_empty() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match cfg {
|
match cfg {
|
||||||
None => tcx.sess.span_fatal(attr.span, "no cfg attribute"),
|
None => tcx.sess.emit_fatal(errors::NoCfg { span: attr.span }),
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,13 +417,11 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
|
||||||
if let Some(value) = item.value_str() {
|
if let Some(value) = item.value_str() {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let msg = if let Some(ident) = item.ident() {
|
if let Some(ident) = item.ident() {
|
||||||
format!("associated value expected for `{}`", ident)
|
tcx.sess.emit_fatal(errors::AssociatedValueExpectedFor { span: item.span(), ident });
|
||||||
} else {
|
} else {
|
||||||
"expected an associated value".to_string()
|
tcx.sess.emit_fatal(errors::AssociatedValueExpected { span: item.span() });
|
||||||
};
|
}
|
||||||
|
|
||||||
tcx.sess.span_fatal(item.span(), &msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,7 +445,7 @@ impl<'tcx> FindAllAttrs<'tcx> {
|
||||||
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<ast::AttrId>) {
|
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<ast::AttrId>) {
|
||||||
for attr in &self.found_attrs {
|
for attr in &self.found_attrs {
|
||||||
if !checked_attrs.contains(&attr.id) {
|
if !checked_attrs.contains(&attr.id) {
|
||||||
self.tcx.sess.span_err(attr.span, "found unchecked `#[rustc_clean]` attribute");
|
self.tcx.sess.emit_err(errors::UncheckedClean { span: attr.span });
|
||||||
checked_attrs.insert(attr.id);
|
checked_attrs.insert(attr.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,15 @@
|
||||||
//! compiler versions don't change frequently for the typical user, being
|
//! compiler versions don't change frequently for the typical user, being
|
||||||
//! conservative here practically has no downside.
|
//! conservative here practically has no downside.
|
||||||
|
|
||||||
use std::env;
|
use crate::errors;
|
||||||
use std::fs;
|
|
||||||
use std::io::{self, Read};
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
use rustc_data_structures::memmap::Mmap;
|
use rustc_data_structures::memmap::Mmap;
|
||||||
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
|
||||||
use rustc_serialize::Encoder;
|
use rustc_serialize::Encoder;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::{self, Read};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// The first few bytes of files generated by incremental compilation.
|
/// The first few bytes of files generated by incremental compilation.
|
||||||
const FILE_MAGIC: &[u8] = b"RSIC";
|
const FILE_MAGIC: &[u8] = b"RSIC";
|
||||||
|
@ -60,12 +60,7 @@ where
|
||||||
}
|
}
|
||||||
Err(err) if err.kind() == io::ErrorKind::NotFound => (),
|
Err(err) if err.kind() == io::ErrorKind::NotFound => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sess.err(&format!(
|
sess.emit_err(errors::DeleteOld { name, path: path_buf, err });
|
||||||
"unable to delete old {} at `{}`: {}",
|
|
||||||
name,
|
|
||||||
path_buf.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +68,7 @@ where
|
||||||
let mut encoder = match FileEncoder::new(&path_buf) {
|
let mut encoder = match FileEncoder::new(&path_buf) {
|
||||||
Ok(encoder) => encoder,
|
Ok(encoder) => encoder,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sess.err(&format!("failed to create {} at `{}`: {}", name, path_buf.display(), err));
|
sess.emit_err(errors::CreateNew { name, path: path_buf, err });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -90,7 +85,7 @@ where
|
||||||
debug!("save: data written to disk successfully");
|
debug!("save: data written to disk successfully");
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sess.err(&format!("failed to write {} to `{}`: {}", name, path_buf.display(), err));
|
sess.emit_err(errors::WriteNew { name, path: path_buf, err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
//! unsupported file system and emit a warning in that case. This is not yet
|
//! unsupported file system and emit a warning in that case. This is not yet
|
||||||
//! implemented.
|
//! implemented.
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
use rustc_data_structures::{base_n, flock};
|
use rustc_data_structures::{base_n, flock};
|
||||||
|
@ -225,12 +226,7 @@ pub fn prepare_session_directory(
|
||||||
let crate_dir = match crate_dir.canonicalize() {
|
let crate_dir = match crate_dir.canonicalize() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let reported = sess.err(&format!(
|
return Err(sess.emit_err(errors::CanonicalizePath { path: crate_dir, err }));
|
||||||
"incremental compilation: error canonicalizing path `{}`: {}",
|
|
||||||
crate_dir.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
return Err(reported);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,14 +269,7 @@ pub fn prepare_session_directory(
|
||||||
debug!("successfully copied data from: {}", source_directory.display());
|
debug!("successfully copied data from: {}", source_directory.display());
|
||||||
|
|
||||||
if !allows_links {
|
if !allows_links {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::HardLinkFailed { path: &session_dir });
|
||||||
"Hard linking files in the incremental \
|
|
||||||
compilation cache failed. Copying files \
|
|
||||||
instead. Consider moving the cache \
|
|
||||||
directory to a file system which supports \
|
|
||||||
hard linking in session dir `{}`",
|
|
||||||
session_dir.display()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sess.init_incr_comp_session(session_dir, directory_lock, true);
|
sess.init_incr_comp_session(session_dir, directory_lock, true);
|
||||||
|
@ -295,12 +284,7 @@ pub fn prepare_session_directory(
|
||||||
// Try to remove the session directory we just allocated. We don't
|
// Try to remove the session directory we just allocated. We don't
|
||||||
// know if there's any garbage in it from the failed copy action.
|
// know if there's any garbage in it from the failed copy action.
|
||||||
if let Err(err) = safe_remove_dir_all(&session_dir) {
|
if let Err(err) = safe_remove_dir_all(&session_dir) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::DeletePartial { path: &session_dir, err });
|
||||||
"Failed to delete partly initialized \
|
|
||||||
session dir `{}`: {}",
|
|
||||||
session_dir.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_session_dir_lock_file(sess, &lock_file_path);
|
delete_session_dir_lock_file(sess, &lock_file_path);
|
||||||
|
@ -332,12 +316,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) {
|
if let Err(err) = safe_remove_dir_all(&*incr_comp_session_dir) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::DeleteFull { path: &incr_comp_session_dir, err });
|
||||||
"Error deleting incremental compilation \
|
|
||||||
session directory `{}`: {}",
|
|
||||||
incr_comp_session_dir.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let lock_file_path = lock_file_path(&*incr_comp_session_dir);
|
let lock_file_path = lock_file_path(&*incr_comp_session_dir);
|
||||||
|
@ -380,12 +359,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) {
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Warn about the error. However, no need to abort compilation now.
|
// Warn about the error. However, no need to abort compilation now.
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::Finalize { path: &incr_comp_session_dir, err: e });
|
||||||
"Error finalizing incremental compilation \
|
|
||||||
session directory `{}`: {}",
|
|
||||||
incr_comp_session_dir.display(),
|
|
||||||
e
|
|
||||||
));
|
|
||||||
|
|
||||||
debug!("finalize_session_directory() - error, marking as invalid");
|
debug!("finalize_session_directory() - error, marking as invalid");
|
||||||
// Drop the file lock, so we can garage collect
|
// Drop the file lock, so we can garage collect
|
||||||
|
@ -488,16 +462,7 @@ fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(), ErrorGua
|
||||||
debug!("{} directory created successfully", dir_tag);
|
debug!("{} directory created successfully", dir_tag);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => Err(sess.emit_err(errors::CreateIncrCompDir { tag: dir_tag, path, err })),
|
||||||
let reported = sess.err(&format!(
|
|
||||||
"Could not create incremental compilation {} \
|
|
||||||
directory `{}`: {}",
|
|
||||||
dir_tag,
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
Err(reported)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,46 +483,20 @@ fn lock_directory(
|
||||||
// the lock should be exclusive
|
// the lock should be exclusive
|
||||||
Ok(lock) => Ok((lock, lock_file_path)),
|
Ok(lock) => Ok((lock, lock_file_path)),
|
||||||
Err(lock_err) => {
|
Err(lock_err) => {
|
||||||
let mut err = sess.struct_err(&format!(
|
let is_unsupported_lock = flock::Lock::error_unsupported(&lock_err).then_some(());
|
||||||
"incremental compilation: could not create \
|
Err(sess.emit_err(errors::CreateLock {
|
||||||
session directory lock file: {}",
|
lock_err,
|
||||||
lock_err
|
session_dir,
|
||||||
));
|
is_unsupported_lock,
|
||||||
if flock::Lock::error_unsupported(&lock_err) {
|
is_cargo: std::env::var_os("CARGO").map(|_| ()),
|
||||||
err.note(&format!(
|
}))
|
||||||
"the filesystem for the incremental path at {} \
|
|
||||||
does not appear to support locking, consider changing the \
|
|
||||||
incremental path to a filesystem that supports locking \
|
|
||||||
or disable incremental compilation",
|
|
||||||
session_dir.display()
|
|
||||||
));
|
|
||||||
if std::env::var_os("CARGO").is_some() {
|
|
||||||
err.help(
|
|
||||||
"incremental compilation can be disabled by setting the \
|
|
||||||
environment variable CARGO_INCREMENTAL=0 (see \
|
|
||||||
https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)",
|
|
||||||
);
|
|
||||||
err.help(
|
|
||||||
"the entire build directory can be changed to a different \
|
|
||||||
filesystem by setting the environment variable CARGO_TARGET_DIR \
|
|
||||||
to a different path (see \
|
|
||||||
https://doc.rust-lang.org/cargo/reference/config.html#buildtarget-dir)",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err.emit())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_session_dir_lock_file(sess: &Session, lock_file_path: &Path) {
|
fn delete_session_dir_lock_file(sess: &Session, lock_file_path: &Path) {
|
||||||
if let Err(err) = safe_remove_file(&lock_file_path) {
|
if let Err(err) = safe_remove_file(&lock_file_path) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::DeleteLock { path: lock_file_path, err });
|
||||||
"Error deleting lock file for incremental \
|
|
||||||
compilation session directory `{}`: {}",
|
|
||||||
lock_file_path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,12 +713,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
|
||||||
if !lock_file_to_session_dir.values().any(|dir| *dir == directory_name) {
|
if !lock_file_to_session_dir.values().any(|dir| *dir == directory_name) {
|
||||||
let path = crate_directory.join(directory_name);
|
let path = crate_directory.join(directory_name);
|
||||||
if let Err(err) = safe_remove_dir_all(&path) {
|
if let Err(err) = safe_remove_dir_all(&path) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::InvalidGcFailed { path: &path, err });
|
||||||
"Failed to garbage collect invalid incremental \
|
|
||||||
compilation session directory `{}`: {}",
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -885,12 +819,7 @@ pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> {
|
||||||
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
|
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
|
||||||
|
|
||||||
if let Err(err) = safe_remove_dir_all(&path) {
|
if let Err(err) = safe_remove_dir_all(&path) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::FinalizedGcFailed { path: &path, err });
|
||||||
"Failed to garbage collect finalized incremental \
|
|
||||||
compilation session directory `{}`: {}",
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
delete_session_dir_lock_file(sess, &lock_file_path(&path));
|
delete_session_dir_lock_file(sess, &lock_file_path(&path));
|
||||||
}
|
}
|
||||||
|
@ -907,11 +836,7 @@ fn delete_old(sess: &Session, path: &Path) {
|
||||||
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
|
debug!("garbage_collect_session_directories() - deleting `{}`", path.display());
|
||||||
|
|
||||||
if let Err(err) = safe_remove_dir_all(&path) {
|
if let Err(err) = safe_remove_dir_all(&path) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::SessionGcFailed { path: &path, err });
|
||||||
"Failed to garbage collect incremental compilation session directory `{}`: {}",
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
delete_session_dir_lock_file(sess, &lock_file_path(&path));
|
delete_session_dir_lock_file(sess, &lock_file_path(&path));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Code to save/load the dep-graph from files.
|
//! Code to save/load the dep-graph from files.
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::memmap::Mmap;
|
use rustc_data_structures::memmap::Mmap;
|
||||||
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
|
use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
|
||||||
|
@ -8,7 +9,7 @@ use rustc_serialize::opaque::MemDecoder;
|
||||||
use rustc_serialize::Decodable;
|
use rustc_serialize::Decodable;
|
||||||
use rustc_session::config::IncrementalStateAssertion;
|
use rustc_session::config::IncrementalStateAssertion;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use super::data::*;
|
use super::data::*;
|
||||||
use super::file_format;
|
use super::file_format;
|
||||||
|
@ -27,11 +28,10 @@ pub enum LoadResult<T> {
|
||||||
},
|
},
|
||||||
/// The file either didn't exist or was produced by an incompatible compiler version.
|
/// The file either didn't exist or was produced by an incompatible compiler version.
|
||||||
DataOutOfDate,
|
DataOutOfDate,
|
||||||
/// An error occurred.
|
/// Loading the dep graph failed.
|
||||||
Error {
|
LoadDepGraph(PathBuf, std::io::Error),
|
||||||
#[allow(missing_docs)]
|
/// Decoding loaded incremental cache failed.
|
||||||
message: String,
|
DecodeIncrCache(Box<dyn std::any::Any + Send>),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> LoadResult<T> {
|
impl<T: Default> LoadResult<T> {
|
||||||
|
@ -40,36 +40,31 @@ impl<T: Default> LoadResult<T> {
|
||||||
// Check for errors when using `-Zassert-incremental-state`
|
// Check for errors when using `-Zassert-incremental-state`
|
||||||
match (sess.opts.assert_incr_state, &self) {
|
match (sess.opts.assert_incr_state, &self) {
|
||||||
(Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => {
|
(Some(IncrementalStateAssertion::NotLoaded), LoadResult::Ok { .. }) => {
|
||||||
sess.fatal(
|
sess.emit_fatal(errors::AssertNotLoaded);
|
||||||
"We asserted that the incremental cache should not be loaded, \
|
|
||||||
but it was loaded.",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
Some(IncrementalStateAssertion::Loaded),
|
Some(IncrementalStateAssertion::Loaded),
|
||||||
LoadResult::Error { .. } | LoadResult::DataOutOfDate,
|
LoadResult::LoadDepGraph(..)
|
||||||
|
| LoadResult::DecodeIncrCache(..)
|
||||||
|
| LoadResult::DataOutOfDate,
|
||||||
) => {
|
) => {
|
||||||
sess.fatal(
|
sess.emit_fatal(errors::AssertLoaded);
|
||||||
"We asserted that an existing incremental cache directory should \
|
|
||||||
be successfully loaded, but it was not.",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
LoadResult::Error { message } => {
|
LoadResult::LoadDepGraph(path, err) => {
|
||||||
sess.warn(&message);
|
sess.emit_warning(errors::LoadDepGraph { path, err });
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
LoadResult::DecodeIncrCache(err) => {
|
||||||
|
sess.emit_warning(errors::DecodeIncrCache { err: format!("{err:?}") });
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
LoadResult::DataOutOfDate => {
|
LoadResult::DataOutOfDate => {
|
||||||
if let Err(err) = delete_all_session_dir_contents(sess) {
|
if let Err(err) = delete_all_session_dir_contents(sess) {
|
||||||
sess.err(&format!(
|
sess.emit_err(errors::DeleteIncompatible { path: dep_graph_path(sess), err });
|
||||||
"Failed to delete invalidated or incompatible \
|
|
||||||
incremental compilation session directory contents `{}`: {}.",
|
|
||||||
dep_graph_path(sess).display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
@ -90,9 +85,7 @@ fn load_data(
|
||||||
// compiler version. Neither is an error.
|
// compiler version. Neither is an error.
|
||||||
LoadResult::DataOutOfDate
|
LoadResult::DataOutOfDate
|
||||||
}
|
}
|
||||||
Err(err) => LoadResult::Error {
|
Err(err) => LoadResult::LoadDepGraph(path.to_path_buf(), err),
|
||||||
message: format!("could not load dep-graph from `{}`: {}", path.display(), err),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,9 +107,9 @@ impl<T> MaybeAsync<LoadResult<T>> {
|
||||||
pub fn open(self) -> LoadResult<T> {
|
pub fn open(self) -> LoadResult<T> {
|
||||||
match self {
|
match self {
|
||||||
MaybeAsync::Sync(result) => result,
|
MaybeAsync::Sync(result) => result,
|
||||||
MaybeAsync::Async(handle) => handle.join().unwrap_or_else(|e| LoadResult::Error {
|
MaybeAsync::Async(handle) => {
|
||||||
message: format!("could not decode incremental cache: {:?}", e),
|
handle.join().unwrap_or_else(|e| LoadResult::DecodeIncrCache(e))
|
||||||
}),
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +178,8 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||||
|
|
||||||
match load_data(report_incremental_info, &path, nightly_build) {
|
match load_data(report_incremental_info, &path, nightly_build) {
|
||||||
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
|
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
|
||||||
LoadResult::Error { message } => LoadResult::Error { message },
|
LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
|
||||||
|
LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
|
||||||
LoadResult::Ok { data: (bytes, start_pos) } => {
|
LoadResult::Ok { data: (bytes, start_pos) } => {
|
||||||
let mut decoder = MemDecoder::new(&bytes, start_pos);
|
let mut decoder = MemDecoder::new(&bytes, start_pos);
|
||||||
let prev_commandline_args_hash = u64::decode(&mut decoder);
|
let prev_commandline_args_hash = u64::decode(&mut decoder);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::errors;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::join;
|
use rustc_data_structures::sync::join;
|
||||||
use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
|
use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
|
||||||
|
@ -59,19 +60,14 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) {
|
||||||
move || {
|
move || {
|
||||||
sess.time("incr_comp_persist_dep_graph", || {
|
sess.time("incr_comp_persist_dep_graph", || {
|
||||||
if let Err(err) = tcx.dep_graph.encode(&tcx.sess.prof) {
|
if let Err(err) = tcx.dep_graph.encode(&tcx.sess.prof) {
|
||||||
sess.err(&format!(
|
sess.emit_err(errors::WriteDepGraph { path: &staging_dep_graph_path, err });
|
||||||
"failed to write dependency graph to `{}`: {}",
|
|
||||||
staging_dep_graph_path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
if let Err(err) = fs::rename(&staging_dep_graph_path, &dep_graph_path) {
|
if let Err(err) = fs::rename(&staging_dep_graph_path, &dep_graph_path) {
|
||||||
sess.err(&format!(
|
sess.emit_err(errors::MoveDepGraph {
|
||||||
"failed to move dependency graph from `{}` to `{}`: {}",
|
from: &staging_dep_graph_path,
|
||||||
staging_dep_graph_path.display(),
|
to: &dep_graph_path,
|
||||||
dep_graph_path.display(),
|
err,
|
||||||
err
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -163,11 +159,7 @@ pub fn build_dep_graph(
|
||||||
let mut encoder = match FileEncoder::new(&path_buf) {
|
let mut encoder = match FileEncoder::new(&path_buf) {
|
||||||
Ok(encoder) => encoder,
|
Ok(encoder) => encoder,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sess.err(&format!(
|
sess.emit_err(errors::CreateDepGraph { path: &path_buf, err });
|
||||||
"failed to create dependency graph at `{}`: {}",
|
|
||||||
path_buf.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! [work products]: WorkProduct
|
//! [work products]: WorkProduct
|
||||||
|
|
||||||
|
use crate::errors;
|
||||||
use crate::persist::fs::*;
|
use crate::persist::fs::*;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_fs_util::link_or_copy;
|
use rustc_fs_util::link_or_copy;
|
||||||
|
@ -28,12 +29,11 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir(
|
||||||
let _ = saved_files.insert(ext.to_string(), file_name);
|
let _ = saved_files.insert(ext.to_string(), file_name);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::CopyWorkProductToCache {
|
||||||
"error copying object file `{}` to incremental directory as `{}`: {}",
|
from: &path,
|
||||||
path.display(),
|
to: &path_in_incr_dir,
|
||||||
path_in_incr_dir.display(),
|
err,
|
||||||
err
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,7 @@ pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) {
|
||||||
for (_, path) in &work_product.saved_files {
|
for (_, path) in &work_product.saved_files {
|
||||||
let path = in_incr_comp_dir_sess(sess, path);
|
let path = in_incr_comp_dir_sess(sess, path);
|
||||||
if let Err(err) = std_fs::remove_file(&path) {
|
if let Err(err) = std_fs::remove_file(&path) {
|
||||||
sess.warn(&format!(
|
sess.emit_warning(errors::DeleteWorkProduct { path: &path, err });
|
||||||
"file-system error deleting outdated file `{}`: {}",
|
|
||||||
path.display(),
|
|
||||||
err
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,6 @@ all:
|
||||||
touch $(SESSION_DIR)
|
touch $(SESSION_DIR)
|
||||||
# Check exit code is 1 for an error, and not 101 for ICE.
|
# Check exit code is 1 for an error, and not 101 for ICE.
|
||||||
$(RUSTC) foo.rs --crate-type=rlib -C incremental=$(SESSION_DIR) > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ]
|
$(RUSTC) foo.rs --crate-type=rlib -C incremental=$(SESSION_DIR) > $(OUTPUT_FILE) 2>&1; [ $$? -eq 1 ]
|
||||||
$(CGREP) "Could not create incremental compilation crate directory" < $(OUTPUT_FILE)
|
$(CGREP) "could not create incremental compilation crate directory" < $(OUTPUT_FILE)
|
||||||
# -v tests are fragile, hopefully this text won't change
|
# -v tests are fragile, hopefully this text won't change
|
||||||
$(CGREP) -v "internal compiler error" < $(OUTPUT_FILE)
|
$(CGREP) -v "internal compiler error" < $(OUTPUT_FILE)
|
||||||
|
|
Loading…
Add table
Reference in a new issue