Allow for try_force_from_dep_node to fail

The way it is implemented currently try_force_from_dep_node returns true
as long as there's a function to force the query. It wasn't this way
from the beginning, earlier version was producing forcing result and it
was changed in https://github.com/rust-lang/rust/pull/89978, I couldn't
find any comments addressing this change.

One way it can fail is by failing to recover the query in
DepNodeParams::recover - when we are trying to query something that no
longer exists in the current environment
This commit is contained in:
Michael Baikov 2024-06-13 08:27:21 -04:00
parent 3c0f019b3c
commit db5ed4bd79
2 changed files with 51 additions and 7 deletions

View File

@ -51,20 +51,24 @@ fn is_eval_always(self, kind: DepKind) -> bool {
}
/// Try to force a dep node to execute and see if it's green.
///
/// Returns true if the query has actually been forced. It is valid that a query
/// fails to be forced, e.g. when the query key cannot be reconstructed from the
/// dep-node or when the query kind outright does not support it.
#[inline]
#[instrument(skip(self, frame), level = "debug")]
fn try_force_from_dep_node(self, dep_node: DepNode, frame: Option<&MarkFrame<'_>>) -> bool {
let cb = self.dep_kind_info(dep_node.kind);
if let Some(f) = cb.force_from_dep_node {
if let Err(value) = panic::catch_unwind(panic::AssertUnwindSafe(|| {
f(self, dep_node);
})) {
if !value.is::<rustc_errors::FatalErrorMarker>() {
print_markframe_trace(self.dep_graph(), frame);
match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node))) {
Err(value) => {
if !value.is::<rustc_errors::FatalErrorMarker>() {
print_markframe_trace(self.dep_graph(), frame);
}
panic::resume_unwind(value)
}
panic::resume_unwind(value)
Ok(query_has_been_forced) => query_has_been_forced,
}
true
} else {
false
}

View File

@ -0,0 +1,40 @@
// If it is impossible to find query arguments just from the hash
// compiler should treat the node as red
// In this test prior to fixing compiler was having problems figuring out
// drop impl for T inside of m
//@ revisions:cfail1 cfail2
//@ compile-flags: --crate-type=lib
//@ build-pass
pub trait P {
type A;
}
struct S;
impl P for S {
type A = C;
}
struct T<D: P>(D::A, Z<D>);
struct Z<D: P>(D::A, String);
impl<D: P> T<D> {
pub fn i() -> Self {
loop {}
}
}
enum C {
#[cfg(cfail1)]
Up(()),
#[cfg(cfail2)]
Lorry(()),
}
pub fn m() {
T::<S>::i();
}