Skip to main content

rustc_infer/infer/lexical_region_resolve/
indexed_edges.rs

1use rustc_index::IndexVec;
2use rustc_type_ir::RegionVid;
3
4use crate::infer::SubregionOrigin;
5use crate::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};
6
7/// Selects either out-edges or in-edges for [`IndexedConstraintEdges::adjacent_edges`].
8#[derive(#[automatically_derived]
impl ::core::clone::Clone for EdgeDirection {
    #[inline]
    fn clone(&self) -> EdgeDirection { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for EdgeDirection { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for EdgeDirection {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                EdgeDirection::Out => "Out",
                EdgeDirection::In => "In",
            })
    }
}Debug)]
9pub(super) enum EdgeDirection {
10    Out,
11    In,
12}
13
14/// Type alias for the pairs stored in [`RegionConstraintData::constraints`],
15/// which we are indexing.
16type ConstraintPair<'tcx> = (Constraint<'tcx>, SubregionOrigin<'tcx>);
17
18/// An index from region variables to their corresponding constraint edges,
19/// used on some error paths.
20pub(super) struct IndexedConstraintEdges<'data, 'tcx> {
21    out_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
22    in_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
23}
24
25impl<'data, 'tcx> IndexedConstraintEdges<'data, 'tcx> {
26    pub(super) fn build_index(num_vars: usize, data: &'data RegionConstraintData<'tcx>) -> Self {
27        let mut out_edges = IndexVec::from_fn_n(|_| ::alloc::vec::Vec::new()vec![], num_vars);
28        let mut in_edges = IndexVec::from_fn_n(|_| ::alloc::vec::Vec::new()vec![], num_vars);
29
30        for pair @ (c, _) in &data.constraints {
31            // Only push a var out-edge for `VarSub...` constraints.
32            match c.kind {
33                ConstraintKind::VarSubVar | ConstraintKind::VarSubReg => {
34                    out_edges[c.sub.as_var()].push(pair)
35                }
36                ConstraintKind::RegSubVar | ConstraintKind::RegSubReg => {}
37            }
38        }
39
40        // Index in-edges in reverse order, to match what current tests expect.
41        // (It's unclear whether this is important or not.)
42        for pair @ (c, _) in data.constraints.iter().rev() {
43            // Only push a var in-edge for `...SubVar` constraints.
44            match c.kind {
45                ConstraintKind::VarSubVar | ConstraintKind::RegSubVar => {
46                    in_edges[c.sup.as_var()].push(pair)
47                }
48                ConstraintKind::VarSubReg | ConstraintKind::RegSubReg => {}
49            }
50        }
51
52        IndexedConstraintEdges { out_edges, in_edges }
53    }
54
55    /// Returns either the out-edges or in-edges of the specified region var,
56    /// as selected by `dir`.
57    pub(super) fn adjacent_edges(
58        &self,
59        region_vid: RegionVid,
60        dir: EdgeDirection,
61    ) -> &[&'data ConstraintPair<'tcx>] {
62        let edges = match dir {
63            EdgeDirection::Out => &self.out_edges,
64            EdgeDirection::In => &self.in_edges,
65        };
66        &edges[region_vid]
67    }
68}