1use std::fmt::Debug;
24
25use rustc_index::bit_set::DenseBitSet;
26use rustc_index::{Idx, IndexSlice, IndexVec};
27use tracing::debug;
28
29#[cfg(test)]
30mod tests;
31
32pub struct LinkedGraph<N, E> {
49 nodes: IndexVec<NodeIndex, Node<N>>,
50 edges: Vec<Edge<E>>,
51}
52
53pub struct Node<N> {
54 first_edge: [EdgeIndex; 2], pub data: Option<N>,
56}
57
58#[derive(#[automatically_derived]
impl<E: ::core::fmt::Debug> ::core::fmt::Debug for Edge<E> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "Edge",
"next_edge", &self.next_edge, "source", &self.source, "target",
&self.target, "data", &&self.data)
}
}Debug)]
59pub struct Edge<E> {
60 next_edge: [EdgeIndex; 2], source: NodeIndex,
62 target: NodeIndex,
63 pub data: E,
64}
65
66#[derive(#[automatically_derived]
impl ::core::marker::Copy for NodeIndex { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NodeIndex {
#[inline]
fn clone(&self) -> NodeIndex {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for NodeIndex {
#[inline]
fn eq(&self, other: &NodeIndex) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NodeIndex {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<usize>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for NodeIndex {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for NodeIndex {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "NodeIndex",
&&self.0)
}
}Debug)]
67pub struct NodeIndex(pub usize);
68
69#[derive(#[automatically_derived]
impl ::core::marker::Copy for EdgeIndex { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EdgeIndex {
#[inline]
fn clone(&self) -> EdgeIndex {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for EdgeIndex {
#[inline]
fn eq(&self, other: &EdgeIndex) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for EdgeIndex {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "EdgeIndex",
&&self.0)
}
}Debug)]
70pub struct EdgeIndex(pub usize);
71
72pub const INVALID_EDGE_INDEX: EdgeIndex = EdgeIndex(usize::MAX);
73
74#[derive(#[automatically_derived]
impl ::core::marker::Copy for Direction { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Direction {
#[inline]
fn clone(&self) -> Direction {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Direction {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "Direction",
"repr", &&self.repr)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Direction {
#[inline]
fn eq(&self, other: &Direction) -> bool { self.repr == other.repr }
}PartialEq)]
76pub struct Direction {
77 repr: usize,
78}
79
80pub const OUTGOING: Direction = Direction { repr: 0 };
81
82pub const INCOMING: Direction = Direction { repr: 1 };
83
84impl NodeIndex {
85 pub fn node_id(self) -> usize {
87 self.0
88 }
89}
90
91impl Idx for NodeIndex {
92 fn new(idx: usize) -> NodeIndex {
93 NodeIndex(idx)
94 }
95
96 fn index(self) -> usize {
97 self.0
98 }
99}
100
101impl<N: Debug, E: Debug> LinkedGraph<N, E> {
102 pub fn new() -> Self {
103 Self { nodes: IndexVec::new(), edges: Vec::new() }
104 }
105
106 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
107 Self { nodes: IndexVec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
108 }
109
110 #[inline]
113 pub fn all_nodes(&self) -> &IndexSlice<NodeIndex, Node<N>> {
114 &self.nodes
115 }
116
117 #[inline]
118 pub fn len_nodes(&self) -> usize {
119 self.nodes.len()
120 }
121
122 #[inline]
123 pub fn all_edges(&self) -> &[Edge<E>] {
124 &self.edges
125 }
126
127 #[inline]
128 pub fn len_edges(&self) -> usize {
129 self.edges.len()
130 }
131
132 pub fn next_node_index(&self) -> NodeIndex {
135 NodeIndex(self.nodes.len())
136 }
137
138 fn ensure_node(&mut self, idx: NodeIndex) -> &mut Node<N> {
139 self.nodes.ensure_contains_elem(idx, || Node {
140 first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
141 data: None,
142 })
143 }
144
145 pub fn add_node_with_idx(&mut self, idx: NodeIndex, data: N) {
146 let old_data = self.ensure_node(idx).data.replace(data);
147 if true {
if !old_data.is_none() {
::core::panicking::panic("assertion failed: old_data.is_none()")
};
};debug_assert!(old_data.is_none());
148 }
149
150 pub fn add_node(&mut self, data: N) -> NodeIndex {
151 let idx = self.next_node_index();
152 self.add_node_with_idx(idx, data);
153 idx
154 }
155
156 pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
157 self.nodes[idx].data.as_mut().unwrap()
158 }
159
160 pub fn node_data(&self, idx: NodeIndex) -> &N {
161 self.nodes[idx].data.as_ref().unwrap()
162 }
163
164 pub fn node(&self, idx: NodeIndex) -> &Node<N> {
165 &self.nodes[idx]
166 }
167
168 pub fn next_edge_index(&self) -> EdgeIndex {
171 EdgeIndex(self.edges.len())
172 }
173
174 pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, data: E) -> EdgeIndex {
175 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_data_structures/src/graph/linked_graph/mod.rs:175",
"rustc_data_structures::graph::linked_graph",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_data_structures/src/graph/linked_graph/mod.rs"),
::tracing_core::__macro_support::Option::Some(175u32),
::tracing_core::__macro_support::Option::Some("rustc_data_structures::graph::linked_graph"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("graph: add_edge({0:?}, {1:?}, {2:?})",
source, target, data) as &dyn Value))])
});
} else { ; }
};debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);
176
177 let idx = self.next_edge_index();
178
179 let source_first = self.ensure_node(source).first_edge[OUTGOING.repr];
181 let target_first = self.ensure_node(target).first_edge[INCOMING.repr];
182
183 self.edges.push(Edge { next_edge: [source_first, target_first], source, target, data });
186
187 self.nodes[source].first_edge[OUTGOING.repr] = idx;
189 self.nodes[target].first_edge[INCOMING.repr] = idx;
190
191 idx
192 }
193
194 pub fn edge(&self, idx: EdgeIndex) -> &Edge<E> {
195 &self.edges[idx.0]
196 }
197
198 pub fn enumerated_nodes(&self) -> impl Iterator<Item = (NodeIndex, &Node<N>)> {
201 self.nodes.iter().enumerate().map(|(idx, n)| (NodeIndex(idx), n))
202 }
203
204 pub fn enumerated_edges(&self) -> impl Iterator<Item = (EdgeIndex, &Edge<E>)> {
205 self.edges.iter().enumerate().map(|(idx, e)| (EdgeIndex(idx), e))
206 }
207
208 pub fn each_node<'a>(&'a self, mut f: impl FnMut(NodeIndex, &'a Node<N>) -> bool) -> bool {
209 self.enumerated_nodes().all(|(node_idx, node)| f(node_idx, node))
211 }
212
213 pub fn each_edge<'a>(&'a self, mut f: impl FnMut(EdgeIndex, &'a Edge<E>) -> bool) -> bool {
214 self.enumerated_edges().all(|(edge_idx, edge)| f(edge_idx, edge))
216 }
217
218 pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> {
219 self.adjacent_edges(source, OUTGOING)
220 }
221
222 pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<'_, N, E> {
223 self.adjacent_edges(source, INCOMING)
224 }
225
226 pub fn adjacent_edges(
227 &self,
228 source: NodeIndex,
229 direction: Direction,
230 ) -> AdjacentEdges<'_, N, E> {
231 let first_edge = self.node(source).first_edge[direction.repr];
232 AdjacentEdges { graph: self, direction, next: first_edge }
233 }
234
235 pub fn successor_nodes(&self, source: NodeIndex) -> impl Iterator<Item = NodeIndex> {
236 self.outgoing_edges(source).targets()
237 }
238
239 pub fn predecessor_nodes(&self, target: NodeIndex) -> impl Iterator<Item = NodeIndex> {
240 self.incoming_edges(target).sources()
241 }
242
243 pub fn depth_traverse(
244 &self,
245 start: NodeIndex,
246 direction: Direction,
247 ) -> DepthFirstTraversal<'_, N, E> {
248 DepthFirstTraversal::with_start_node(self, start, direction)
249 }
250
251 pub fn nodes_in_postorder(
252 &self,
253 direction: Direction,
254 entry_node: NodeIndex,
255 ) -> Vec<NodeIndex> {
256 let mut visited = DenseBitSet::new_empty(self.len_nodes());
257 let mut stack = ::alloc::vec::Vec::new()vec![];
258 let mut result = Vec::with_capacity(self.len_nodes());
259 let mut push_node = |stack: &mut Vec<_>, node: NodeIndex| {
260 if visited.insert(node.0) {
261 stack.push((node, self.adjacent_edges(node, direction)));
262 }
263 };
264
265 for node in
266 Some(entry_node).into_iter().chain(self.enumerated_nodes().map(|(node, _)| node))
267 {
268 push_node(&mut stack, node);
269 while let Some((node, mut iter)) = stack.pop() {
270 if let Some((_, child)) = iter.next() {
271 let target = child.source_or_target(direction);
272 stack.push((node, iter));
275 push_node(&mut stack, target);
277 } else {
278 result.push(node);
279 }
280 }
281 }
282
283 match (&result.len(), &self.len_nodes()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
};assert_eq!(result.len(), self.len_nodes());
284 result
285 }
286}
287
288pub struct AdjacentEdges<'g, N, E> {
291 graph: &'g LinkedGraph<N, E>,
292 direction: Direction,
293 next: EdgeIndex,
294}
295
296impl<'g, N: Debug, E: Debug> AdjacentEdges<'g, N, E> {
297 fn targets(self) -> impl Iterator<Item = NodeIndex> {
298 self.map(|(_, edge)| edge.target)
299 }
300
301 fn sources(self) -> impl Iterator<Item = NodeIndex> {
302 self.map(|(_, edge)| edge.source)
303 }
304}
305
306impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
307 type Item = (EdgeIndex, &'g Edge<E>);
308
309 fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
310 let edge_index = self.next;
311 if edge_index == INVALID_EDGE_INDEX {
312 return None;
313 }
314
315 let edge = self.graph.edge(edge_index);
316 self.next = edge.next_edge[self.direction.repr];
317 Some((edge_index, edge))
318 }
319
320 fn size_hint(&self) -> (usize, Option<usize>) {
321 (0, Some(self.graph.len_edges()))
323 }
324}
325
326pub struct DepthFirstTraversal<'g, N, E> {
327 graph: &'g LinkedGraph<N, E>,
328 stack: Vec<NodeIndex>,
329 visited: DenseBitSet<usize>,
330 direction: Direction,
331}
332
333impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
334 pub fn with_start_node(
335 graph: &'g LinkedGraph<N, E>,
336 start_node: NodeIndex,
337 direction: Direction,
338 ) -> Self {
339 let mut visited = DenseBitSet::new_empty(graph.len_nodes());
340 visited.insert(start_node.node_id());
341 DepthFirstTraversal { graph, stack: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[start_node]))vec![start_node], visited, direction }
342 }
343
344 fn visit(&mut self, node: NodeIndex) {
345 if self.visited.insert(node.node_id()) {
346 self.stack.push(node);
347 }
348 }
349}
350
351impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
352 type Item = NodeIndex;
353
354 fn next(&mut self) -> Option<NodeIndex> {
355 let next = self.stack.pop();
356 if let Some(idx) = next {
357 for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
358 let target = edge.source_or_target(self.direction);
359 self.visit(target);
360 }
361 }
362 next
363 }
364
365 fn size_hint(&self) -> (usize, Option<usize>) {
366 let remaining = self.graph.len_nodes() - self.visited.count();
368 (remaining, Some(remaining))
369 }
370}
371
372impl<'g, N: Debug, E: Debug> ExactSizeIterator for DepthFirstTraversal<'g, N, E> {}
373
374impl<E> Edge<E> {
375 pub fn source(&self) -> NodeIndex {
376 self.source
377 }
378
379 pub fn target(&self) -> NodeIndex {
380 self.target
381 }
382
383 pub fn source_or_target(&self, direction: Direction) -> NodeIndex {
384 if direction == OUTGOING { self.target } else { self.source }
385 }
386}