From 59babd80bde4ce2f96768e44047ba0e44afc8eac Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 11 Apr 2017 17:11:22 -0400 Subject: [PATCH] add some comments and `debug!` calls to "obligation forest" --- .../obligation_forest/mod.rs | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index a46238309bb..3515e5c5ede 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -43,7 +43,16 @@ pub trait ObligationProcessor { obligation: &mut Self::Obligation) -> Result>, Self::Error>; - fn process_backedge<'c, I>(&mut self, cycle: I, + /// As we do the cycle check, we invoke this callback when we + /// encounter an actual cycle. `cycle` is an iterator that starts + /// at the start of the cycle in the stack and walks **toward the + /// top**. + /// + /// In other words, if we had O1 which required O2 which required + /// O3 which required O1, we would give an iterator yielding O1, + /// O2, O3 (O1 is not yielded twice). + fn process_backedge<'c, I>(&mut self, + cycle: I, _marker: PhantomData<&'c Self::Obligation>) where I: Clone + Iterator; } @@ -239,8 +248,8 @@ impl ObligationForest { } } Entry::Vacant(v) => { - debug!("register_obligation_at({:?}, {:?}) - ok", - obligation, parent); + debug!("register_obligation_at({:?}, {:?}) - ok, new index is {}", + obligation, parent, self.nodes.len()); v.insert(NodeIndex::new(self.nodes.len())); self.cache_list.push(obligation.as_predicate().clone()); self.nodes.push(Node::new(parent, obligation)); @@ -376,6 +385,9 @@ impl ObligationForest { where P: ObligationProcessor { let mut stack = self.scratch.take().unwrap(); + debug_assert!(stack.is_empty()); + + debug!("process_cycles()"); for index in 0..self.nodes.len() { // For rustc-benchmarks/inflate-0.1.0 this state test is extremely @@ -389,6 +401,9 @@ impl ObligationForest { } } + debug!("process_cycles: complete"); + + debug_assert!(stack.is_empty()); self.scratch = Some(stack); } @@ -402,21 +417,6 @@ impl ObligationForest { NodeState::OnDfsStack => { let index = stack.iter().rposition(|n| *n == index).unwrap(); - // I need a Clone closure - #[derive(Clone)] - struct GetObligation<'a, O: 'a>(&'a [Node]); - impl<'a, 'b, O> FnOnce<(&'b usize,)> for GetObligation<'a, O> { - type Output = &'a O; - extern "rust-call" fn call_once(self, args: (&'b usize,)) -> &'a O { - &self.0[*args.0].obligation - } - } - impl<'a, 'b, O> FnMut<(&'b usize,)> for GetObligation<'a, O> { - extern "rust-call" fn call_mut(&mut self, args: (&'b usize,)) -> &'a O { - &self.0[*args.0].obligation - } - } - processor.process_backedge(stack[index..].iter().map(GetObligation(&self.nodes)), PhantomData); } @@ -645,3 +645,20 @@ impl Node { } } } + +// I need a Clone closure +#[derive(Clone)] +struct GetObligation<'a, O: 'a>(&'a [Node]); + +impl<'a, 'b, O> FnOnce<(&'b usize,)> for GetObligation<'a, O> { + type Output = &'a O; + extern "rust-call" fn call_once(self, args: (&'b usize,)) -> &'a O { + &self.0[*args.0].obligation + } +} + +impl<'a, 'b, O> FnMut<(&'b usize,)> for GetObligation<'a, O> { + extern "rust-call" fn call_mut(&mut self, args: (&'b usize,)) -> &'a O { + &self.0[*args.0].obligation + } +}