simplify DepNode for trait selection
This commit is contained in:
parent
b44d94a516
commit
4eb7362c2c
@ -132,7 +132,7 @@ pub enum DepNode<D: Clone + Debug> {
|
||||
// which would yield an overly conservative dep-graph.
|
||||
TraitItems(D),
|
||||
ReprHints(D),
|
||||
TraitSelect(D, Vec<D>),
|
||||
TraitSelect(Vec<D>),
|
||||
}
|
||||
|
||||
impl<D: Clone + Debug> DepNode<D> {
|
||||
@ -237,10 +237,9 @@ impl<D: Clone + Debug> DepNode<D> {
|
||||
TraitImpls(ref d) => op(d).map(TraitImpls),
|
||||
TraitItems(ref d) => op(d).map(TraitItems),
|
||||
ReprHints(ref d) => op(d).map(ReprHints),
|
||||
TraitSelect(ref d, ref type_ds) => {
|
||||
let d = try_opt!(op(d));
|
||||
TraitSelect(ref type_ds) => {
|
||||
let type_ds = try_opt!(type_ds.iter().map(|d| op(d)).collect());
|
||||
Some(TraitSelect(d, type_ds))
|
||||
Some(TraitSelect(type_ds))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -670,6 +670,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
self.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
|
||||
}
|
||||
|
||||
/// Finishes processes any obligations that remain in the
|
||||
/// fulfillment context, and then returns the result with all type
|
||||
/// variables removed and regions erased. Because this is intended
|
||||
/// for use after type-check has completed, if any errors occur,
|
||||
/// it will panic. It is used during normalization and other cases
|
||||
/// where processing the obligations in `fulfill_cx` may cause
|
||||
/// type inference variables that appear in `result` to be
|
||||
/// unified, and hence we need to process those obligations to get
|
||||
/// the complete picture of the type.
|
||||
pub fn drain_fulfillment_cx_or_panic<T>(&self,
|
||||
span: Span,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
@ -679,45 +688,26 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
{
|
||||
debug!("drain_fulfillment_cx_or_panic()");
|
||||
|
||||
let when = "resolving bounds after type-checking";
|
||||
let v = match self.drain_fulfillment_cx(fulfill_cx, result) {
|
||||
Ok(v) => v,
|
||||
Err(errors) => {
|
||||
span_bug!(span, "Encountered errors `{:?}` {}", errors, when);
|
||||
}
|
||||
};
|
||||
|
||||
match self.tcx.lift_to_global(&v) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
span_bug!(span, "Uninferred types/regions in `{:?}` {}", v, when);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Finishes processes any obligations that remain in the fulfillment
|
||||
/// context, and then "freshens" and returns `result`. This is
|
||||
/// primarily used during normalization and other cases where
|
||||
/// processing the obligations in `fulfill_cx` may cause type
|
||||
/// inference variables that appear in `result` to be unified, and
|
||||
/// hence we need to process those obligations to get the complete
|
||||
/// picture of the type.
|
||||
pub fn drain_fulfillment_cx<T>(&self,
|
||||
fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
|
||||
result: &T)
|
||||
-> Result<T,Vec<traits::FulfillmentError<'tcx>>>
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
debug!("drain_fulfillment_cx(result={:?})",
|
||||
result);
|
||||
|
||||
// In principle, we only need to do this so long as `result`
|
||||
// contains unbound type parameters. It could be a slight
|
||||
// optimization to stop iterating early.
|
||||
fulfill_cx.select_all_or_error(self)?;
|
||||
match fulfill_cx.select_all_or_error(self) {
|
||||
Ok(()) => { }
|
||||
Err(errors) => {
|
||||
span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking",
|
||||
errors);
|
||||
}
|
||||
}
|
||||
|
||||
let result = self.resolve_type_vars_if_possible(result);
|
||||
Ok(self.tcx.erase_regions(&result))
|
||||
let result = self.tcx.erase_regions(&result);
|
||||
|
||||
match self.tcx.lift_to_global(&result) {
|
||||
Some(result) => result,
|
||||
None => {
|
||||
span_bug!(span, "Uninferred types/regions in `{:?}`", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn projection_mode(&self) -> Reveal {
|
||||
|
@ -958,8 +958,9 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||
_ =>
|
||||
None
|
||||
})
|
||||
.chain(iter::once(self.def_id()))
|
||||
.collect();
|
||||
DepNode::TraitSelect(self.def_id(), def_ids)
|
||||
DepNode::TraitSelect(def_ids)
|
||||
}
|
||||
|
||||
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
|
||||
|
@ -1028,7 +1028,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fulfill_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
|
||||
fulfill_cx.select_all_or_error(infcx).is_ok()
|
||||
fulfill_cx.select_all_or_error(&infcx).is_ok()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,11 @@ pub fn apply_param_substs<'a, 'tcx, T>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
-> T
|
||||
where T: TransNormalize<'tcx>
|
||||
{
|
||||
debug!("apply_param_substs(param_substs={:?}, value={:?})", param_substs, value);
|
||||
let substituted = value.subst(tcx, param_substs);
|
||||
debug!("apply_param_substs: substituted={:?}{}",
|
||||
substituted,
|
||||
if substituted.has_projection_types() { " [needs projection]" } else { "" });
|
||||
tcx.normalize_associated_type(&substituted)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user