Skip to content

Commit 8e6ca04

Browse files
MarwesMarkus Westerlind
authored and
Markus Westerlind
committed
Restore alternative predicates for obligation forest
Extracted a test from the object crate found while running on CI (did not exist the in the actual test suite).
1 parent c49182b commit 8e6ca04

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

compiler/rustc_data_structures/src/obligation_forest/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ struct Node<O: ForestObligation> {
252252
obligation: O,
253253
state: Cell<NodeState>,
254254

255+
/// A predicate (and its key) can change during processing. If it does we need to register the
256+
/// old predicate so that we can remove or mark it as done if this node errors or is done.
257+
alternative_predicates: Vec<O::CacheKey>,
258+
255259
/// Obligations that depend on this obligation for their completion. They
256260
/// must all be in a non-pending state.
257261
dependents: Vec<NodeIndex>,
@@ -287,6 +291,7 @@ where
287291
Node {
288292
obligation,
289293
state: Cell::new(NodeState::Pending),
294+
alternative_predicates: vec![],
290295
dependents: if let Some(parent_index) = parent { vec![parent_index] } else { vec![] },
291296
reverse_dependents: vec![],
292297
has_parent: parent.is_some(),
@@ -311,6 +316,7 @@ where
311316
self.state
312317
);
313318
self.state.set(NodeState::Pending);
319+
self.alternative_predicates.clear();
314320
self.dependents.clear();
315321
self.reverse_dependents.clear();
316322
if let Some(parent_index) = parent {
@@ -660,7 +666,12 @@ impl<O: ForestObligation> ObligationForest<O> {
660666
// `self.active_cache`. This means that `self.active_cache` can get
661667
// out of sync with `nodes`. It's not very common, but it does
662668
// happen, and code in `compress` has to allow for it.
669+
let before = node.obligation.as_cache_key();
663670
let result = processor.process_obligation(&mut node.obligation);
671+
let after = node.obligation.as_cache_key();
672+
if before != after {
673+
node.alternative_predicates.push(before);
674+
}
664675

665676
self.unblock_nodes(processor);
666677
let node = &mut self.nodes[index];
@@ -934,6 +945,12 @@ impl<O: ForestObligation> ObligationForest<O> {
934945
.active_cache
935946
.entry(node.obligation.as_cache_key())
936947
.or_insert(CacheState::Done) = CacheState::Done;
948+
// If the node's predicate changed at some point we mark all its alternate
949+
// predicates as done as well
950+
for alt in node.alternative_predicates.drain(..) {
951+
*self.active_cache.entry(alt).or_insert(CacheState::Done) =
952+
CacheState::Done;
953+
}
937954

938955
if do_completed == DoCompleted::Yes {
939956
// Extract the success stories.
@@ -949,6 +966,11 @@ impl<O: ForestObligation> ObligationForest<O> {
949966
// tests must come up with a different type on every type error they
950967
// check against.
951968
self.active_cache.remove(&node.obligation.as_cache_key());
969+
// If the node's predicate changed at some point we remove all its alternate
970+
// predicates as well
971+
for alt in &node.alternative_predicates {
972+
self.active_cache.remove(alt);
973+
}
952974
self.insert_into_error_cache(index);
953975
self.dead_nodes.push(index);
954976
}

compiler/rustc_middle/src/infer/unify_key.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ pub struct ConstVarValue<'tcx> {
160160
pub val: ConstVariableValue<'tcx>,
161161
}
162162

163-
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
163+
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
164164
pub struct ConstVidEqKey<'tcx> {
165165
pub vid: ty::ConstVid,
166166
pub phantom: PhantomData<&'tcx ()>,

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,11 +1040,7 @@ impl<T> Binder<T> {
10401040
where
10411041
T: TypeFoldable<'tcx>,
10421042
{
1043-
if self.0.has_escaping_bound_vars() {
1044-
None
1045-
} else {
1046-
Some(self.skip_binder())
1047-
}
1043+
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
10481044
}
10491045

10501046
/// Given two things that have the same binder level,
@@ -1927,11 +1923,7 @@ impl<'tcx> TyS<'tcx> {
19271923

19281924
#[inline]
19291925
pub fn is_phantom_data(&self) -> bool {
1930-
if let Adt(def, _) = self.kind() {
1931-
def.is_phantom_data()
1932-
} else {
1933-
false
1934-
}
1926+
if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false }
19351927
}
19361928

19371929
#[inline]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// run-pass
2+
#![allow(dead_code)]
3+
4+
use std::borrow::Cow;
5+
6+
pub type Result<T> = std::result::Result<T, &'static str>;
7+
8+
pub struct CompressedData<'data> {
9+
pub format: CompressionFormat,
10+
pub data: &'data [u8],
11+
}
12+
13+
pub enum CompressionFormat {
14+
None,
15+
Unknown,
16+
}
17+
18+
impl<'data> CompressedData<'data> {
19+
pub fn decompress(self) -> Result<Cow<'data, [u8]>> {
20+
match self.format {
21+
CompressionFormat::None => Ok(Cow::Borrowed(self.data)),
22+
_ => Err("Unsupported compressed data."),
23+
}
24+
}
25+
}
26+
27+
fn main() {}

0 commit comments

Comments
 (0)