use hir::def_id::DefId;
use hir;
-use middle::free_region::FreeRegionMap;
+use middle::free_region::{FreeRegionMap, RegionRelations};
+use middle::region::RegionMaps;
use middle::mem_categorization as mc;
use middle::mem_categorization::McResult;
use middle::lang_items;
use ty::{self, Ty, TyCtxt};
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use ty::relate::{Relate, RelateResult, TypeRelation};
+use ty::relate::RelateResult;
use traits::{self, ObligationCause, PredicateObligations, Reveal};
use rustc_data_structures::unify::{self, UnificationTable};
use std::cell::{Cell, RefCell, Ref, RefMut};
use self::type_variable::TypeVariableOrigin;
use self::unify_key::ToType;
+pub mod at;
mod combine;
mod equate;
pub mod error_reporting;
// For region variables.
region_vars: RegionVarBindings<'a, 'gcx, 'tcx>,
- pub parameter_environment: ty::ParameterEnvironment<'gcx>,
-
/// Caches the results of trait selection. This cache is used
/// for things that have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache<'tcx>,
// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FxHashSet<traits::TraitErrorKey<'tcx>>>,
- // Sadly, the behavior of projection varies a bit depending on the
- // stage of compilation. The specifics are given in the
- // documentation for `Reveal`.
- projection_mode: Reveal,
-
// When an error occurs, we want to avoid reporting "derived"
// errors that are due to this original failure. Normally, we
// handle this with the `err_count_on_creation` count, which
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
/// region that each late-bound region was replaced with.
-pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
+pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, ty::Region<'tcx>>;
/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
pub trait InferEnv<'a, 'tcx> {
fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>);
+ Option<ty::TypeckTables<'tcx>>);
}
impl<'a, 'tcx> InferEnv<'a, 'tcx> for () {
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>) {
- (None, None, None)
- }
-}
-
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::ParameterEnvironment<'tcx> {
- fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
- -> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>) {
- (None, None, Some(self))
+ Option<ty::TypeckTables<'tcx>>) {
+ (None, None)
}
}
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for (&'a ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for &'a ty::TypeckTables<'tcx> {
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>) {
- (Some(self.0), None, Some(self.1))
+ Option<ty::TypeckTables<'tcx>>) {
+ (Some(self), None)
}
}
-impl<'a, 'tcx> InferEnv<'a, 'tcx> for (ty::TypeckTables<'tcx>, ty::ParameterEnvironment<'tcx>) {
+impl<'a, 'tcx> InferEnv<'a, 'tcx> for ty::TypeckTables<'tcx> {
fn to_parts(self, _: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>) {
- (None, Some(self.0), Some(self.1))
+ Option<ty::TypeckTables<'tcx>>) {
+ (None, Some(self))
}
}
impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
fn to_parts(self, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> (Option<&'a ty::TypeckTables<'tcx>>,
- Option<ty::TypeckTables<'tcx>>,
- Option<ty::ParameterEnvironment<'tcx>>) {
- let item_id = tcx.hir.body_owner(self);
- (Some(tcx.item_tables(tcx.hir.local_def_id(item_id))),
- None,
- Some(ty::ParameterEnvironment::for_item(tcx, item_id)))
+ Option<ty::TypeckTables<'tcx>>) {
+ let def_id = tcx.hir.body_owner_def_id(self);
+ (Some(tcx.typeck_tables_of(def_id)), None)
}
}
arena: DroplessArena,
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
tables: Option<&'a ty::TypeckTables<'gcx>>,
- param_env: Option<ty::ParameterEnvironment<'gcx>>,
- projection_mode: Reveal,
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
- pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self,
- env: E,
- projection_mode: Reveal)
- -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
- let (tables, fresh_tables, param_env) = env.to_parts(self);
+ pub fn infer_ctxt<E: InferEnv<'a, 'gcx>>(self, env: E) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
+ let (tables, fresh_tables) = env.to_parts(self);
InferCtxtBuilder {
global_tcx: self,
arena: DroplessArena::new(),
fresh_tables: fresh_tables.map(RefCell::new),
tables: tables,
- param_env: param_env,
- projection_mode: projection_mode,
}
}
/// If any inference functionality is used, ICEs will occur.
pub fn borrowck_fake_infer_ctxt(self, body: hir::BodyId)
-> InferCtxt<'a, 'gcx, 'gcx> {
- let (tables, _, param_env) = body.to_parts(self);
+ let (tables, _) = body.to_parts(self);
InferCtxt {
tcx: self,
tables: InferTables::Interned(tables.unwrap()),
int_unification_table: RefCell::new(UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(self),
- parameter_environment: param_env.unwrap(),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
projection_cache: RefCell::new(traits::ProjectionCache::new()),
reported_trait_errors: RefCell::new(FxHashSet()),
- projection_mode: Reveal::UserFacing,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: self.sess.err_count(),
in_snapshot: Cell::new(false),
ref arena,
ref fresh_tables,
tables,
- ref mut param_env,
- projection_mode,
} = *self;
let tables = tables.map(InferTables::Interned).unwrap_or_else(|| {
fresh_tables.as_ref().map_or(InferTables::Missing, InferTables::InProgress)
});
- let param_env = param_env.take().unwrap_or_else(|| {
- global_tcx.empty_parameter_environment()
- });
global_tcx.enter_local(arena, |tcx| f(InferCtxt {
tcx: tcx,
tables: tables,
int_unification_table: RefCell::new(UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(tcx),
- parameter_environment: param_env,
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
reported_trait_errors: RefCell::new(FxHashSet()),
- projection_mode: projection_mode,
tainted_by_errors_flag: Cell::new(false),
err_count_on_creation: tcx.sess.err_count(),
in_snapshot: Cell::new(false),
}
#[must_use = "once you start a snapshot, you should always consume it"]
-pub struct CombinedSnapshot {
+pub struct CombinedSnapshot<'a, 'tcx:'a> {
projection_cache_snapshot: traits::ProjectionCacheSnapshot,
type_snapshot: type_variable::Snapshot,
int_snapshot: unify::Snapshot<ty::IntVid>,
float_snapshot: unify::Snapshot<ty::FloatVid>,
region_vars_snapshot: RegionSnapshot,
was_in_snapshot: bool,
+ _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
}
/// Helper trait for shortening the lifetimes inside a
/// value for post-type-checking normalization.
pub trait TransNormalize<'gcx>: TypeFoldable<'gcx> {
- fn trans_normalize<'a, 'tcx>(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>) -> Self;
+ fn trans_normalize<'a, 'tcx>(&self,
+ infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>)
+ -> Self;
}
macro_rules! items { ($($item:item)+) => ($($item)+) }
($lt_gcx:tt, $($ty:ty),+) => {
items!($(impl<$lt_gcx> TransNormalize<$lt_gcx> for $ty {
fn trans_normalize<'a, 'tcx>(&self,
- infcx: &InferCtxt<'a, $lt_gcx, 'tcx>)
+ infcx: &InferCtxt<'a, $lt_gcx, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>)
-> Self {
- infcx.normalize_projections_in(self)
+ infcx.normalize_projections_in(param_env, self)
}
})+);
}
);
impl<'gcx> TransNormalize<'gcx> for LvalueTy<'gcx> {
- fn trans_normalize<'a, 'tcx>(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>) -> Self {
+ fn trans_normalize<'a, 'tcx>(&self,
+ infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+ param_env: ty::ParamEnv<'tcx>)
+ -> Self {
match *self {
- LvalueTy::Ty { ty } => LvalueTy::Ty { ty: ty.trans_normalize(infcx) },
+ LvalueTy::Ty { ty } => LvalueTy::Ty { ty: ty.trans_normalize(infcx, param_env) },
LvalueTy::Downcast { adt_def, substs, variant_index } => {
LvalueTy::Downcast {
adt_def: adt_def,
- substs: substs.trans_normalize(infcx),
+ substs: substs.trans_normalize(infcx, param_env),
variant_index: variant_index
}
}
self.normalize_associated_type(&value)
}
+ /// Fully normalizes any associated types in `value`, using an
+ /// empty environment and `Reveal::All` mode (therefore, suitable
+ /// only for monomorphized code during trans, basically).
pub fn normalize_associated_type<T>(self, value: &T) -> T
where T: TransNormalize<'tcx>
{
debug!("normalize_associated_type(t={:?})", value);
+ let param_env = ty::ParamEnv::empty(Reveal::All);
let value = self.erase_regions(value);
if !value.has_projection_types() {
return value;
}
- self.infer_ctxt((), Reveal::All).enter(|infcx| {
- value.trans_normalize(&infcx)
+ self.infer_ctxt(()).enter(|infcx| {
+ value.trans_normalize(&infcx, param_env)
})
}
+ /// Does a best-effort to normalize any associated types in
+ /// `value`; this includes revealing specializable types, so this
+ /// should be not be used during type-checking, but only during
+ /// optimization and code generation.
pub fn normalize_associated_type_in_env<T>(
- self, value: &T, env: &'a ty::ParameterEnvironment<'tcx>
+ self, value: &T, env: ty::ParamEnv<'tcx>
) -> T
where T: TransNormalize<'tcx>
{
return value;
}
- self.infer_ctxt(env.clone(), Reveal::All).enter(|infcx| {
- value.trans_normalize(&infcx)
+ self.infer_ctxt(()).enter(|infcx| {
+ value.trans_normalize(&infcx, env.reveal_all())
})
}
}
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
- fn normalize_projections_in<T>(&self, value: &T) -> T::Lifted
+ fn normalize_projections_in<T>(&self, param_env: ty::ParamEnv<'tcx>, value: &T) -> T::Lifted
where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
{
let mut selcx = traits::SelectionContext::new(self);
let cause = traits::ObligationCause::dummy();
let traits::Normalized { value: result, obligations } =
- traits::normalize(&mut selcx, cause, value);
+ traits::normalize(&mut selcx, param_env, cause, value);
debug!("normalize_projections_in: result={:?} obligations={:?}",
result, obligations);
}
}
- pub fn projection_mode(&self) -> Reveal {
- self.projection_mode
- }
-
pub fn is_in_snapshot(&self) -> bool {
self.in_snapshot.get()
}
return variables;
}
- fn combine_fields(&'a self, trace: TypeTrace<'tcx>)
+ fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)
-> CombineFields<'a, 'gcx, 'tcx> {
CombineFields {
infcx: self,
trace: trace,
cause: None,
+ param_env,
obligations: PredicateObligations::new(),
}
}
- pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
- -> InferResult<'tcx, T>
- where T: Relate<'tcx>
- {
- let mut fields = self.combine_fields(trace);
- let result = fields.equate(a_is_expected).relate(a, b);
- result.map(move |t| InferOk { value: t, obligations: fields.obligations })
- }
-
- pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
- -> InferResult<'tcx, T>
- where T: Relate<'tcx>
- {
- let mut fields = self.combine_fields(trace);
- let result = fields.sub(a_is_expected).relate(a, b);
- result.map(move |t| InferOk { value: t, obligations: fields.obligations })
- }
-
- pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
- -> InferResult<'tcx, T>
- where T: Relate<'tcx>
- {
- let mut fields = self.combine_fields(trace);
- let result = fields.lub(a_is_expected).relate(a, b);
- result.map(move |t| InferOk { value: t, obligations: fields.obligations })
- }
-
- pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
- -> InferResult<'tcx, T>
- where T: Relate<'tcx>
- {
- let mut fields = self.combine_fields(trace);
- let result = fields.glb(a_is_expected).relate(a, b);
- result.map(move |t| InferOk { value: t, obligations: fields.obligations })
- }
-
// Clear the "currently in a snapshot" flag, invoke the closure,
// then restore the flag to its original value. This flag is a
// debugging measure designed to detect cases where we start a
result
}
- fn start_snapshot(&self) -> CombinedSnapshot {
+ fn start_snapshot<'b>(&'b self) -> CombinedSnapshot<'b, 'tcx> {
debug!("start_snapshot()");
let in_snapshot = self.in_snapshot.get();
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
region_vars_snapshot: self.region_vars.start_snapshot(),
was_in_snapshot: in_snapshot,
+ // Borrow tables "in progress" (i.e. during typeck)
+ // to ban writes from within a snapshot to them.
+ _in_progress_tables: match self.tables {
+ InferTables::InProgress(ref tables) => tables.try_borrow().ok(),
+ _ => None
+ }
}
}
int_snapshot,
float_snapshot,
region_vars_snapshot,
- was_in_snapshot } = snapshot;
+ was_in_snapshot,
+ _in_progress_tables } = snapshot;
self.in_snapshot.set(was_in_snapshot);
int_snapshot,
float_snapshot,
region_vars_snapshot,
- was_in_snapshot } = snapshot;
+ was_in_snapshot,
+ _in_progress_tables } = snapshot;
self.in_snapshot.set(was_in_snapshot);
}
pub fn add_given(&self,
- sub: ty::FreeRegion,
+ sub: ty::Region<'tcx>,
sup: ty::RegionVid)
{
self.region_vars.add_given(sub, sup);
}
- pub fn sub_types(&self,
- a_is_expected: bool,
- cause: &ObligationCause<'tcx>,
- a: Ty<'tcx>,
- b: Ty<'tcx>)
- -> InferResult<'tcx, ()>
- {
- debug!("sub_types({:?} <: {:?})", a, b);
- self.commit_if_ok(|_| {
- let trace = TypeTrace::types(cause, a_is_expected, a, b);
- self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
- })
- }
-
- pub fn can_sub_types(&self,
- a: Ty<'tcx>,
- b: Ty<'tcx>)
- -> UnitResult<'tcx>
+ pub fn can_sub<T>(&self,
+ param_env: ty::ParamEnv<'tcx>,
+ a: T,
+ b: T)
+ -> UnitResult<'tcx>
+ where T: at::ToTrace<'tcx>
{
+ let origin = &ObligationCause::dummy();
self.probe(|_| {
- let origin = &ObligationCause::dummy();
- let trace = TypeTrace::types(origin, true, a, b);
- self.sub(true, trace, &a, &b).map(|InferOk { obligations: _, .. }| {
+ self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
// Ignore obligations, since we are unrolling
// everything anyway.
})
})
}
- pub fn eq_types(&self,
- a_is_expected: bool,
- cause: &ObligationCause<'tcx>,
- a: Ty<'tcx>,
- b: Ty<'tcx>)
- -> InferResult<'tcx, ()>
+ pub fn can_eq<T>(&self,
+ param_env: ty::ParamEnv<'tcx>,
+ a: T,
+ b: T)
+ -> UnitResult<'tcx>
+ where T: at::ToTrace<'tcx>
{
- self.commit_if_ok(|_| {
- let trace = TypeTrace::types(cause, a_is_expected, a, b);
- self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
- })
- }
-
- pub fn eq_trait_refs(&self,
- a_is_expected: bool,
- cause: &ObligationCause<'tcx>,
- a: ty::TraitRef<'tcx>,
- b: ty::TraitRef<'tcx>)
- -> InferResult<'tcx, ()>
- {
- debug!("eq_trait_refs({:?} = {:?})", a, b);
- self.commit_if_ok(|_| {
- let trace = TypeTrace {
- cause: cause.clone(),
- values: TraitRefs(ExpectedFound::new(a_is_expected, a, b))
- };
- self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
- })
- }
-
- pub fn eq_impl_headers(&self,
- a_is_expected: bool,
- cause: &ObligationCause<'tcx>,
- a: &ty::ImplHeader<'tcx>,
- b: &ty::ImplHeader<'tcx>)
- -> InferResult<'tcx, ()>
- {
- debug!("eq_impl_header({:?} = {:?})", a, b);
- match (a.trait_ref, b.trait_ref) {
- (Some(a_ref), Some(b_ref)) => self.eq_trait_refs(a_is_expected, cause, a_ref, b_ref),
- (None, None) => self.eq_types(a_is_expected, cause, a.self_ty, b.self_ty),
- _ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
- }
- }
-
- pub fn sub_poly_trait_refs(&self,
- a_is_expected: bool,
- cause: ObligationCause<'tcx>,
- a: ty::PolyTraitRef<'tcx>,
- b: ty::PolyTraitRef<'tcx>)
- -> InferResult<'tcx, ()>
- {
- debug!("sub_poly_trait_refs({:?} <: {:?})", a, b);
- self.commit_if_ok(|_| {
- let trace = TypeTrace {
- cause: cause,
- values: PolyTraitRefs(ExpectedFound::new(a_is_expected, a, b))
- };
- self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
+ let origin = &ObligationCause::dummy();
+ self.probe(|_| {
+ self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| {
+ // Ignore obligations, since we are unrolling
+ // everything anyway.
+ })
})
}
pub fn sub_regions(&self,
origin: SubregionOrigin<'tcx>,
- a: &'tcx ty::Region,
- b: &'tcx ty::Region) {
+ a: ty::Region<'tcx>,
+ b: ty::Region<'tcx>) {
debug!("sub_regions({:?} <: {:?})", a, b);
self.region_vars.make_subregion(origin, a, b);
}
pub fn equality_predicate(&self,
cause: &ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
predicate: &ty::PolyEquatePredicate<'tcx>)
-> InferResult<'tcx, ()>
{
let (ty::EquatePredicate(a, b), skol_map) =
self.skolemize_late_bound_regions(predicate, snapshot);
let cause_span = cause.span;
- let eqty_ok = self.eq_types(false, cause, a, b)?;
+ let eqty_ok = self.at(cause, param_env).eq(b, a)?;
self.leak_check(false, cause_span, &skol_map, snapshot)?;
self.pop_skolemized(skol_map, snapshot);
Ok(eqty_ok.unit())
pub fn subtype_predicate(&self,
cause: &ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
predicate: &ty::PolySubtypePredicate<'tcx>)
-> Option<InferResult<'tcx, ()>>
{
self.skolemize_late_bound_regions(predicate, snapshot);
let cause_span = cause.span;
- let ok = self.sub_types(a_is_expected, cause, a, b)?;
+ let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
self.leak_check(false, cause_span, &skol_map, snapshot)?;
self.pop_skolemized(skol_map, snapshot);
Ok(ok.unit())
}
pub fn next_region_var(&self, origin: RegionVariableOrigin)
- -> &'tcx ty::Region {
+ -> ty::Region<'tcx> {
self.tcx.mk_region(ty::ReVar(self.region_vars.new_region_var(origin)))
}
pub fn region_var_for_def(&self,
span: Span,
def: &ty::RegionParameterDef)
- -> &'tcx ty::Region {
+ -> ty::Region<'tcx> {
self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
}
substs: &[Kind<'tcx>])
-> Ty<'tcx> {
let default = if def.has_default {
- let default = self.tcx.item_type(def.def_id);
+ let default = self.tcx.type_of(def.def_id);
Some(type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
})
}
- pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> &'tcx ty::Region {
+ pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region<'tcx> {
self.region_vars.new_bound(debruijn)
}
}
pub fn resolve_regions_and_report_errors(&self,
- free_regions: &FreeRegionMap,
- subject_node_id: ast::NodeId) {
- let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
+ region_context: DefId,
+ region_map: &RegionMaps,
+ free_regions: &FreeRegionMap<'tcx>) {
+ let region_rels = RegionRelations::new(self.tcx,
+ region_context,
+ region_map,
+ free_regions);
+ let errors = self.region_vars.resolve_regions(®ion_rels);
if !self.is_tainted_by_errors() {
// As a heuristic, just skip reporting region errors
// altogether if other errors have been reported while
span: Span,
lbrct: LateBoundRegionConversionTime,
value: &ty::Binder<T>)
- -> (T, FxHashMap<ty::BoundRegion, &'tcx ty::Region>)
+ -> (T, FxHashMap<ty::BoundRegion, ty::Region<'tcx>>)
where T : TypeFoldable<'tcx>
{
self.tcx.replace_late_bound_regions(
/// details.
pub fn match_poly_projection_predicate(&self,
cause: ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
match_a: ty::PolyProjectionPredicate<'tcx>,
match_b: ty::TraitRef<'tcx>)
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
};
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
- let mut combine = self.combine_fields(trace);
+ let mut combine = self.combine_fields(trace, param_env);
let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
Ok(InferOk { value: result, obligations: combine.obligations })
}
pub fn verify_generic_bound(&self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
- a: &'tcx ty::Region,
+ a: ty::Region<'tcx>,
bound: VerifyBound<'tcx>) {
debug!("verify_generic_bound({:?}, {:?} <: {:?})",
kind,
self.region_vars.verify_generic_bound(origin, kind, a, bound);
}
- pub fn can_equate<T>(&self, a: &T, b: &T) -> UnitResult<'tcx>
- where T: Relate<'tcx> + fmt::Debug
- {
- debug!("can_equate({:?}, {:?})", a, b);
- self.probe(|_| {
- // Gin up a dummy trace, since this won't be committed
- // anyhow. We should make this typetrace stuff more
- // generic so we don't have to do anything quite this
- // terrible.
- let trace = TypeTrace::dummy(self.tcx);
- self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
- // We can intentionally ignore obligations here, since
- // this is part of a simple test for general
- // "equatability". However, it's not entirely clear
- // that we *ought* to be, perhaps a better thing would
- // be to use a mini-fulfillment context or something
- // like that.
- })
- })
- }
-
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
let ty = self.node_type(id);
self.resolve_type_vars_or_error(&ty)
self.resolve_type_vars_or_error(&ty)
}
- pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
+ pub fn type_moves_by_default(&self,
+ param_env: ty::ParamEnv<'tcx>,
+ ty: Ty<'tcx>,
+ span: Span)
+ -> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
- if let Some(ty) = self.tcx.lift_to_global(&ty) {
+ if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.
let local_closures = match self.tables {
_ => false
};
if !local_closures {
- return ty.moves_by_default(self.tcx.global_tcx(), self.param_env(), span);
+ return ty.moves_by_default(self.tcx.global_tcx(), param_env, span);
}
}
// rightly refuses to work with inference variables, but
// moves_by_default has a cache, which we want to use in other
// cases.
- !traits::type_known_to_meet_bound(self, ty, copy_def_id, span)
- }
-
- pub fn node_method_ty(&self, method_call: ty::MethodCall)
- -> Option<Ty<'tcx>> {
- self.tables
- .borrow()
- .method_map
- .get(&method_call)
- .map(|method| method.ty)
- .map(|ty| self.resolve_type_vars_if_possible(&ty))
- }
-
- pub fn node_method_id(&self, method_call: ty::MethodCall)
- -> Option<DefId> {
- self.tables
- .borrow()
- .method_map
- .get(&method_call)
- .map(|method| method.def_id)
- }
-
- pub fn is_method_call(&self, id: ast::NodeId) -> bool {
- self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
+ !traits::type_known_to_meet_bound(self, param_env, ty, copy_def_id, span)
}
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture<'tcx>> {
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
}
- pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> {
- &self.parameter_environment
- }
-
pub fn closure_kind(&self,
def_id: DefId)
-> Option<ty::ClosureKind>
{
if let InferTables::InProgress(tables) = self.tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
- return tables.borrow().closure_kinds.get(&id).cloned();
+ return tables.borrow()
+ .closure_kinds
+ .get(&id)
+ .cloned()
+ .map(|(kind, _)| kind);
}
}