// 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`.
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
/// region that each late-bound region was replaced with.
-pub type SkolemizationMap = FnvHashMap<ty::BoundRegion, ty::Region>;
+pub type SkolemizationMap<'tcx> = FnvHashMap<ty::BoundRegion, &'tcx ty::Region>;
/// Why did we require that the two types be related?
///
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
}
pub fn sub_regions(&self,
origin: SubregionOrigin<'tcx>,
- a: ty::Region,
- b: ty::Region) {
+ a: &'tcx ty::Region,
+ b: &'tcx ty::Region) {
debug!("sub_regions({:?} <: {:?})", a, b);
self.region_vars.make_subregion(origin, a, b);
}
pub fn region_outlives_predicate(&self,
span: Span,
- predicate: &ty::PolyRegionOutlivesPredicate)
+ predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
-> UnitResult<'tcx>
{
self.commit_if_ok(|snapshot| {
.new_key(None)
}
- pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
- ty::ReVar(self.region_vars.new_region_var(origin))
+ pub fn next_region_var(&self, origin: RegionVariableOrigin)
+ -> &'tcx ty::Region {
+ self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
}
/// Create a region inference variable for the given
pub fn region_var_for_def(&self,
span: Span,
def: &ty::RegionParameterDef)
- -> ty::Region {
+ -> &'tcx ty::Region {
self.next_region_var(EarlyBoundRegion(span, def.name))
}
})
}
- pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
+ pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region {
self.region_vars.new_bound(debruijn)
}
span: Span,
lbrct: LateBoundRegionConversionTime,
value: &ty::Binder<T>)
- -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
+ -> (T, FnvHashMap<ty::BoundRegion, &'tcx ty::Region>)
where T : TypeFoldable<'tcx>
{
self.tcx.replace_late_bound_regions(
pub fn verify_generic_bound(&self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
- a: ty::Region,
- bound: VerifyBound) {
+ a: &'tcx ty::Region,
+ bound: VerifyBound<'tcx>) {
debug!("verify_generic_bound({:?}, {:?} <: {:?})",
kind,
a,
self.tcx.region_maps.temporary_scope(rvalue_id)
}
- pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
+ pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
}
}
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
}
}