Repository: rust-lang/rust
File: compiler/rustc_infer/src/infer/lexical_region_resolve/indexed_edges.rs (Rust)

Code before:

use crate::infer::SubregionOrigin;
use crate::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};

/// Selects either out-edges or in-edges for [`IndexedConstraintEdges::adjacent_edges`].
#[derive(Clone, Copy, Debug)]
pub(crate) enum EdgeDirection {
    Out,
    In,
}

pub(crate) type ConstraintPair<'tcx> = (Constraint<'tcx>, SubregionOrigin<'tcx>);

/// An index from region variables to their corresponding constraint edges,
/// used on some error paths.
pub(crate) struct IndexedConstraintEdges<'data, 'tcx> {
    out_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
    in_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
}

impl<'data, 'tcx> IndexedConstraintEdges<'data, 'tcx> {
    pub(crate) fn build_index(num_vars: usize, data: &'data RegionConstraintData<'tcx>) -> Self {
        let mut out_edges = IndexVec::from_fn_n(|_| vec![], num_vars);
        let mut in_edges = IndexVec::from_fn_n(|_| vec![], num_vars);

        for pair @ (c, _) in data.constraints.iter() {
            let mut push_in_edge = || out_edges[c.sub.as_var()].push(pair);
            // Only push out-edges if the source is a var.
            match c.kind {
                ConstraintKind::VarSubVar => push_in_edge(),
                ConstraintKind::RegSubVar => {}
                ConstraintKind::VarSubReg => push_in_edge(),
                ConstraintKind::RegSubReg => {}
            }
        }

        // Index in-edges in reverse order, to match what current tests expect.
        // (It's unclear whether this is important or not.)
        for pair @ (c, _) in data.constraints.iter().rev() {
            let mut push_out_edge = || in_edges[c.sup.as_var()].push(pair);
            // Only push in-edges if the target is a var.
            match c.kind {
                ConstraintKind::VarSubVar => push_out_edge(),
                ConstraintKind::RegSubVar => push_out_edge(),
                ConstraintKind::VarSubReg => {}
                ConstraintKind::RegSubReg => {}
            }
        }

        Self { out_edges, in_edges }
    }

Review comment (suggestion):
```suggestion
        for pair @ (c, _) in &data.constraints {
```

Code after:

use crate::infer::SubregionOrigin;
use crate::infer::region_constraints::{Constraint, ConstraintKind, RegionConstraintData};

/// Selects either out-edges or in-edges for [`IndexedConstraintEdges::adjacent_edges`].
#[derive(Clone, Copy, Debug)]
pub(super) enum EdgeDirection {
    Out,
    In,
}

/// Type alias for the pairs stored in [`RegionConstraintData::constraints`],
/// which we are indexing.
type ConstraintPair<'tcx> = (Constraint<'tcx>, SubregionOrigin<'tcx>);

/// An index from region variables to their corresponding constraint edges,
/// used on some error paths.
pub(super) struct IndexedConstraintEdges<'data, 'tcx> {
    out_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
    in_edges: IndexVec<RegionVid, Vec<&'data ConstraintPair<'tcx>>>,
}

impl<'data, 'tcx> IndexedConstraintEdges<'data, 'tcx> {
    pub(super) fn build_index(num_vars: usize, data: &'data RegionConstraintData<'tcx>) -> Self {
        let mut out_edges = IndexVec::from_fn_n(|_| vec![], num_vars);
        let mut in_edges = IndexVec::from_fn_n(|_| vec![], num_vars);

        for pair @ (c, _) in &data.constraints {
            // Only push a var out-edge for `VarSub...` constraints.
            match c.kind {
                ConstraintKind::VarSubVar | ConstraintKind::VarSubReg => {
                    out_edges[c.sub.as_var()].push(pair)
                }
                ConstraintKind::RegSubVar | ConstraintKind::RegSubReg => {}
            }
        }

        // Index in-edges in reverse order, to match what current tests expect.
        // (It's unclear whether this is important or not.)
        for pair @ (c, _) in data.constraints.iter().rev() {
            // Only push a var in-edge for `...SubVar` constraints.
            match c.kind {
                ConstraintKind::VarSubVar | ConstraintKind::RegSubVar => {
                    in_edges[c.sup.as_var()].push(pair)
                }
                ConstraintKind::VarSubReg | ConstraintKind::RegSubReg => {}
            }
        }

        IndexedConstraintEdges { out_edges, in_edges }
    }