Skip to content

Commit 5a9b704

Browse files
committed
Improve comments about NodeStates.
This commit clarifies some comments, fixes some minor errors in comments, and adds a state transition diagram.
1 parent caf0187 commit 5a9b704

File tree

1 file changed

+52
-21
lines changed
  • src/librustc_data_structures/obligation_forest

1 file changed

+52
-21
lines changed

src/librustc_data_structures/obligation_forest/mod.rs

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,11 @@ type ObligationTreeIdGenerator =
130130
pub struct ObligationForest<O: ForestObligation> {
131131
/// The list of obligations. In between calls to
132132
/// `process_obligations`, this list only contains nodes in the
133-
/// `Pending` or `Success` state (with a non-zero number of
133+
/// `Pending` or `Waiting` state (with a non-zero number of
134134
/// incomplete children). During processing, some of those nodes
135135
/// may be changed to the error state, or we may find that they
136-
/// are completed (That is, `num_incomplete_children` drops to 0).
137-
/// At the end of processing, those nodes will be removed by a
138-
/// call to `compress`.
136+
/// are completed. At the end of processing, those nodes will be
137+
/// removed by a call to `compress`.
139138
///
140139
/// `usize` indices are used here and throughout this module, rather than
141140
/// `rustc_index::newtype_index!` indices, because this code is hot enough that the
@@ -211,28 +210,56 @@ impl<O> Node<O> {
211210
/// represents the current state of processing for the obligation (of
212211
/// type `O`) associated with this node.
213212
///
214-
/// Outside of ObligationForest methods, nodes should be either Pending
215-
/// or Waiting.
213+
/// The non-`Error` state transitions are as follows.
214+
/// ```
215+
/// (Pre-creation)
216+
/// |
217+
/// | register_obligation_at() (called by process_obligations() and
218+
/// v from outside the crate)
219+
/// Pending
220+
/// |
221+
/// | process_obligations()
222+
/// v
223+
/// Success
224+
/// | ^
225+
/// | | mark_as_waiting()
226+
/// | v
227+
/// | Waiting
228+
/// |
229+
/// | process_cycles()
230+
/// v
231+
/// Done
232+
/// |
233+
/// | compress()
234+
/// v
235+
/// (Removed)
236+
/// ```
237+
/// The `Error` state can be introduced in several places, via `error_at()`.
238+
///
239+
/// Outside of `ObligationForest` methods, nodes should be either `Pending` or
240+
/// `Waiting`.
216241
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
217242
enum NodeState {
218-
/// Obligations for which selection had not yet returned a
219-
/// non-ambiguous result.
243+
/// This obligation has not yet been selected successfully. Cannot have
244+
/// subobligations.
220245
Pending,
221246

222-
/// This obligation was selected successfully, but may or
223-
/// may not have subobligations.
247+
/// This obligation was selected successfully, but the state of any
248+
/// subobligations are current unknown. It will be converted to `Waiting`
249+
/// or `Done` once the states of the subobligations become known.
224250
Success,
225251

226-
/// This obligation was selected successfully, but it has
227-
/// a pending subobligation.
252+
/// This obligation was selected successfully, but it has one or more
253+
/// pending subobligations.
228254
Waiting,
229255

230-
/// This obligation, along with its subobligations, are complete,
231-
/// and will be removed in the next collection.
256+
/// This obligation was selected successfully, as were all of its
257+
/// subobligations (of which there may be none). It will be removed by the
258+
/// next compression step.
232259
Done,
233260

234-
/// This obligation was resolved to an error. Error nodes are
235-
/// removed from the vector by the compression step.
261+
/// This obligation was resolved to an error. It will be removed by the
262+
/// next compression step.
236263
Error,
237264
}
238265

@@ -466,10 +493,9 @@ impl<O: ForestObligation> ObligationForest<O> {
466493
}
467494
}
468495

469-
/// Mark all `NodeState::Success` nodes as `NodeState::Done` and
470-
/// report all cycles between them. This should be called
471-
/// after `mark_as_waiting` marks all nodes with pending
472-
/// subobligations as NodeState::Waiting.
496+
/// Mark all `Success` nodes as `Done` and report all cycles between them.
497+
/// This should be called after `mark_as_waiting` updates the status of all
498+
/// `Waiting` and `Success` nodes.
473499
fn process_cycles<P>(&self, processor: &mut P)
474500
where P: ObligationProcessor<Obligation=O>
475501
{
@@ -575,14 +601,19 @@ impl<O: ForestObligation> ObligationForest<O> {
575601
self.inlined_mark_neighbors_as_waiting_from(node)
576602
}
577603

578-
/// Marks all nodes that depend on a pending node as `NodeState::Waiting`.
604+
/// Updates the states of all `Waiting` and `Success` nodes. Upon
605+
/// completion, all such nodes that depend on a pending node will be marked
606+
/// as `Waiting`, and all others will be marked as `Success`.
579607
fn mark_as_waiting(&self) {
608+
// Optimistically mark all `Waiting` nodes as `Success`.
580609
for node in &self.nodes {
581610
if node.state.get() == NodeState::Waiting {
582611
node.state.set(NodeState::Success);
583612
}
584613
}
585614

615+
// Convert all `Success` nodes that still depend on a pending node to
616+
// `Waiting`. This may undo some of the changes done in the loop above.
586617
for node in &self.nodes {
587618
if node.state.get() == NodeState::Pending {
588619
// This call site is hot.

0 commit comments

Comments
 (0)