Skip to content

Commit 2da080e

Browse files
committed
rustc: treat ReEarlyBound as free without replacing it with ReFree.
1 parent dbae169 commit 2da080e

File tree

35 files changed

+248
-332
lines changed

35 files changed

+248
-332
lines changed

src/librustc/ich/impls_ty.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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
}

src/librustc/infer/combine.rs

Lines changed: 1 addition & 9 deletions
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),

src/librustc/infer/error_reporting/mod.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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 = self.hir.as_local_node_id(fr.scope)
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,

src/librustc/infer/freshen.rs

Lines changed: 1 addition & 1 deletion
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(_) |

src/librustc/infer/higher_ranked/mod.rs

Lines changed: 4 additions & 4 deletions
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:

src/librustc/infer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10091009
}
10101010

10111011
pub fn add_given(&self,
1012-
sub: ty::FreeRegion,
1012+
sub: ty::Region<'tcx>,
10131013
sup: ty::RegionVid)
10141014
{
10151015
self.region_vars.add_given(sub, sup);

src/librustc/infer/region_inference/mod.rs

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound, ReErased};
2929
use ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
3030

3131
use std::cell::{Cell, RefCell};
32-
use std::cmp::Ordering::{self, Less, Greater, Equal};
3332
use std::fmt;
3433
use std::mem;
3534
use std::u32;
@@ -127,7 +126,7 @@ pub enum UndoLogEntry<'tcx> {
127126
AddVerify(usize),
128127

129128
/// We added the given `given`
130-
AddGiven(ty::FreeRegion, ty::RegionVid),
129+
AddGiven(Region<'tcx>, ty::RegionVid),
131130

132131
/// We added a GLB/LUB "combinaton variable"
133132
AddCombination(CombineMapType, TwoRegions<'tcx>),
@@ -213,7 +212,7 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
213212
// record the fact that `'a <= 'b` is implied by the fn signature,
214213
// and then ignore the constraint when solving equations. This is
215214
// a bit of a hack but seems to work.
216-
givens: RefCell<FxHashSet<(ty::FreeRegion, ty::RegionVid)>>,
215+
givens: RefCell<FxHashSet<(Region<'tcx>, ty::RegionVid)>>,
217216

218217
lubs: RefCell<CombineMap<'tcx>>,
219218
glbs: RefCell<CombineMap<'tcx>>,
@@ -309,8 +308,7 @@ impl<'a, 'gcx, 'tcx> TaintSet<'tcx> {
309308
self.add_edge(a, b);
310309
}
311310
&AddGiven(a, b) => {
312-
self.add_edge(tcx.mk_region(ReFree(a)),
313-
tcx.mk_region(ReVar(b)));
311+
self.add_edge(a, tcx.mk_region(ReVar(b)));
314312
}
315313
&AddVerify(i) => {
316314
verifys[i].bound.for_each_region(&mut |b| {
@@ -661,7 +659,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
661659
}
662660
}
663661

664-
pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
662+
pub fn add_given(&self, sub: Region<'tcx>, sup: ty::RegionVid) {
665663
// cannot add givens once regions are resolved
666664
assert!(self.values_are_none());
667665

@@ -702,9 +700,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
702700
origin);
703701

704702
match (sub, sup) {
705-
(&ReEarlyBound(..), _) |
706703
(&ReLateBound(..), _) |
707-
(_, &ReEarlyBound(..)) |
708704
(_, &ReLateBound(..)) => {
709705
span_bug!(origin.span(),
710706
"cannot relate bound region: {:?} <= {:?}",
@@ -908,8 +904,6 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
908904
match (a, b) {
909905
(&ReLateBound(..), _) |
910906
(_, &ReLateBound(..)) |
911-
(&ReEarlyBound(..), _) |
912-
(_, &ReEarlyBound(..)) |
913907
(&ReErased, _) |
914908
(_, &ReErased) => {
915909
bug!("cannot relate region: LUB({:?}, {:?})", a, b);
@@ -931,18 +925,32 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
931925
b);
932926
}
933927

934-
(&ReFree(ref fr), &ReScope(s_id)) |
935-
(&ReScope(s_id), &ReFree(ref fr)) => {
928+
(&ReEarlyBound(_), &ReScope(s_id)) |
929+
(&ReScope(s_id), &ReEarlyBound(_)) |
930+
(&ReFree(_), &ReScope(s_id)) |
931+
(&ReScope(s_id), &ReFree(_)) => {
936932
// A "free" region can be interpreted as "some region
937933
// at least as big as fr.scope". So, we can
938934
// reasonably compare free regions and scopes:
939-
let fr_scope = region_rels.region_maps.free_extent(self.tcx, fr);
935+
let fr_scope = match (a, b) {
936+
(&ReEarlyBound(ref br), _) | (_, &ReEarlyBound(ref br)) => {
937+
region_rels.region_maps.early_free_extent(self.tcx, br)
938+
}
939+
(&ReFree(ref fr), _) | (_, &ReFree(ref fr)) => {
940+
region_rels.region_maps.free_extent(self.tcx, fr)
941+
}
942+
_ => bug!()
943+
};
940944
let r_id = region_rels.region_maps.nearest_common_ancestor(fr_scope, s_id);
941945
if r_id == fr_scope {
942946
// if the free region's scope `fr.scope` is bigger than
943947
// the scope region `s_id`, then the LUB is the free
944948
// region itself:
945-
return self.tcx.mk_region(ReFree(*fr));
949+
match (a, b) {
950+
(_, &ReScope(_)) => return a,
951+
(&ReScope(_), _) => return b,
952+
_ => bug!()
953+
}
946954
}
947955

948956
// otherwise, we don't know what the free region is,
@@ -958,6 +966,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
958966
self.tcx.mk_region(ReScope(lub))
959967
}
960968

969+
(&ReEarlyBound(_), &ReEarlyBound(_)) |
970+
(&ReFree(_), &ReEarlyBound(_)) |
971+
(&ReEarlyBound(_), &ReFree(_)) |
961972
(&ReFree(_), &ReFree(_)) => {
962973
region_rels.lub_free_regions(a, b)
963974
}
@@ -1040,13 +1051,13 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
10401051

10411052
let mut givens = self.givens.borrow_mut();
10421053
let seeds: Vec<_> = givens.iter().cloned().collect();
1043-
for (fr, vid) in seeds {
1054+
for (r, vid) in seeds {
10441055
let seed_index = NodeIndex(vid.index as usize);
10451056
for succ_index in graph.depth_traverse(seed_index, OUTGOING) {
10461057
let succ_index = succ_index.0 as u32;
10471058
if succ_index < self.num_vars() {
10481059
let succ_vid = RegionVid { index: succ_index };
1049-
givens.insert((fr, succ_vid));
1060+
givens.insert((r, succ_vid));
10501061
}
10511062
}
10521063
}
@@ -1095,8 +1106,9 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
10951106

10961107
// Check if this relationship is implied by a given.
10971108
match *a_region {
1098-
ty::ReFree(fr) => {
1099-
if self.givens.borrow().contains(&(fr, b_vid)) {
1109+
ty::ReEarlyBound(_) |
1110+
ty::ReFree(_) => {
1111+
if self.givens.borrow().contains(&(a_region, b_vid)) {
11001112
debug!("given");
11011113
return false;
11021114
}
@@ -1332,16 +1344,15 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
13321344
// We place free regions first because we are special casing
13331345
// SubSupConflict(ReFree, ReFree) when reporting error, and so
13341346
// the user will more likely get a specific suggestion.
1335-
fn free_regions_first(a: &RegionAndOrigin, b: &RegionAndOrigin) -> Ordering {
1336-
match (a.region, b.region) {
1337-
(&ReFree(..), &ReFree(..)) => Equal,
1338-
(&ReFree(..), _) => Less,
1339-
(_, &ReFree(..)) => Greater,
1340-
(..) => Equal,
1347+
fn region_order_key(x: &RegionAndOrigin) -> u8 {
1348+
match *x.region {
1349+
ReEarlyBound(_) => 0,
1350+
ReFree(_) => 1,
1351+
_ => 2
13411352
}
13421353
}
1343-
lower_bounds.sort_by(|a, b| free_regions_first(a, b));
1344-
upper_bounds.sort_by(|a, b| free_regions_first(a, b));
1354+
lower_bounds.sort_by_key(region_order_key);
1355+
upper_bounds.sort_by_key(region_order_key);
13451356

13461357
for lower_bound in &lower_bounds {
13471358
for upper_bound in &upper_bounds {

0 commit comments

Comments
 (0)