Skip to content

Commit ad9e9d9

Browse files
committed
make solving "universe aware", in a simplistic way
This simple change says that if you have a constraint like ``` exists<'a> { for<'b> { 'a: 'b } } ``` you can solve it by making 'a static. This is "good enough" for now, though not super smart, since for example ``` exists<'a> { for<'b> { if ('a: 'b) { 'a: 'b } } } ``` will still force 'a to be 'static, though it should not. (We don't intend to fix that in this PR series; current rustc kind of sidesteps the need to consider such concerns at the moment.)
1 parent 59f3b20 commit ad9e9d9

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

src/librustc/infer/lexical_region_resolve/mod.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@
1212
1313
use infer::SubregionOrigin;
1414
use infer::RegionVariableOrigin;
15-
use infer::region_constraints::Constraint;
16-
use infer::region_constraints::GenericKind;
17-
use infer::region_constraints::RegionConstraintData;
18-
use infer::region_constraints::VarInfos;
19-
use infer::region_constraints::VerifyBound;
15+
use infer::region_constraints::{Constraint, GenericKind, RegionConstraintData,
16+
VarInfos, VerifyBound, region_universe};
2017
use middle::free_region::RegionRelations;
2118
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
2219
use rustc_data_structures::fx::FxHashSet;
@@ -232,11 +229,40 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
232229

233230
match *b_data {
234231
VarValue::Value(cur_region) => {
235-
let lub = self.lub_concrete_regions(a_region, cur_region);
232+
let b_universe = self.var_infos[b_vid].universe;
233+
let mut lub = self.lub_concrete_regions(a_region, cur_region);
236234
if lub == cur_region {
237235
return false;
238236
}
239237

238+
// Find the universe of the new value (`lub`) and
239+
// check whether this value is something that we can
240+
// legally name in this variable. If not, promote the
241+
// variable to `'static`, which is surely greater than
242+
// or equal to `lub`. This is obviously a kind of sub-optimal
243+
// choice -- in the future, when we incorporate a knowledge
244+
// of the parameter environment, we might be able to find a
245+
// tighter bound than `'static`.
246+
//
247+
// To make this more concrete, imagine a bound like:
248+
//
249+
// for<'a> '0: 'a
250+
//
251+
// Here we have that `'0` must outlive `'a` -- no
252+
// matter what `'a` is. When solving such a
253+
// constraint, we would initially assign `'0` to be
254+
// `'empty`. We would then compute the LUB of `'empty`
255+
// and `'a` (which is something like `ReSkolemized(1)`),
256+
// resulting in `'a`.
257+
//
258+
// At this point, `lub_universe` would be `1` and
259+
// `b_universe` would be `0`, and hence we would wind
260+
// up promoting `lub` to `'static`.
261+
let lub_universe = region_universe(&self.var_infos, lub);
262+
if !lub_universe.is_visible_in(b_universe) {
263+
lub = self.region_rels.tcx.types.re_static;
264+
}
265+
240266
debug!(
241267
"Expanding value of {:?} from {:?} to {:?}",
242268
b_vid,

src/librustc/infer/region_constraints/mod.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use std::{cmp, fmt, mem, u32};
3030
mod taint;
3131

3232
pub struct RegionConstraintCollector<'tcx> {
33-
/// For each `RegionVid`, the corresponding `RegionVariableOrigin`.
33+
/// For each `RegionVid`, the corresponding `RegionVariableInfo`.
3434
var_infos: IndexVec<RegionVid, RegionVariableInfo>,
3535

3636
data: RegionConstraintData<'tcx>,
@@ -817,8 +817,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
817817
if let Some(&c) = self.combine_map(t).get(&vars) {
818818
return tcx.mk_region(ReVar(c));
819819
}
820-
let a_universe = self.universe(a);
821-
let b_universe = self.universe(b);
820+
let a_universe = region_universe(&self.var_infos, a);
821+
let b_universe = region_universe(&self.var_infos, b);
822822
let c_universe = cmp::max(a_universe, b_universe);
823823
let c = self.new_region_var(c_universe, MiscVariable(origin.span()));
824824
self.combine_map(t).insert(vars, c);
@@ -836,22 +836,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
836836
new_r
837837
}
838838

839-
fn universe(&self, region: Region<'tcx>) -> ty::UniverseIndex {
840-
match *region {
841-
ty::ReScope(..) |
842-
ty::ReStatic |
843-
ty::ReEmpty |
844-
ty::ReErased |
845-
ty::ReFree(..) |
846-
ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
847-
ty::ReSkolemized(universe, _) => universe,
848-
ty::ReClosureBound(vid) |
849-
ty::ReVar(vid) => self.var_universe(vid),
850-
ty::ReLateBound(..) =>
851-
bug!("universe(): encountered bound region {:?}", region),
852-
}
853-
}
854-
855839
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec<RegionVid> {
856840
self.undo_log[mark.length..]
857841
.iter()
@@ -894,6 +878,22 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
894878
}
895879
}
896880

881+
pub fn region_universe(var_infos: &VarInfos, region: Region<'_>) -> ty::UniverseIndex {
882+
match *region {
883+
ty::ReScope(..) |
884+
ty::ReStatic |
885+
ty::ReEmpty |
886+
ty::ReErased |
887+
ty::ReFree(..) |
888+
ty::ReEarlyBound(..) => ty::UniverseIndex::ROOT,
889+
ty::ReSkolemized(universe, _) => universe,
890+
ty::ReClosureBound(vid) |
891+
ty::ReVar(vid) => var_infos[vid].universe,
892+
ty::ReLateBound(..) =>
893+
bug!("region_universe(): encountered bound region {:?}", region),
894+
}
895+
}
896+
897897
impl fmt::Debug for RegionSnapshot {
898898
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
899899
write!(

src/librustc/ty/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,12 @@ impl UniverseIndex {
13581358
pub fn as_usize(&self) -> usize {
13591359
self.0 as usize
13601360
}
1361+
1362+
/// Indicates whether a name in this universe is visible in the
1363+
/// universe `other`.
1364+
pub fn is_visible_in(self, other: UniverseIndex) -> bool {
1365+
self <= other
1366+
}
13611367
}
13621368

13631369
impl From<u32> for UniverseIndex {

0 commit comments

Comments
 (0)