Skip to content

Remove the "leak check" in favor of "universes" #48407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
48df576
Revert "change skolemizations to use universe index"
sgrif Mar 6, 2018
50bd71c
Revert "fix tests in `librustc_driver`"
sgrif Mar 6, 2018
5dad682
Revert "fix tidy error"
sgrif Mar 6, 2018
2a94f30
Revert "change skolemizations to use universe index"
sgrif Mar 6, 2018
f6e6d23
Revert "introduce `UniverseIndex` into `ParamEnv`"
sgrif Mar 6, 2018
26d1fc7
Revert "add universes to type inference variables"
sgrif Mar 6, 2018
3d4791b
introduce `UniverseIndex` into `InferCtxt`
sgrif Feb 7, 2018
ff17bd7
add universes to type inference variables
sgrif Feb 7, 2018
66520ff
change skolemizations to use universe index
sgrif Feb 7, 2018
534d5d1
store RegionVariableInfo and not just RegionVariableOrigin
sgrif Feb 7, 2018
59f3b20
give a universe to region variables
sgrif Feb 7, 2018
ad9e9d9
make solving "universe aware", in a simplistic way
sgrif Feb 7, 2018
24478c4
kill higher_ranked_lub and higher_ranked_glb
sgrif Feb 7, 2018
367be87
remove `hr_match` -- no longer needed
nikomatsakis Aug 23, 2017
5aca3b9
move param-env from CombineFields into the individual operations
nikomatsakis Aug 21, 2017
afb4010
Wrap `InferCtxt::universe` in a cell
sgrif Feb 8, 2018
3b8008f
track skol levels in the InferCtxt rather than via counter
sgrif Feb 8, 2018
0bc324a
remove pop_skolemized and friends
sgrif Feb 8, 2018
17e0577
DO NOT MERGE THIS COMMIT
sgrif Mar 6, 2018
bd90fb5
Fix rustdoc breakage
sgrif Mar 6, 2018
725eeb0
[DO NOT MERGE THIS COMMIT] Remove more failing tests
sgrif Mar 7, 2018
3f599ad
Fix rebase issues
sgrif Mar 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,6 @@ for ty::steal::Steal<T>

impl_stable_hash_for!(struct ty::ParamEnv<'tcx> {
caller_bounds,
universe,
reveal
});

Expand Down Expand Up @@ -1237,15 +1236,6 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContex
}
}

impl<'a> HashStable<StableHashingContext<'a>>
for ty::UniverseIndex {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
self.depth().hash_stable(hcx, hasher);
}
}

impl_stable_hash_for!(
impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> {
variables, value
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/infer/anon_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
return anon_defn.concrete_ty;
}
let span = tcx.def_span(def_id);
let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT,
TypeVariableOrigin::TypeInference(span));
let ty_var = infcx.next_ty_var(TypeVariableOrigin::TypeInference(span));

let predicates_of = tcx.predicates_of(def_id);
let bounds = predicates_of.instantiate(tcx, substs);
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
debug!("sub({:?} <: {:?})", a, b);
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env);
fields.sub(a_is_expected)
let mut fields = at.infcx.combine_fields(trace);
fields.sub(at.param_env, a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
})
Expand All @@ -227,8 +227,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
debug!("eq({:?} == {:?})", a, b);
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env);
fields.equate(a_is_expected)
let mut fields = at.infcx.combine_fields(trace);
fields.equate(at.param_env, a_is_expected)
.relate(a, b)
.map(move |_| InferOk { value: (), obligations: fields.obligations })
})
Expand All @@ -243,8 +243,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
debug!("lub({:?} \\/ {:?})", a, b);
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env);
fields.lub(a_is_expected)
let mut fields = at.infcx.combine_fields(trace);
fields.lub(at.param_env, a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
})
Expand All @@ -259,8 +259,8 @@ impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
debug!("glb({:?} /\\ {:?})", a, b);
let Trace { at, trace, a_is_expected } = self;
at.infcx.commit_if_ok(|_| {
let mut fields = at.infcx.combine_fields(trace, at.param_env);
fields.glb(a_is_expected)
let mut fields = at.infcx.combine_fields(trace);
fields.glb(at.param_env, a_is_expected)
.relate(a, b)
.map(move |t| InferOk { value: t, obligations: fields.obligations })
})
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
let ty = match ty_kind {
CanonicalTyVarKind::General => {
self.next_ty_var(
// FIXME(#48696) this handling of universes is not right.
ty::UniverseIndex::ROOT,
TypeVariableOrigin::MiscVariable(span),
)
}
Expand Down
38 changes: 25 additions & 13 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
pub infcx: &'infcx InferCtxt<'infcx, 'gcx, 'tcx>,
pub trace: TypeTrace<'tcx>,
pub cause: Option<ty::relate::Cause>,
pub param_env: ty::ParamEnv<'tcx>,
pub obligations: PredicateObligations<'tcx>,
}

Expand Down Expand Up @@ -159,20 +158,32 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
self.infcx.tcx
}

pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'gcx, 'tcx> {
Equate::new(self, a_is_expected)
pub fn equate<'a>(&'a mut self,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Equate<'a, 'infcx, 'gcx, 'tcx> {
Equate::new(self, param_env, a_is_expected)
}

pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'gcx, 'tcx> {
Sub::new(self, a_is_expected)
pub fn sub<'a>(&'a mut self,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Sub<'a, 'infcx, 'gcx, 'tcx> {
Sub::new(self, param_env, a_is_expected)
}

pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'gcx, 'tcx> {
Lub::new(self, a_is_expected)
pub fn lub<'a>(&'a mut self,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Lub<'a, 'infcx, 'gcx, 'tcx> {
Lub::new(self, param_env, a_is_expected)
}

pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'gcx, 'tcx> {
Glb::new(self, a_is_expected)
pub fn glb<'a>(&'a mut self,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Glb<'a, 'infcx, 'gcx, 'tcx> {
Glb::new(self, param_env, a_is_expected)
}

/// Here dir is either EqTo, SubtypeOf, or SupertypeOf. The
Expand All @@ -185,6 +196,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
/// of `a_ty`. Generalization introduces other inference
/// variables wherever subtyping could occur.
pub fn instantiate(&mut self,
param_env: ty::ParamEnv<'tcx>,
a_ty: Ty<'tcx>,
dir: RelationDir,
b_vid: ty::TyVid,
Expand Down Expand Up @@ -216,7 +228,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {

if needs_wf {
self.obligations.push(Obligation::new(self.trace.cause.clone(),
self.param_env,
param_env,
ty::Predicate::WellFormed(b_ty)));
}

Expand All @@ -227,9 +239,9 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
// to associate causes/spans with each of the relations in
// the stack to get this right.
match dir {
EqTo => self.equate(a_is_expected).relate(&a_ty, &b_ty),
SubtypeOf => self.sub(a_is_expected).relate(&a_ty, &b_ty),
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
EqTo => self.equate(param_env, a_is_expected).relate(&a_ty, &b_ty),
SubtypeOf => self.sub(param_env, a_is_expected).relate(&a_ty, &b_ty),
SupertypeOf => self.sub(param_env, a_is_expected).relate_with_variance(
ty::Contravariant, &a_ty, &b_ty),
}?;

Expand Down
23 changes: 17 additions & 6 deletions src/librustc/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ use ty::relate::{self, Relate, RelateResult, TypeRelation};
pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool,
param_env: ty::ParamEnv<'tcx>,
}

impl<'combine, 'infcx, 'gcx, 'tcx> Equate<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Equate<'combine, 'infcx, 'gcx, 'tcx>
{
Equate { fields: fields, a_is_expected: a_is_expected }
Equate { fields, a_is_expected, param_env }
}
}

Expand Down Expand Up @@ -81,12 +84,20 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
}

(&ty::TyInfer(TyVar(a_id)), _) => {
self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
self.fields.instantiate(self.param_env,
b,
RelationDir::EqTo,
a_id,
self.a_is_expected)?;
Ok(a)
}

(_, &ty::TyInfer(TyVar(b_id))) => {
self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
self.fields.instantiate(self.param_env,
a,
RelationDir::EqTo,
b_id,
self.a_is_expected)?;
Ok(a)
}

Expand All @@ -113,7 +124,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'tcx>
{
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
self.fields.higher_ranked_sub(self.param_env, a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(self.param_env, b, a, self.a_is_expected)
}
}
2 changes: 1 addition & 1 deletion src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

self.check_and_note_conflicting_crates(diag, terr, span);
self.tcx.note_and_explain_type_err(diag, terr, span);
self.tcx.note_and_explain_type_err(diag, terr);

// It reads better to have the error origin as the final
// thing.
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/infer/fudge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFudger<'a, 'gcx, 'tcx> {
// This variable was created during the
// fudging. Recreate it with a fresh variable
// here.
//
// The ROOT universe is fine because we only
// ever invoke this routine at the
// "item-level" of inference.
self.infcx.next_ty_var(ty::UniverseIndex::ROOT, origin)
self.infcx.next_ty_var(origin)
}
}
}
Expand Down
34 changes: 11 additions & 23 deletions src/librustc/infer/glb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ use super::Subtype;

use traits::ObligationCause;
use ty::{self, Ty, TyCtxt};
use ty::error::TypeError;
use ty::relate::{Relate, RelateResult, TypeRelation};

/// "Greatest lower bound" (common subtype)
pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
a_is_expected: bool,
param_env: ty::ParamEnv<'tcx>,
}

impl<'combine, 'infcx, 'gcx, 'tcx> Glb<'combine, 'infcx, 'gcx, 'tcx> {
pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
-> Glb<'combine, 'infcx, 'gcx, 'tcx>
pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
a_is_expected: bool)
-> Glb<'combine, 'infcx, 'gcx, 'tcx>
{
Glb { fields: fields, a_is_expected: a_is_expected }
Glb { fields, a_is_expected, param_env }
}
}

Expand All @@ -48,11 +50,11 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
-> RelateResult<'tcx, T>
{
match variance {
ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
ty::Invariant => self.fields.equate(self.param_env, self.a_is_expected).relate(a, b),
ty::Covariant => self.relate(a, b),
// FIXME(#41044) -- not correct, need test
ty::Bivariant => Ok(a.clone()),
ty::Contravariant => self.fields.lub(self.a_is_expected).relate(a, b),
ty::Contravariant => self.fields.lub(self.param_env, self.a_is_expected).relate(a, b),
}
}

Expand All @@ -76,29 +78,15 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
where T: Relate<'tcx>
{
debug!("binders(a={:?}, b={:?})", a, b);
let was_error = self.infcx().probe(|_snapshot| {
// Subtle: use a fresh combine-fields here because we recover
// from Err. Doing otherwise could propagate obligations out
// through our `self.obligations` field.
self.infcx()
.combine_fields(self.fields.trace.clone(), self.fields.param_env)
.higher_ranked_glb(a, b, self.a_is_expected)
.is_err()
});
debug!("binders: was_error={:?}", was_error);

// When higher-ranked types are involved, computing the LUB is
// very challenging, switch to invariance. This is obviously
// overly conservative but works ok in practice.
match self.relate_with_variance(ty::Variance::Invariant, a, b) {
Ok(_) => Ok(a.clone()),
Err(err) => {
debug!("binders: error occurred, was_error={:?}", was_error);
if !was_error {
Err(TypeError::OldStyleLUB(Box::new(err)))
} else {
Err(err)
}
debug!("binders: error occurred");
Err(err)
}
}
}
Expand All @@ -116,7 +104,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx>
}

fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
let mut sub = self.fields.sub(self.a_is_expected);
let mut sub = self.fields.sub(self.param_env, self.a_is_expected);
sub.relate(&v, &a)?;
sub.relate(&v, &b)?;
Ok(())
Expand Down
Loading