Skip to content

Commit 4e706f5

Browse files
committed
[nll] teach SCC about 'static
Fixes #53178
1 parent db01b67 commit 4e706f5

File tree

5 files changed

+71
-13
lines changed

5 files changed

+71
-13
lines changed

Diff for: src/librustc_mir/borrow_check/nll/constraints/graph.rs

+61-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use borrow_check::nll::type_check::Locations;
1112
use borrow_check::nll::constraints::{ConstraintIndex, ConstraintSet, OutlivesConstraint};
1213
use rustc::ty::RegionVid;
1314
use rustc_data_structures::graph;
@@ -31,6 +32,7 @@ crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
3132
crate trait ConstraintGraphDirecton: Copy + 'static {
3233
fn start_region(c: &OutlivesConstraint) -> RegionVid;
3334
fn end_region(c: &OutlivesConstraint) -> RegionVid;
35+
fn is_normal() -> bool;
3436
}
3537

3638
/// In normal mode, a `R1: R2` constraint results in an edge `R1 ->
@@ -48,6 +50,10 @@ impl ConstraintGraphDirecton for Normal {
4850
fn end_region(c: &OutlivesConstraint) -> RegionVid {
4951
c.sub
5052
}
53+
54+
fn is_normal() -> bool {
55+
true
56+
}
5157
}
5258

5359
/// In reverse mode, a `R1: R2` constraint results in an edge `R2 ->
@@ -65,6 +71,10 @@ impl ConstraintGraphDirecton for Reverse {
6571
fn end_region(c: &OutlivesConstraint) -> RegionVid {
6672
c.sup
6773
}
74+
75+
fn is_normal() -> bool {
76+
false
77+
}
6878
}
6979

7080
impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
@@ -98,21 +108,41 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
98108
/// Given the constraint set from which this graph was built
99109
/// creates a region graph so that you can iterate over *regions*
100110
/// and not constraints.
101-
crate fn region_graph<'rg>(&'rg self, set: &'rg ConstraintSet) -> RegionGraph<'rg, D> {
102-
RegionGraph::new(set, self)
111+
crate fn region_graph<'rg>(
112+
&'rg self,
113+
set: &'rg ConstraintSet,
114+
static_region: RegionVid,
115+
) -> RegionGraph<'rg, D> {
116+
RegionGraph::new(set, self, static_region)
103117
}
104118

105119
/// Given a region `R`, iterate over all constraints `R: R1`.
106120
crate fn outgoing_edges<'a>(
107121
&'a self,
108122
region_sup: RegionVid,
109123
constraints: &'a ConstraintSet,
124+
static_region: RegionVid,
110125
) -> Edges<'a, D> {
111-
let first = self.first_constraints[region_sup];
112-
Edges {
113-
graph: self,
114-
constraints,
115-
pointer: first,
126+
//if this is the `'static` region and the graph's direction is normal,
127+
//then setup the Edges iterator to return all regions #53178
128+
if region_sup == static_region && D::is_normal() {
129+
Edges {
130+
graph: self,
131+
constraints,
132+
pointer: None,
133+
next_static_idx: Some(0),
134+
static_region,
135+
}
136+
} else {
137+
//otherwise, just setup the iterator as normal
138+
let first = self.first_constraints[region_sup];
139+
Edges {
140+
graph: self,
141+
constraints,
142+
pointer: first,
143+
next_static_idx: None,
144+
static_region,
145+
}
116146
}
117147
}
118148
}
@@ -121,6 +151,8 @@ crate struct Edges<'s, D: ConstraintGraphDirecton> {
121151
graph: &'s ConstraintGraph<D>,
122152
constraints: &'s ConstraintSet,
123153
pointer: Option<ConstraintIndex>,
154+
next_static_idx: Option<usize>,
155+
static_region: RegionVid,
124156
}
125157

126158
impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
@@ -129,7 +161,21 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
129161
fn next(&mut self) -> Option<Self::Item> {
130162
if let Some(p) = self.pointer {
131163
self.pointer = self.graph.next_constraints[p];
164+
132165
Some(self.constraints[p])
166+
} else if let Some(next_static_idx) = self.next_static_idx {
167+
self.next_static_idx =
168+
if next_static_idx == (self.graph.first_constraints.len() - 1) {
169+
None
170+
} else {
171+
Some(next_static_idx + 1)
172+
};
173+
174+
Some(OutlivesConstraint {
175+
sup: self.static_region,
176+
sub: next_static_idx.into(),
177+
locations: Locations::All,
178+
})
133179
} else {
134180
None
135181
}
@@ -142,25 +188,31 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
142188
crate struct RegionGraph<'s, D: ConstraintGraphDirecton> {
143189
set: &'s ConstraintSet,
144190
constraint_graph: &'s ConstraintGraph<D>,
191+
static_region: RegionVid,
145192
}
146193

147194
impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
148195
/// Create a "dependency graph" where each region constraint `R1:
149196
/// R2` is treated as an edge `R1 -> R2`. We use this graph to
150197
/// construct SCCs for region inference but also for error
151198
/// reporting.
152-
crate fn new(set: &'s ConstraintSet, constraint_graph: &'s ConstraintGraph<D>) -> Self {
199+
crate fn new(
200+
set: &'s ConstraintSet,
201+
constraint_graph: &'s ConstraintGraph<D>,
202+
static_region: RegionVid,
203+
) -> Self {
153204
Self {
154205
set,
155206
constraint_graph,
207+
static_region,
156208
}
157209
}
158210

159211
/// Given a region `R`, iterate over all regions `R1` such that
160212
/// there exists a constraint `R: R1`.
161213
crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'_, D> {
162214
Successors {
163-
edges: self.constraint_graph.outgoing_edges(region_sup, self.set),
215+
edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region),
164216
}
165217
}
166218
}

Diff for: src/librustc_mir/borrow_check/nll/constraints/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ impl ConstraintSet {
5858
crate fn compute_sccs(
5959
&self,
6060
constraint_graph: &graph::NormalConstraintGraph,
61+
static_region: RegionVid,
6162
) -> Sccs<RegionVid, ConstraintSccIndex> {
62-
let region_graph = &constraint_graph.region_graph(self);
63+
let region_graph = &constraint_graph.region_graph(self, static_region);
6364
Sccs::new(region_graph)
6465
}
6566
}

Diff for: src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
201201
// Otherwise, walk over the outgoing constraints and
202202
// enqueue any regions we find, keeping track of how we
203203
// reached them.
204-
for constraint in self.constraint_graph.outgoing_edges(r, &self.constraints) {
204+
let fr_static = self.universal_regions.fr_static;
205+
for constraint in self.constraint_graph.outgoing_edges(r,
206+
&self.constraints,
207+
fr_static) {
205208
assert_eq!(constraint.sup, r);
206209
let sub_region = constraint.sub;
207210
if let Trace::NotVisited = context[sub_region] {

Diff for: src/librustc_mir/borrow_check/nll/region_infer/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
234234

235235
let constraints = Rc::new(outlives_constraints); // freeze constraints
236236
let constraint_graph = Rc::new(constraints.graph(definitions.len()));
237-
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph));
237+
let fr_static = universal_regions.fr_static;
238+
let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
238239

239240
let mut scc_values = RegionValues::new(elements, universal_regions.len(), max_universe);
240241

Diff for: src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ fn regions_that_outlive_free_regions(
6969
// reachable from each free region, we will have all the
7070
// regions that are forced to outlive some free region.
7171
let rev_constraint_graph = constraint_set.reverse_graph(num_region_vars);
72-
let rev_region_graph = rev_constraint_graph.region_graph(constraint_set);
72+
let fr_static = universal_regions.fr_static;
73+
let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static);
7374

7475
// Stack for the depth-first search. Start out with all the free regions.
7576
let mut stack: Vec<_> = universal_regions.universal_regions().collect();

0 commit comments

Comments
 (0)