Skip to content

Commit 91c6e9a

Browse files
committed
Switch SCC annotations to a update style; it's more ergonomic
1 parent 5df668a commit 91c6e9a

File tree

3 files changed

+37
-61
lines changed

3 files changed

+37
-61
lines changed

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,10 @@ pub(crate) struct PlaceholderReachability {
7676

7777
impl PlaceholderReachability {
7878
/// Merge the reachable placeholders of two graph components.
79-
fn merge(self, other: PlaceholderReachability) -> PlaceholderReachability {
80-
PlaceholderReachability {
81-
max_universe: self.max_universe.max(other.max_universe),
82-
min_placeholder: self.min_placeholder.min(other.min_placeholder),
83-
max_placeholder: self.max_placeholder.max(other.max_placeholder),
84-
}
79+
fn merge(&mut self, other: &PlaceholderReachability) {
80+
self.max_universe = self.max_universe.max(other.max_universe);
81+
self.min_placeholder = self.min_placeholder.min(other.min_placeholder);
82+
self.max_placeholder = self.max_placeholder.max(other.max_placeholder);
8583
}
8684
}
8785

@@ -192,34 +190,26 @@ impl RegionTracker {
192190
}
193191

194192
impl scc::Annotation for RegionTracker {
195-
fn merge_scc(self, other: Self) -> Self {
193+
fn update_scc(&mut self, other: &Self) {
196194
trace!("{:?} << {:?}", self.representative, other.representative);
197-
Self {
198-
representative: self.representative.min(other.representative),
199-
is_placeholder: self.is_placeholder.max(other.is_placeholder),
200-
..self.merge_reached(other)
201-
}
195+
self.representative = self.representative.min(other.representative);
196+
self.is_placeholder = self.is_placeholder.max(other.is_placeholder);
197+
self.update_reachable(other); // SCC membership implies reachability.
202198
}
203199

204200
#[inline(always)]
205-
fn merge_reached(self, other: Self) -> Self {
206-
Self {
207-
worst_existential: self
208-
.worst_existential
209-
.xor(other.worst_existential)
210-
.or_else(|| self.worst_existential.min(other.worst_existential)),
211-
min_max_nameable_universe: self
212-
.min_max_nameable_universe
213-
.min(other.min_max_nameable_universe),
214-
reachable_placeholders: match (
215-
self.reachable_placeholders,
216-
other.reachable_placeholders,
217-
) {
218-
(None, x) | (x, None) => x,
219-
(Some(ours), Some(theirs)) => Some(ours.merge(theirs)),
220-
},
221-
..self
222-
}
201+
fn update_reachable(&mut self, other: &Self) {
202+
self.worst_existential = self
203+
.worst_existential
204+
.xor(other.worst_existential)
205+
.or_else(|| self.worst_existential.min(other.worst_existential));
206+
self.min_max_nameable_universe =
207+
self.min_max_nameable_universe.min(other.min_max_nameable_universe);
208+
match (self.reachable_placeholders.as_mut(), other.reachable_placeholders.as_ref()) {
209+
(None, None) | (Some(_), None) => (),
210+
(None, Some(theirs)) => self.reachable_placeholders = Some(*theirs),
211+
(Some(ours), Some(theirs)) => ours.merge(theirs),
212+
};
223213
}
224214
}
225215

@@ -461,13 +451,12 @@ pub(crate) fn rewrite_placeholder_outlives<'tcx>(
461451
// inference since `p` isn't empty)
462452
// - another placeholder (will flag an error above, but will reach here).
463453
//
464-
// To avoid adding the invalid constraint "'p: 'static` due to `'p` being
454+
// To avoid adding the invalid constraint "`'p: 'static` due to `'p` being
465455
// unnameable from the SCC represented by `'p`", we nope out early here
466456
// at no risk of soundness issues since at this point all paths lead
467457
// to an error.
468458
continue;
469459
}
470-
471460
// This SCC outlives a placeholder it can't name and must outlive 'static.
472461

473462
// FIXME: if we can extract a useful blame span here, future error

compiler/rustc_data_structures/src/graph/scc/mod.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,18 @@ mod tests;
2727
/// the max/min element of the SCC, or all of the above.
2828
///
2929
/// Concretely, the both merge operations must commute, e.g. where `merge`
30-
/// is `merge_scc` and `merge_reached`: `a.merge(b) == b.merge(a)`
30+
/// is `update_scc` and `update_reached`: `a.merge(b) == b.merge(a)`
3131
///
3232
/// In general, what you want is probably always min/max according
3333
/// to some ordering, potentially with side constraints (min x such
3434
/// that P holds).
3535
pub trait Annotation: Debug + Copy {
3636
/// Merge two existing annotations into one during
37-
/// path compression.o
38-
fn merge_scc(self, other: Self) -> Self;
37+
/// path compression.
38+
fn update_scc(&mut self, other: &Self);
3939

4040
/// Merge a successor into this annotation.
41-
fn merge_reached(self, other: Self) -> Self;
42-
43-
fn update_scc(&mut self, other: Self) {
44-
*self = self.merge_scc(other)
45-
}
46-
47-
fn update_reachable(&mut self, other: Self) {
48-
*self = self.merge_reached(other)
49-
}
41+
fn update_reachable(&mut self, other: &Self);
5042
}
5143

5244
/// An accumulator for annotations.
@@ -70,12 +62,8 @@ impl<N: Idx, S: Idx + Ord> Annotations<N> for NoAnnotations<S> {
7062

7163
/// The empty annotation, which does nothing.
7264
impl Annotation for () {
73-
fn merge_reached(self, _other: Self) -> Self {
74-
()
75-
}
76-
fn merge_scc(self, _other: Self) -> Self {
77-
()
78-
}
65+
fn update_reachable(&mut self, _other: &Self) {}
66+
fn update_scc(&mut self, _other: &Self) {}
7967
}
8068

8169
/// Strongly connected components (SCC) of a graph. The type `N` is
@@ -614,7 +602,7 @@ where
614602
*min_depth = successor_min_depth;
615603
*min_cycle_root = successor_node;
616604
}
617-
current_component_annotation.update_scc(successor_annotation);
605+
current_component_annotation.update_scc(&successor_annotation);
618606
}
619607
// The starting node `node` is succeeded by a fully identified SCC
620608
// which is now added to the set under `scc_index`.
@@ -629,7 +617,7 @@ where
629617
// the `successors_stack` for later.
630618
trace!(?node, ?successor_scc_index);
631619
successors_stack.push(successor_scc_index);
632-
current_component_annotation.update_reachable(successor_annotation);
620+
current_component_annotation.update_reachable(&successor_annotation);
633621
}
634622
// `node` has no more (direct) successors; search recursively.
635623
None => {

compiler/rustc_data_structures/src/graph/scc/tests.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ impl Maxes {
3232
}
3333

3434
impl Annotation for MaxReached {
35-
fn merge_scc(self, other: Self) -> Self {
36-
Self(std::cmp::max(other.0, self.0))
35+
fn update_scc(&mut self, other: &Self) {
36+
self.0 = self.0.max(other.0);
3737
}
3838

39-
fn merge_reached(self, other: Self) -> Self {
40-
Self(std::cmp::max(other.0, self.0))
39+
fn update_reachable(&mut self, other: &Self) {
40+
self.0 = self.0.max(other.0);
4141
}
4242
}
4343

@@ -75,13 +75,12 @@ impl Annotations<usize> for MinMaxes {
7575
}
7676

7777
impl Annotation for MinMaxIn {
78-
fn merge_scc(self, other: Self) -> Self {
79-
Self { min: std::cmp::min(self.min, other.min), max: std::cmp::max(self.max, other.max) }
78+
fn update_scc(&mut self, other: &Self) {
79+
self.min = self.min.min(other.min);
80+
self.max = self.max.max(other.max);
8081
}
8182

82-
fn merge_reached(self, _other: Self) -> Self {
83-
self
84-
}
83+
fn update_reachable(&mut self, _other: &Self) {}
8584
}
8685

8786
#[test]

0 commit comments

Comments
 (0)