Skip to content

Commit d9afd2b

Browse files
committed
introduce new subtyping
1 parent b913df0 commit d9afd2b

File tree

16 files changed

+1016
-121
lines changed

16 files changed

+1016
-121
lines changed

src/librustc/dep_graph/graph.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ pub struct DepGraph {
3939
fingerprints: Lrc<Lock<IndexVec<DepNodeIndex, Fingerprint>>>
4040
}
4141

42-
4342
newtype_index!(DepNodeIndex);
4443

4544
impl DepNodeIndex {

src/librustc/infer/higher_ranked/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
617617
debug!("leak_check: skol_map={:?}",
618618
skol_map);
619619

620+
// If the user gave `-Zno-leak-check`, then skip the leak
621+
// check completely. This is wildly unsound and also not
622+
// unlikely to cause an ICE or two. It is intended for use
623+
// only during a transition period, in which the MIR typeck
624+
// uses the "universe-style" check, and the rest of typeck
625+
// uses the more conservative leak check. Since the leak
626+
// check is more conservative, we can't test the
627+
// universe-style check without disabling it.
628+
if self.tcx.sess.opts.debugging_opts.no_leak_check {
629+
return Ok(());
630+
}
631+
620632
let new_vars = self.region_vars_confined_to_snapshot(snapshot);
621633
for (&skol_br, &skol) in skol_map {
622634
// The inputs to a skolemized variable can only

src/librustc/infer/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,16 @@ pub enum NLLRegionVariableOrigin {
377377
// elsewhere. This origin indices we've got one of those.
378378
FreeRegion,
379379

380+
BoundRegion(ty::UniverseIndex),
381+
380382
Existential,
381383
}
382384

383385
impl NLLRegionVariableOrigin {
384386
pub fn is_universal(self) -> bool {
385387
match self {
386388
NLLRegionVariableOrigin::FreeRegion => true,
389+
NLLRegionVariableOrigin::BoundRegion(..) => true,
387390
NLLRegionVariableOrigin::Existential => false,
388391
}
389392
}
@@ -1394,6 +1397,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13941397
fn universe(&self) -> ty::UniverseIndex {
13951398
self.universe.get()
13961399
}
1400+
1401+
/// Create and return a new subunivese of the current universe;
1402+
/// update `self.universe` to that new subuniverse. At present,
1403+
/// used only in the NLL subtyping code, which uses the new
1404+
/// universe-based scheme instead of the more limited leak-check
1405+
/// scheme.
1406+
pub fn create_subuniverse(&self) -> ty::UniverseIndex {
1407+
let u = self.universe.get().subuniverse();
1408+
self.universe.set(u);
1409+
u
1410+
}
13971411
}
13981412

13991413
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {

src/librustc/session/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
13531353
"generate build artifacts that are compatible with linker-based LTO."),
13541354
no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
13551355
"don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
1356+
no_leak_check: bool = (false, parse_bool, [UNTRACKED],
1357+
"disables the 'leak check' for subtyping; unsound, but useful for tests"),
13561358
}
13571359

13581360
pub fn default_lib_output() -> CrateType {

src/librustc/ty/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,14 +1481,27 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
14811481
/// type name in a non-zero universe is a skolemized type -- an
14821482
/// idealized representative of "types in general" that we use for
14831483
/// checking generic functions.
1484-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
1484+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
14851485
pub struct UniverseIndex(u32);
14861486

14871487
impl UniverseIndex {
14881488
/// The root universe, where things that the user defined are
14891489
/// visible.
14901490
pub const ROOT: Self = UniverseIndex(0);
14911491

1492+
/// The "max universe" -- this isn't really a valid universe, but
1493+
/// it's useful sometimes as a "starting value" when you are
1494+
/// taking the minimum of a (non-empty!) set of universes.
1495+
pub const MAX: Self = UniverseIndex(::std::u32::MAX);
1496+
1497+
/// Creates a universe index from the given integer. Not to be
1498+
/// used lightly lest you pick a bad value. But sometimes we
1499+
/// convert universe indicies into integers and back for various
1500+
/// reasons.
1501+
pub fn from_u32(index: u32) -> Self {
1502+
UniverseIndex(index)
1503+
}
1504+
14921505
/// A "subuniverse" corresponds to being inside a `forall` quantifier.
14931506
/// So, for example, suppose we have this type in universe `U`:
14941507
///
@@ -1504,6 +1517,11 @@ impl UniverseIndex {
15041517
UniverseIndex(self.0.checked_add(1).unwrap())
15051518
}
15061519

1520+
/// True if the names in this universe are a subset of the names in `other`.
1521+
pub fn is_subset_of(self, other: UniverseIndex) -> bool {
1522+
self.0 <= other.0
1523+
}
1524+
15071525
pub fn as_u32(&self) -> u32 {
15081526
self.0
15091527
}
@@ -1513,6 +1531,12 @@ impl UniverseIndex {
15131531
}
15141532
}
15151533

1534+
impl fmt::Debug for UniverseIndex {
1535+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1536+
write!(fmt, "U{}", self.as_u32())
1537+
}
1538+
}
1539+
15161540
impl From<u32> for UniverseIndex {
15171541
fn from(index: u32) -> Self {
15181542
UniverseIndex(index)

src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//! state of region inference. This code handles emitting the region
1414
//! context internal state.
1515
16+
use rustc::infer::NLLRegionVariableOrigin;
1617
use std::io::{self, Write};
1718
use super::{OutlivesConstraint, RegionInferenceContext};
1819

@@ -27,8 +28,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
2728
writeln!(out, "| Free Region Mapping")?;
2829

2930
for region in self.regions() {
30-
if self.definitions[region].origin.is_universal() {
31-
let classification = self.universal_regions
31+
if let NLLRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
32+
let classification = self
33+
.universal_regions
3234
.region_classification(region)
3335
.unwrap();
3436
let outlived_by = self.universal_regions.regions_outlived_by(region);
@@ -49,9 +51,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
4951
for region in self.regions() {
5052
writeln!(
5153
out,
52-
"| {r:rw$} | {v}",
54+
"| {r:rw$} | {ui:4?} | {v}",
5355
r = format!("{:?}", region),
5456
rw = REGION_WIDTH,
57+
ui = self.region_universe(region),
5558
v = self.region_value_str(region),
5659
)?;
5760
}

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
401401
// `elem`.
402402
crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid {
403403
// Find all paths
404-
let (_path, r) = self
405-
.find_constraint_paths_between_regions(fr1, |r| {
404+
let (_path, r) =
405+
self.find_constraint_paths_between_regions(fr1, |r| {
406406
self.liveness_constraints.contains(r, elem)
407-
})
408-
.unwrap();
407+
}).unwrap();
409408
r
410409
}
411410

412411
// Finds a good span to blame for the fact that `fr1` outlives `fr2`.
413-
crate fn find_outlives_blame_span(&self, mir: &Mir<'tcx>, fr1: RegionVid, fr2: RegionVid) -> Span {
412+
crate fn find_outlives_blame_span(
413+
&self,
414+
mir: &Mir<'tcx>,
415+
fr1: RegionVid,
416+
fr2: RegionVid,
417+
) -> Span {
414418
let (_, span, _) = self.best_blame_constraint(mir, fr1, |r| r == fr2);
415419
span
416420
}

0 commit comments

Comments
 (0)