borrow_graph/
references.rs1use crate::{
5 paths::{self, Path},
6 shared::*,
7};
8use std::{
9 cmp::Ordering,
10 collections::{BTreeMap, BTreeSet},
11 fmt,
12 fmt::Debug,
13};
14
15#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
21pub struct RefID(pub(crate) usize);
22
23impl RefID {
24 pub const fn new(x: usize) -> Self {
26 RefID(x)
27 }
28
29 pub fn number(&self) -> usize {
31 self.0
32 }
33}
34
35#[derive(Clone)]
37pub(crate) struct BorrowEdge<Loc: Copy, Lbl: Clone + Ord> {
38 pub(crate) strong: bool,
41 pub(crate) path: Path<Lbl>,
43 pub(crate) loc: Loc,
45}
46
47#[derive(Clone, Debug, PartialEq, Eq)]
49pub(crate) struct BorrowEdges<Loc: Copy, Lbl: Clone + Ord>(
50 pub(crate) BTreeMap<RefID, BTreeSet<BorrowEdge<Loc, Lbl>>>,
51);
52
53#[derive(Clone, Debug, PartialEq, Eq)]
56pub(crate) struct Ref<Loc: Copy, Lbl: Clone + Ord> {
57 pub(crate) borrowed_by: BorrowEdges<Loc, Lbl>,
60 pub(crate) borrows_from: BTreeSet<RefID>,
65 pub(crate) mutable: bool,
67}
68
69impl<Loc: Copy, Lbl: Clone + Ord> BorrowEdge<Loc, Lbl> {
74 pub(crate) fn leq(&self, other: &Self) -> bool {
75 self == other || (!self.strong && paths::leq(&self.path, &other.path))
76 }
77}
78
79impl<Loc: Copy, Lbl: Clone + Ord> BorrowEdges<Loc, Lbl> {
80 pub(crate) fn new() -> Self {
81 Self(BTreeMap::new())
82 }
83}
84
85impl<Loc: Copy, Lbl: Clone + Ord> Ref<Loc, Lbl> {
86 pub(crate) fn new(mutable: bool) -> Self {
87 let borrowed_by = BorrowEdges::new();
88 let borrows_from = BTreeSet::new();
89 Self {
90 borrowed_by,
91 borrows_from,
92 mutable,
93 }
94 }
95}
96
97impl<Loc: Copy, Lbl: Clone + Ord> BorrowEdges<Loc, Lbl> {
102 pub(crate) fn remap_refs(&mut self, id_map: &BTreeMap<RefID, RefID>) {
105 for (old, new) in id_map {
106 if let Some(edges) = self.0.remove(old) {
107 self.0.insert(*new, edges);
108 }
109 }
110 }
111}
112
113impl<Loc: Copy, Lbl: Clone + Ord> Ref<Loc, Lbl> {
114 pub(crate) fn remap_refs(&mut self, id_map: &BTreeMap<RefID, RefID>) {
117 self.borrowed_by.remap_refs(id_map);
118 remap_set(&mut self.borrows_from, id_map)
119 }
120}
121
122#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
128struct BorrowEdgeNoLoc<'a, Lbl: Clone> {
129 strong: bool,
130 path: &'a Path<Lbl>,
131}
132
133impl<'a, Lbl: Clone + Ord> BorrowEdgeNoLoc<'a, Lbl> {
134 fn new<Loc: Copy>(e: &'a BorrowEdge<Loc, Lbl>) -> Self {
135 BorrowEdgeNoLoc {
136 strong: e.strong,
137 path: &e.path,
138 }
139 }
140}
141
142impl<Loc: Copy, Lbl: Clone + Ord> PartialEq for BorrowEdge<Loc, Lbl> {
143 fn eq(&self, other: &BorrowEdge<Loc, Lbl>) -> bool {
144 BorrowEdgeNoLoc::new(self) == BorrowEdgeNoLoc::new(other)
145 }
146}
147
148impl<Loc: Copy, Lbl: Clone + Ord> Eq for BorrowEdge<Loc, Lbl> {}
149
150impl<Loc: Copy, Lbl: Clone + Ord> PartialOrd for BorrowEdge<Loc, Lbl> {
151 fn partial_cmp(&self, other: &BorrowEdge<Loc, Lbl>) -> Option<Ordering> {
152 BorrowEdgeNoLoc::new(self).partial_cmp(&BorrowEdgeNoLoc::new(other))
153 }
154}
155
156impl<Loc: Copy, Lbl: Clone + Ord> Ord for BorrowEdge<Loc, Lbl> {
157 fn cmp(&self, other: &BorrowEdge<Loc, Lbl>) -> Ordering {
158 BorrowEdgeNoLoc::new(self).cmp(&BorrowEdgeNoLoc::new(other))
159 }
160}
161
162impl<Loc: Copy, Lbl: Clone + Ord + Debug> Debug for BorrowEdge<Loc, Lbl> {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 BorrowEdgeNoLoc::new(self).fmt(f)
165 }
166}