Merge branch 'refactor-select' of https://github.com/aravind-pg/rust into update-cargo

This commit is contained in:
Alex Crichton 2018-03-06 18:03:04 -08:00
commit 8121db3340
2 changed files with 39 additions and 84 deletions

View File

@ -851,19 +851,6 @@ impl<'tcx, N> Vtable<'tcx, N> {
}
}
fn nested_obligations_mut(&mut self) -> &mut Vec<N> {
match self {
&mut VtableImpl(ref mut i) => &mut i.nested,
&mut VtableParam(ref mut n) => n,
&mut VtableBuiltin(ref mut i) => &mut i.nested,
&mut VtableAutoImpl(ref mut d) => &mut d.nested,
&mut VtableGenerator(ref mut c) => &mut c.nested,
&mut VtableClosure(ref mut c) => &mut c.nested,
&mut VtableObject(ref mut d) => &mut d.nested,
&mut VtableFnPointer(ref mut d) => &mut d.nested,
}
}
pub fn map<M, F>(self, f: F) -> Vtable<'tcx, M> where F: FnMut(N) -> M {
match self {
VtableImpl(i) => VtableImpl(VtableImplData {

View File

@ -44,12 +44,10 @@ use ty::relate::TypeRelation;
use middle::lang_items;
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
use std::iter;
use std::cell::RefCell;
use std::cmp;
use std::fmt;
use std::marker::PhantomData;
use std::mem;
use std::rc::Rc;
use syntax::abi::Abi;
@ -57,14 +55,6 @@ use hir;
use lint;
use util::nodemap::{FxHashMap, FxHashSet};
struct InferredObligationsSnapshotVecDelegate<'tcx> {
phantom: PhantomData<&'tcx i32>,
}
impl<'tcx> SnapshotVecDelegate for InferredObligationsSnapshotVecDelegate<'tcx> {
type Value = PredicateObligation<'tcx>;
type Undo = ();
fn reverse(_: &mut Vec<Self::Value>, _: Self::Undo) {}
}
pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
@ -92,8 +82,6 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
/// would satisfy it. This avoids crippling inference, basically.
intercrate: Option<IntercrateMode>,
inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
/// Controls whether or not to filter out negative impls when selecting.
@ -429,7 +417,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: None,
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
}
@ -442,7 +429,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: Some(mode),
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
}
@ -455,7 +441,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
infcx,
freshener: infcx.freshener(),
intercrate: None,
inferred_obligations: SnapshotVec::new(),
intercrate_ambiguity_causes: None,
allow_negative_impls,
}
@ -498,8 +483,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn in_snapshot<R, F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
{
// The irrefutable nature of the operation means we don't need to snapshot the
// inferred_obligations vector.
self.infcx.in_snapshot(|snapshot| f(self, snapshot))
}
@ -508,10 +491,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn probe<R, F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self, &infer::CombinedSnapshot<'cx, 'tcx>) -> R
{
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
let result = self.infcx.probe(|snapshot| f(self, snapshot));
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
result
self.infcx.probe(|snapshot| f(self, snapshot))
}
/// Wraps a commit_if_ok s.t. obligations collected during it are not returned in selection if
@ -519,17 +499,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn commit_if_ok<T, E, F>(&mut self, f: F) -> Result<T, E> where
F: FnOnce(&mut Self, &infer::CombinedSnapshot) -> Result<T, E>
{
let inferred_obligations_snapshot = self.inferred_obligations.start_snapshot();
match self.infcx.commit_if_ok(|snapshot| f(self, snapshot)) {
Ok(ok) => {
self.inferred_obligations.commit(inferred_obligations_snapshot);
Ok(ok)
},
Err(err) => {
self.inferred_obligations.rollback_to(inferred_obligations_snapshot);
Err(err)
}
}
self.infcx.commit_if_ok(|snapshot| f(self, snapshot))
}
@ -560,12 +530,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
let ret = match self.candidate_from_obligation(&stack)? {
None => None,
Some(candidate) => {
let mut candidate = self.confirm_candidate(obligation, candidate)?;
let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
candidate.nested_obligations_mut().extend(inferred_obligations);
Some(candidate)
},
Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?)
};
// Test whether this is a `()` which was produced by defaulting a
@ -658,7 +623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
stack: TraitObligationStackList<'o, 'tcx>,
predicates: I)
-> EvaluationResult
where I : Iterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
{
let mut result = EvaluatedToOk;
for obligation in predicates {
@ -695,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// does this code ever run?
match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
Some(Ok(InferOk { obligations, .. })) => {
self.inferred_obligations.extend(obligations);
self.evaluate_predicates_recursively(previous_stack, &obligations);
EvaluatedToOk
},
Some(Err(_)) => EvaluatedToErr,
@ -1542,12 +1507,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
-> bool
{
assert!(!skol_trait_ref.has_escaping_regions());
match self.infcx.at(&obligation.cause, obligation.param_env)
.sup(ty::Binder(skol_trait_ref), trait_bound) {
Ok(InferOk { obligations, .. }) => {
self.inferred_obligations.extend(obligations);
}
Err(_) => { return false; }
if let Err(_) = self.infcx.at(&obligation.cause, obligation.param_env)
.sup(ty::Binder(skol_trait_ref), trait_bound) {
return false;
}
self.infcx.leak_check(false, obligation.cause.span, skol_map, snapshot).is_ok()
@ -2633,6 +2595,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
};
let mut upcast_trait_ref = None;
let mut nested = vec![];
let vtable_base;
{
@ -2651,7 +2614,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.commit_if_ok(
|this, _| this.match_poly_trait_ref(obligation, t))
{
Ok(_) => { upcast_trait_ref = Some(t); false }
Ok(obligations) => {
upcast_trait_ref = Some(t);
nested.extend(obligations);
false
}
Err(_) => { true }
}
});
@ -2669,7 +2636,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
VtableObjectData {
upcast_trait_ref: upcast_trait_ref.unwrap(),
vtable_base,
nested: vec![]
nested,
}
}
@ -2726,7 +2693,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
let Normalized {
value: trait_ref,
obligations
mut obligations
} = normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
@ -2738,10 +2705,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
trait_ref,
obligations);
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?;
obligations.extend(
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?);
Ok(VtableGeneratorData {
closure_def_id: closure_def_id,
@ -2787,10 +2755,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
trait_ref,
obligations);
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?;
obligations.extend(
self.confirm_poly_trait_refs(obligation.cause.clone(),
obligation.param_env,
obligation.predicate.to_poly_trait_ref(),
trait_ref)?);
obligations.push(Obligation::new(
obligation.cause.clone(),
@ -2834,13 +2803,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
obligation_param_env: ty::ParamEnv<'tcx>,
obligation_trait_ref: ty::PolyTraitRef<'tcx>,
expected_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<(), SelectionError<'tcx>>
-> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>
{
let obligation_trait_ref = obligation_trait_ref.clone();
self.infcx
.at(&obligation_cause, obligation_param_env)
.sup(obligation_trait_ref, expected_trait_ref)
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
.map(|InferOk { obligations, .. }| obligations)
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
}
@ -2877,7 +2846,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_trait)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Register one obligation for 'a: 'b.
let cause = ObligationCause::new(obligation.cause.span,
@ -2939,7 +2908,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(b, a)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
}
// Struct<T> -> Struct<U>.
@ -3003,7 +2972,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_struct)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Construct the nested Field<T>: Unsize<Field<U>> predicate.
nested.push(tcx.predicate_for_trait_def(
@ -3034,7 +3003,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_tuple)
.map_err(|_| Unimplemented)?;
self.inferred_obligations.extend(obligations);
nested.extend(obligations);
// Construct the nested T: Unsize<U> predicate.
nested.push(tcx.predicate_for_trait_def(
@ -3107,7 +3076,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
impl_substs);
let impl_trait_ref =
let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
project::normalize_with_depth(self,
obligation.param_env,
obligation.cause.clone(),
@ -3123,12 +3092,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let InferOk { obligations, .. } =
self.infcx.at(&obligation.cause, obligation.param_env)
.eq(skol_obligation_trait_ref, impl_trait_ref.value)
.eq(skol_obligation_trait_ref, impl_trait_ref)
.map_err(|e| {
debug!("match_impl: failed eq_trait_refs due to `{}`", e);
()
})?;
self.inferred_obligations.extend(obligations);
nested_obligations.extend(obligations);
if let Err(e) = self.infcx.leak_check(false,
obligation.cause.span,
@ -3141,7 +3110,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
debug!("match_impl: success impl_substs={:?}", impl_substs);
Ok((Normalized {
value: impl_substs,
obligations: impl_trait_ref.obligations
obligations: nested_obligations
}, skol_map))
}
@ -3178,8 +3147,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<Vec<PredicateObligation<'tcx>>,()>
{
self.match_poly_trait_ref(obligation, where_clause_trait_ref)?;
Ok(Vec::new())
self.match_poly_trait_ref(obligation, where_clause_trait_ref)
}
/// Returns `Ok` if `poly_trait_ref` being true implies that the
@ -3187,7 +3155,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn match_poly_trait_ref(&mut self,
obligation: &TraitObligation<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<(),()>
-> Result<Vec<PredicateObligation<'tcx>>,()>
{
debug!("match_poly_trait_ref: obligation={:?} poly_trait_ref={:?}",
obligation,
@ -3195,7 +3163,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx.at(&obligation.cause, obligation.param_env)
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
.map(|InferOk { obligations, .. }| self.inferred_obligations.extend(obligations))
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| ())
}