// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
- // This is a temporary field used for toggling on normalization in the inference context,
- // as we move towards the approach described here:
- // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293
- // At a point sometime in the future normalization will be done by the typing context
- // directly.
- normalize: bool,
-
// Sadly, the behavior of projection varies a bit depending on the
// stage of compilation. The specifics are given in the
// documentation for `Reveal`.
tables: Option<RefCell<ty::Tables<'tcx>>>,
param_env: Option<ty::ParameterEnvironment<'gcx>>,
projection_mode: Reveal,
- normalize: bool
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
tables: tables.map(RefCell::new),
param_env: param_env,
projection_mode: projection_mode,
- normalize: false
- }
- }
-
- pub fn normalizing_infer_ctxt(self, projection_mode: Reveal)
- -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
- InferCtxtBuilder {
- global_tcx: self,
- arenas: ty::CtxtArenas::new(),
- tables: None,
- param_env: None,
- projection_mode: projection_mode,
- normalize: false
}
}
evaluation_cache: traits::EvaluationCache::new(),
projection_cache: RefCell::new(traits::ProjectionCache::new()),
reported_trait_errors: RefCell::new(FnvHashSet()),
- normalize: false,
projection_mode: Reveal::NotSpecializable,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count(),
ref tables,
ref mut param_env,
projection_mode,
- normalize
} = *self;
let tables = if let Some(ref tables) = *tables {
InferTables::Local(tables)
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
reported_trait_errors: RefCell::new(FnvHashSet()),
- normalize: normalize,
projection_mode: projection_mode,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: tcx.sess.err_count(),
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>,
{
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);
}
- };
+ }
+
+ let result = self.resolve_type_vars_if_possible(result);
+ let result = self.tcx.erase_regions(&result);
- match self.tcx.lift_to_global(&v) {
- Some(v) => v,
+ 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<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)?;
-
- let result = self.resolve_type_vars_if_possible(result);
- Ok(self.tcx.erase_regions(&result))
- }
-
pub fn projection_mode(&self) -> Reveal {
self.projection_mode
}
}
let closure_ty = self.tcx.closure_type(def_id, substs);
- if self.normalize {
- let closure_ty = self.tcx.erase_regions(&closure_ty);
-
- if !closure_ty.has_projection_types() {
- return closure_ty;
- }
-
- self.normalize_projections_in(&closure_ty)
- } else {
- closure_ty
- }
+ closure_ty
}
}