From 4eb7362c2c8e614b25aa7daa286805ce1382c6af Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 8 Aug 2016 09:40:12 -0400 Subject: [PATCH] simplify DepNode for trait selection --- src/librustc/dep_graph/dep_node.rs | 7 ++-- src/librustc/infer/mod.rs | 56 ++++++++++++------------------ src/librustc/ty/mod.rs | 3 +- src/librustc_trans/common.rs | 2 +- src/librustc_trans/monomorphize.rs | 4 +++ 5 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index e95fbcc8917..18179027c25 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -132,7 +132,7 @@ pub enum DepNode { // which would yield an overly conservative dep-graph. TraitItems(D), ReprHints(D), - TraitSelect(D, Vec), + TraitSelect(Vec), } impl DepNode { @@ -237,10 +237,9 @@ pub fn map_def(&self, mut op: OP) -> Option> 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)) } } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 37c2a8f0d2c..836e52ea45a 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -670,6 +670,15 @@ fn normalize_projections_in(&self, value: &T) -> T::Lifted 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(&self, span: Span, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, @@ -679,47 +688,28 @@ pub fn drain_fulfillment_cx_or_panic(&self, { 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, + // 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. + match fulfill_cx.select_all_or_error(self) { + Ok(()) => { } Err(errors) => { - span_bug!(span, "Encountered errors `{:?}` {}", errors, when); + span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking", + errors); } - }; + } - match self.tcx.lift_to_global(&v) { - Some(v) => v, + let result = self.resolve_type_vars_if_possible(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 `{:?}` {}", v, when); + span_bug!(span, "Uninferred types/regions in `{:?}`", result); } } } - /// 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(&self, - fulfill_cx: &mut traits::FulfillmentContext<'tcx>, - result: &T) - -> Result>> - 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)?; - - let result = self.resolve_type_vars_if_possible(result); - Ok(self.tcx.erase_regions(&result)) - } - pub fn projection_mode(&self) -> Reveal { self.projection_mode } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 1ea82a9c639..a00ea8de7e7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -958,8 +958,9 @@ fn dep_node(&self) -> DepNode { _ => 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> + 'a { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 95a38cd21d9..9758fc07446 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -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() }) } diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 0ffb83067f9..4dd5797a318 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -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) } -- GitLab