Skip to content

Commit 826d8f3

Browse files
committed
Auto merge of #41914 - eddyb:region-refactor, r=nikomatsakis
rustc: simpler ParameterEnvironment and free regions. The commits describe the slow transformation but the highlights are: * `ReEarlyBound` is considered free, with a scope based on the item that defined the lifetime parameter, and the root body of the `RegionMaps` in use, removing the need for `free_substs` * `liberate_late_bound_regions` and `implicit_region_bound` moved to typeck * `CodeExtent` not interned at all now - ideally it would be 2 `u32` but it's small anyway Future work building up on this could include: * `ParameterEnvironment` becoming just the result of `predicates_of` * interning makes my "parent chain" scheme unnecessary * `implicit_region_bound` could be retrieved from `RegionMaps` * renaming `CodeExtent` to `Scope` * generalizing "call site" to "use site" or something better to include constants * renaming `RegionMaps` to `ScopeTree` and its API to talk about "parents" explicitly
2 parents 77f1bec + 6da4123 commit 826d8f3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+707
-1100
lines changed

Diff for: src/librustc/cfg/construct.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use rustc_data_structures::graph;
1212
use cfg::*;
13+
use middle::region::CodeExtent;
1314
use ty::{self, TyCtxt};
1415
use syntax::ast;
1516
use syntax::ptr::P;
@@ -586,8 +587,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
586587
scope_id: ast::NodeId,
587588
to_index: CFGIndex) {
588589
let mut data = CFGEdgeData { exiting_scopes: vec![] };
589-
let mut scope = self.tcx.node_extent(from_expr.id);
590-
let target_scope = self.tcx.node_extent(scope_id);
590+
let mut scope = CodeExtent::Misc(from_expr.id);
591+
let target_scope = CodeExtent::Misc(scope_id);
591592
let region_maps = self.tcx.region_maps(self.owner_def_id);
592593
while scope != target_scope {
593594
data.exiting_scopes.push(scope.node_id());

Diff for: src/librustc/ich/impls_ty.rs

+11-16
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'t
3939
}
4040
}
4141

42-
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionKind<'tcx> {
42+
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionKind {
4343
fn hash_stable<W: StableHasherResult>(&self,
4444
hcx: &mut StableHashingContext<'a, 'tcx>,
4545
hasher: &mut StableHasher<W>) {
@@ -54,7 +54,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionKind<'tc
5454
db.depth.hash_stable(hcx, hasher);
5555
i.hash_stable(hcx, hasher);
5656
}
57-
ty::ReEarlyBound(ty::EarlyBoundRegion { index, name }) => {
57+
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
58+
def_id.hash_stable(hcx, hasher);
5859
index.hash_stable(hcx, hasher);
5960
name.hash_stable(hcx, hasher);
6061
}
@@ -409,11 +410,6 @@ impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
409410
Free(call_site_scope_data, decl)
410411
});
411412

412-
impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData {
413-
fn_id,
414-
body_id
415-
});
416-
417413
impl_stable_hash_for!(struct ty::DebruijnIndex {
418414
depth
419415
});
@@ -432,25 +428,24 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
432428
FnPtrAddrCast
433429
});
434430

435-
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtentData
431+
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtent
436432
{
437433
fn hash_stable<W: StableHasherResult>(&self,
438434
hcx: &mut StableHashingContext<'a, 'tcx>,
439435
hasher: &mut StableHasher<W>) {
440-
use middle::region::CodeExtentData;
436+
use middle::region::CodeExtent;
441437

442438
mem::discriminant(self).hash_stable(hcx, hasher);
443439
match *self {
444-
CodeExtentData::Misc(node_id) |
445-
CodeExtentData::DestructionScope(node_id) => {
440+
CodeExtent::Misc(node_id) |
441+
CodeExtent::DestructionScope(node_id) => {
446442
node_id.hash_stable(hcx, hasher);
447443
}
448-
CodeExtentData::CallSiteScope { fn_id, body_id } |
449-
CodeExtentData::ParameterScope { fn_id, body_id } => {
450-
fn_id.hash_stable(hcx, hasher);
444+
CodeExtent::CallSiteScope(body_id) |
445+
CodeExtent::ParameterScope(body_id) => {
451446
body_id.hash_stable(hcx, hasher);
452447
}
453-
CodeExtentData::Remainder(block_remainder) => {
448+
CodeExtent::Remainder(block_remainder) => {
454449
block_remainder.hash_stable(hcx, hasher);
455450
}
456451
}
@@ -466,7 +461,7 @@ impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
466461
custom_kind
467462
});
468463

469-
impl_stable_hash_for!(struct ty::FreeRegion<'tcx> {
464+
impl_stable_hash_for!(struct ty::FreeRegion {
470465
scope,
471466
bound_region
472467
});

Diff for: src/librustc/infer/combine.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -423,15 +423,6 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
423423
return Ok(r);
424424
}
425425

426-
// Early-bound regions should really have been substituted away before
427-
// we get to this point.
428-
ty::ReEarlyBound(..) => {
429-
span_bug!(
430-
self.span,
431-
"Encountered early bound region when generalizing: {:?}",
432-
r);
433-
}
434-
435426
// Always make a fresh region variable for skolemized regions;
436427
// the higher-ranked decision procedures rely on this.
437428
ty::ReSkolemized(..) => { }
@@ -442,6 +433,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
442433
ty::ReStatic |
443434
ty::ReScope(..) |
444435
ty::ReVar(..) |
436+
ty::ReEarlyBound(..) |
445437
ty::ReFree(..) => {
446438
match self.ambient_variance {
447439
ty::Invariant => return Ok(r),

Diff for: src/librustc/infer/error_reporting/mod.rs

+34-19
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
151151
return;
152152
}
153153
};
154-
let scope_decorated_tag = match *scope {
155-
region::CodeExtentData::Misc(_) => tag,
156-
region::CodeExtentData::CallSiteScope { .. } => {
154+
let scope_decorated_tag = match scope {
155+
region::CodeExtent::Misc(_) => tag,
156+
region::CodeExtent::CallSiteScope(_) => {
157157
"scope of call-site for function"
158158
}
159-
region::CodeExtentData::ParameterScope { .. } => {
159+
region::CodeExtent::ParameterScope(_) => {
160160
"scope of function body"
161161
}
162-
region::CodeExtentData::DestructionScope(_) => {
162+
region::CodeExtent::DestructionScope(_) => {
163163
new_string = format!("destruction scope surrounding {}", tag);
164164
&new_string[..]
165165
}
166-
region::CodeExtentData::Remainder(r) => {
166+
region::CodeExtent::Remainder(r) => {
167167
new_string = format!("block suffix following statement {}",
168168
r.first_statement_index);
169169
&new_string[..]
@@ -172,19 +172,35 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
172172
explain_span(self, scope_decorated_tag, span)
173173
}
174174

175-
ty::ReFree(ref fr) => {
176-
let prefix = match fr.bound_region {
177-
ty::BrAnon(idx) => {
178-
format!("the anonymous lifetime #{} defined on", idx + 1)
175+
ty::ReEarlyBound(_) |
176+
ty::ReFree(_) => {
177+
let scope = match *region {
178+
ty::ReEarlyBound(ref br) => {
179+
self.parent_def_id(br.def_id).unwrap()
179180
}
180-
ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
181-
_ => {
182-
format!("the lifetime {} as defined on",
183-
fr.bound_region)
181+
ty::ReFree(ref fr) => fr.scope,
182+
_ => bug!()
183+
};
184+
let prefix = match *region {
185+
ty::ReEarlyBound(ref br) => {
186+
format!("the lifetime {} as defined on", br.name)
187+
}
188+
ty::ReFree(ref fr) => {
189+
match fr.bound_region {
190+
ty::BrAnon(idx) => {
191+
format!("the anonymous lifetime #{} defined on", idx + 1)
192+
}
193+
ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
194+
_ => {
195+
format!("the lifetime {} as defined on",
196+
fr.bound_region)
197+
}
198+
}
184199
}
200+
_ => bug!()
185201
};
186202

187-
let node = fr.scope.map(|s| s.node_id())
203+
let node = self.hir.as_local_node_id(scope)
188204
.unwrap_or(DUMMY_NODE_ID);
189205
let unknown;
190206
let tag = match self.hir.find(node) {
@@ -199,12 +215,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
199215
Some(_) => {
200216
unknown = format!("unexpected node ({}) for scope {:?}. \
201217
Please report a bug.",
202-
self.hir.node_to_string(node), fr.scope);
218+
self.hir.node_to_string(node), scope);
203219
&unknown
204220
}
205221
None => {
206222
unknown = format!("unknown node for scope {:?}. \
207-
Please report a bug.", fr.scope);
223+
Please report a bug.", scope);
208224
&unknown
209225
}
210226
};
@@ -216,8 +232,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
216232

217233
ty::ReEmpty => ("the empty lifetime".to_owned(), None),
218234

219-
ty::ReEarlyBound(ref data) => (data.name.to_string(), None),
220-
221235
// FIXME(#13998) ReSkolemized should probably print like
222236
// ReFree rather than dumping Debug output on the user.
223237
//
@@ -797,6 +811,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
797811
}
798812

799813
let mut err = match *sub {
814+
ty::ReEarlyBound(_) |
800815
ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
801816
// Does the required lifetime have a nice name we can print?
802817
let mut err = struct_span_err!(self.tcx.sess,

Diff for: src/librustc/infer/freshen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
8585

8686
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
8787
match *r {
88-
ty::ReEarlyBound(..) |
8988
ty::ReLateBound(..) => {
9089
// leave bound regions alone
9190
r
9291
}
9392

9493
ty::ReStatic |
94+
ty::ReEarlyBound(..) |
9595
ty::ReFree(_) |
9696
ty::ReScope(_) |
9797
ty::ReVar(_) |

Diff for: src/librustc/infer/higher_ranked/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
274274
-> ty::Region<'tcx> {
275275
// Regions that pre-dated the LUB computation stay as they are.
276276
if !is_var_in_set(new_vars, r0) {
277-
assert!(!r0.is_bound());
277+
assert!(!r0.is_late_bound());
278278
debug!("generalize_region(r0={:?}): not new variable", r0);
279279
return r0;
280280
}
@@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
288288
debug!("generalize_region(r0={:?}): \
289289
non-new-variables found in {:?}",
290290
r0, tainted);
291-
assert!(!r0.is_bound());
291+
assert!(!r0.is_late_bound());
292292
return r0;
293293
}
294294

@@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
371371
r0: ty::Region<'tcx>)
372372
-> ty::Region<'tcx> {
373373
if !is_var_in_set(new_vars, r0) {
374-
assert!(!r0.is_bound());
374+
assert!(!r0.is_late_bound());
375375
return r0;
376376
}
377377

@@ -424,7 +424,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
424424
return rev_lookup(infcx, span, a_map, a_r.unwrap());
425425
} else if a_r.is_none() && b_r.is_none() {
426426
// Not related to bound variables from either fn:
427-
assert!(!r0.is_bound());
427+
assert!(!r0.is_late_bound());
428428
return r0;
429429
} else {
430430
// Other:

Diff for: src/librustc/infer/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -450,10 +450,10 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
450450
-> (Option<&'a ty::TypeckTables<'tcx>>,
451451
Option<ty::TypeckTables<'tcx>>,
452452
Option<ty::ParameterEnvironment<'tcx>>) {
453-
let item_id = tcx.hir.body_owner(self);
454-
(Some(tcx.typeck_tables_of(tcx.hir.local_def_id(item_id))),
453+
let def_id = tcx.hir.body_owner_def_id(self);
454+
(Some(tcx.typeck_tables_of(def_id)),
455455
None,
456-
Some(ty::ParameterEnvironment::for_item(tcx, item_id)))
456+
Some(tcx.parameter_environment(def_id)))
457457
}
458458
}
459459

@@ -1009,7 +1009,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10091009
}
10101010

10111011
pub fn add_given(&self,
1012-
sub: ty::FreeRegion<'tcx>,
1012+
sub: ty::Region<'tcx>,
10131013
sup: ty::RegionVid)
10141014
{
10151015
self.region_vars.add_given(sub, sup);
@@ -1324,7 +1324,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13241324

13251325
pub fn resolve_regions_and_report_errors(&self,
13261326
region_context: DefId,
1327-
region_map: &RegionMaps<'tcx>,
1327+
region_map: &RegionMaps,
13281328
free_regions: &FreeRegionMap<'tcx>) {
13291329
let region_rels = RegionRelations::new(self.tcx,
13301330
region_context,

Diff for: src/librustc/infer/region_inference/graphviz.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -124,20 +124,20 @@ struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
124124
graph_name: String,
125125
region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
126126
map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
127-
node_ids: FxHashMap<Node<'tcx>, usize>,
127+
node_ids: FxHashMap<Node, usize>,
128128
}
129129

130130
#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
131-
enum Node<'tcx> {
131+
enum Node {
132132
RegionVid(ty::RegionVid),
133-
Region(ty::RegionKind<'tcx>),
133+
Region(ty::RegionKind),
134134
}
135135

136136
// type Edge = Constraint;
137137
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
138138
enum Edge<'tcx> {
139139
Constraint(Constraint<'tcx>),
140-
EnclScope(CodeExtent<'tcx>, CodeExtent<'tcx>),
140+
EnclScope(CodeExtent, CodeExtent),
141141
}
142142

143143
impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
@@ -176,7 +176,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
176176
}
177177

178178
impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
179-
type Node = Node<'tcx>;
179+
type Node = Node;
180180
type Edge = Edge<'tcx>;
181181
fn graph_id(&self) -> dot::Id {
182182
dot::Id::new(&*self.graph_name).unwrap()
@@ -209,7 +209,7 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
209209
}
210210
}
211211

212-
fn constraint_to_nodes<'tcx>(c: &Constraint<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
212+
fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
213213
match *c {
214214
Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
215215
(Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
@@ -222,7 +222,7 @@ fn constraint_to_nodes<'tcx>(c: &Constraint<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
222222
}
223223
}
224224

225-
fn edge_to_nodes<'tcx>(e: &Edge<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
225+
fn edge_to_nodes(e: &Edge) -> (Node, Node) {
226226
match *e {
227227
Edge::Constraint(ref c) => constraint_to_nodes(c),
228228
Edge::EnclScope(sub, sup) => {
@@ -233,9 +233,9 @@ fn edge_to_nodes<'tcx>(e: &Edge<'tcx>) -> (Node<'tcx>, Node<'tcx>) {
233233
}
234234

235235
impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
236-
type Node = Node<'tcx>;
236+
type Node = Node;
237237
type Edge = Edge<'tcx>;
238-
fn nodes(&self) -> dot::Nodes<Node<'tcx>> {
238+
fn nodes(&self) -> dot::Nodes<Node> {
239239
let mut set = FxHashSet();
240240
for node in self.node_ids.keys() {
241241
set.insert(*node);
@@ -250,12 +250,12 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
250250
debug!("region graph has {} edges", v.len());
251251
Cow::Owned(v)
252252
}
253-
fn source(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
253+
fn source(&self, edge: &Edge<'tcx>) -> Node {
254254
let (n1, _) = edge_to_nodes(edge);
255255
debug!("edge {:?} has source {:?}", edge, n1);
256256
n1
257257
}
258-
fn target(&self, edge: &Edge<'tcx>) -> Node<'tcx> {
258+
fn target(&self, edge: &Edge<'tcx>) -> Node {
259259
let (_, n2) = edge_to_nodes(edge);
260260
debug!("edge {:?} has target {:?}", edge, n2);
261261
n2

0 commit comments

Comments
 (0)