//! See the Book for more information.
+pub use self::freshen::TypeFreshener;
pub use self::LateBoundRegionConversionTime::*;
pub use self::RegionVariableOrigin::*;
pub use self::SubregionOrigin::*;
pub use self::ValuePairs::*;
pub use ty::IntVarValue;
-pub use self::freshen::TypeFreshener;
+use arena::SyncDroplessArena;
+use errors::DiagnosticBuilder;
use hir::def_id::DefId;
use middle::free_region::RegionRelations;
-use middle::region;
use middle::lang_items;
-use ty::subst::{Kind, Substs};
-use ty::{TyVid, IntVid, FloatVid};
-use ty::{self, Ty, TyCtxt, GenericParamDefKind};
-use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
-use ty::fold::TypeFoldable;
-use ty::relate::RelateResult;
-use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
+use middle::region;
use rustc_data_structures::unify as ut;
-use std::cell::{Cell, RefCell, Ref, RefMut};
+use std::cell::{Cell, Ref, RefCell, RefMut};
use std::collections::BTreeMap;
use std::fmt;
use syntax::ast;
-use errors::DiagnosticBuilder;
-use syntax_pos::{self, Span};
use syntax_pos::symbol::InternedString;
+use syntax_pos::{self, Span};
+use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
+use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
+use ty::fold::TypeFoldable;
+use ty::relate::RelateResult;
+use ty::subst::{Kind, Substs};
+use ty::{self, GenericParamDefKind, Ty, TyCtxt};
+use ty::{FloatVid, IntVid, TyVid};
use util::nodemap::FxHashMap;
-use arena::SyncDroplessArena;
use self::combine::CombineFields;
use self::higher_ranked::HrMatchResult;
-use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
-use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos};
use self::lexical_region_resolve::LexicalRegionResolutions;
use self::outlives::env::OutlivesEnvironment;
+use self::region_constraints::{GenericKind, RegionConstraintData, VarInfos, VerifyBound};
+use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
use self::type_variable::TypeVariableOrigin;
use self::unify_key::ToType;
mod combine;
mod equate;
pub mod error_reporting;
+mod freshen;
mod fudge;
mod glb;
mod higher_ranked;
pub mod lattice;
-mod lub;
-pub mod region_constraints;
mod lexical_region_resolve;
+mod lub;
pub mod outlives;
+pub mod region_constraints;
pub mod resolve;
-mod freshen;
mod sub;
pub mod type_variable;
pub mod unify_key;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
-pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
/// During type-checking/inference of a body, `in_progress_tables`
/// Places that type/region parameters can appear.
#[derive(Clone, Copy, Debug)]
pub enum ParameterOrigin {
- Path, // foo::bar
- MethodCall, // foo.bar() <-- parameters on impl providing bar()
+ Path, // foo::bar
+ MethodCall, // foo.bar() <-- parameters on impl providing bar()
OverloadedOperator, // a + b when overloaded
- OverloadedDeref, // *a when overloaded
+ OverloadedDeref, // *a when overloaded
}
/// Times when we replace late-bound regions with variables:
pub enum FixupError {
UnresolvedIntTy(IntVid),
UnresolvedFloatTy(FloatVid),
- UnresolvedTy(TyVid)
+ UnresolvedTy(TyVid),
}
/// See the `region_obligations` field for more information.
use self::FixupError::*;
match *self {
- UnresolvedIntTy(_) => {
- write!(f, "cannot determine the type of this integer; \
- add a suffix to specify the type explicitly")
- }
- UnresolvedFloatTy(_) => {
- write!(f, "cannot determine the type of this number; \
- add a suffix to specify the type explicitly")
- }
- UnresolvedTy(_) => write!(f, "unconstrained type")
+ UnresolvedIntTy(_) => write!(
+ f,
+ "cannot determine the type of this integer; \
+ add a suffix to specify the type explicitly"
+ ),
+ UnresolvedFloatTy(_) => write!(
+ f,
+ "cannot determine the type of this number; \
+ add a suffix to specify the type explicitly"
+ ),
+ UnresolvedTy(_) => write!(f, "unconstrained type"),
}
}
}
/// Helper type of a temporary returned by tcx.infer_ctxt().
/// Necessary because we can't write the following bound:
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>).
-pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
arena: SyncDroplessArena,
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
global_tcx: self,
arena: SyncDroplessArena::new(),
fresh_tables: None,
-
}
}
}
}
pub fn enter<F, R>(&'tcx mut self, f: F) -> R
- where F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R
+ where
+ F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R,
{
let InferCtxtBuilder {
global_tcx,
ref fresh_tables,
} = *self;
let in_progress_tables = fresh_tables.as_ref();
- global_tcx.enter_local(arena, |tcx| f(InferCtxt {
- tcx,
- in_progress_tables,
- projection_cache: RefCell::new(traits::ProjectionCache::new()),
- type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
- int_unification_table: RefCell::new(ut::UnificationTable::new()),
- float_unification_table: RefCell::new(ut::UnificationTable::new()),
- region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
- lexical_region_resolutions: RefCell::new(None),
- selection_cache: traits::SelectionCache::new(),
- evaluation_cache: traits::EvaluationCache::new(),
- reported_trait_errors: RefCell::new(FxHashMap()),
- tainted_by_errors_flag: Cell::new(false),
- err_count_on_creation: tcx.sess.err_count(),
- in_snapshot: Cell::new(false),
- region_obligations: RefCell::new(vec![]),
- universe: Cell::new(ty::UniverseIndex::ROOT),
- }))
+ global_tcx.enter_local(arena, |tcx| {
+ f(InferCtxt {
+ tcx,
+ in_progress_tables,
+ projection_cache: RefCell::new(traits::ProjectionCache::new()),
+ type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
+ int_unification_table: RefCell::new(ut::UnificationTable::new()),
+ float_unification_table: RefCell::new(ut::UnificationTable::new()),
+ region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
+ lexical_region_resolutions: RefCell::new(None),
+ selection_cache: traits::SelectionCache::new(),
+ evaluation_cache: traits::EvaluationCache::new(),
+ reported_trait_errors: RefCell::new(FxHashMap()),
+ tainted_by_errors_flag: Cell::new(false),
+ err_count_on_creation: tcx.sess.err_count(),
+ in_snapshot: Cell::new(false),
+ region_obligations: RefCell::new(vec![]),
+ universe: Cell::new(ty::UniverseIndex::ROOT),
+ })
+ })
}
}
impl<T> ExpectedFound<T> {
pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
if a_is_expected {
- ExpectedFound {expected: a, found: b}
+ ExpectedFound {
+ expected: a,
+ found: b,
+ }
} else {
- ExpectedFound {expected: b, found: a}
+ ExpectedFound {
+ expected: b,
+ found: a,
+ }
}
}
}
impl<'tcx, T> InferOk<'tcx, T> {
pub fn unit(self) -> InferOk<'tcx, ()> {
- InferOk { value: (), obligations: self.obligations }
+ InferOk {
+ value: (),
+ obligations: self.obligations,
+ }
}
/// Extract `value`, registering any obligations into `fulfill_cx`
}
#[must_use = "once you start a snapshot, you should always consume it"]
-pub struct CombinedSnapshot<'a, 'tcx:'a> {
+pub struct CombinedSnapshot<'a, 'tcx: 'a> {
projection_cache_snapshot: traits::ProjectionCacheSnapshot,
type_snapshot: type_variable::Snapshot<'tcx>,
int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
self.in_snapshot.get()
}
- pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
+ pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
t.fold_with(&mut self.freshener())
}
pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
match ty.sty {
ty::Infer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
- _ => false
+ _ => false,
}
}
pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
use ty::error::UnconstrainedNumeric::Neither;
- use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
+ use ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
match ty.sty {
ty::Infer(ty::IntVar(vid)) => {
- if self.int_unification_table.borrow_mut().probe_value(vid).is_some() {
+ if self.int_unification_table
+ .borrow_mut()
+ .probe_value(vid)
+ .is_some()
+ {
Neither
} else {
UnconstrainedInt
}
- },
+ }
ty::Infer(ty::FloatVar(vid)) => {
- if self.float_unification_table.borrow_mut().probe_value(vid).is_some() {
+ if self.float_unification_table
+ .borrow_mut()
+ .probe_value(vid)
+ .is_some()
+ {
Neither
} else {
UnconstrainedFloat
}
- },
+ }
_ => Neither,
}
}
(0..int_unification_table.len())
.map(|i| ty::IntVid { index: i as u32 })
.filter(|&vid| int_unification_table.probe_value(vid).is_none())
- .map(|v| self.tcx.mk_int_var(v))
- ).chain(
+ .map(|v| self.tcx.mk_int_var(v)),
+ )
+ .chain(
(0..float_unification_table.len())
.map(|i| ty::FloatVid { index: i as u32 })
.filter(|&vid| float_unification_table.probe_value(vid).is_none())
- .map(|v| self.tcx.mk_float_var(v))
- ).collect()
+ .map(|v| self.tcx.mk_float_var(v)),
+ )
+ .collect()
}
- fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)
- -> CombineFields<'a, 'gcx, 'tcx> {
+ fn combine_fields(
+ &'a self,
+ trace: TypeTrace<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ ) -> CombineFields<'a, 'gcx, 'tcx> {
CombineFields {
infcx: self,
trace,
// escaping obligations in the main cx. In those cases, you can
// use this function.
pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
- where F: FnOnce(&Self) -> R
+ where
+ F: FnOnce(&Self) -> R,
{
let flag = self.in_snapshot.get();
self.in_snapshot.set(false);
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: self.in_progress_tables.map(|tables| {
- tables.borrow()
- })
+ _in_progress_tables: self.in_progress_tables.map(|tables| tables.borrow()),
}
}
fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) {
debug!("rollback_to(cause={})", cause);
- let CombinedSnapshot { projection_cache_snapshot,
- type_snapshot,
- int_snapshot,
- float_snapshot,
- region_constraints_snapshot,
- region_obligations_snapshot,
- universe,
- was_in_snapshot,
- _in_progress_tables } = snapshot;
+ let CombinedSnapshot {
+ projection_cache_snapshot,
+ type_snapshot,
+ int_snapshot,
+ float_snapshot,
+ region_constraints_snapshot,
+ region_obligations_snapshot,
+ universe,
+ was_in_snapshot,
+ _in_progress_tables,
+ } = snapshot;
self.in_snapshot.set(was_in_snapshot);
self.universe.set(universe);
self.projection_cache
.borrow_mut()
.rollback_to(projection_cache_snapshot);
- self.type_variables
- .borrow_mut()
- .rollback_to(type_snapshot);
+ self.type_variables.borrow_mut().rollback_to(type_snapshot);
self.int_unification_table
.borrow_mut()
.rollback_to(int_snapshot);
fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
debug!("commit_from()");
- let CombinedSnapshot { projection_cache_snapshot,
- type_snapshot,
- int_snapshot,
- float_snapshot,
- region_constraints_snapshot,
- region_obligations_snapshot: _,
- universe: _,
- was_in_snapshot,
- _in_progress_tables } = snapshot;
+ let CombinedSnapshot {
+ projection_cache_snapshot,
+ type_snapshot,
+ int_snapshot,
+ float_snapshot,
+ region_constraints_snapshot,
+ region_obligations_snapshot: _,
+ universe: _,
+ was_in_snapshot,
+ _in_progress_tables,
+ } = snapshot;
self.in_snapshot.set(was_in_snapshot);
self.projection_cache
.borrow_mut()
.commit(&projection_cache_snapshot);
- self.type_variables
- .borrow_mut()
- .commit(type_snapshot);
- self.int_unification_table
- .borrow_mut()
- .commit(int_snapshot);
+ self.type_variables.borrow_mut().commit(type_snapshot);
+ self.int_unification_table.borrow_mut().commit(int_snapshot);
self.float_unification_table
.borrow_mut()
.commit(float_snapshot);
}
/// Execute `f` and commit the bindings
- pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
+ pub fn commit_unconditionally<R, F>(&self, f: F) -> R
+ where
F: FnOnce() -> R,
{
debug!("commit()");
}
/// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
- pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
- F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>
+ pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
+ where
+ F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>,
{
debug!("commit_if_ok()");
let snapshot = self.start_snapshot();
let r = f(&snapshot);
debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
match r {
- Ok(_) => { self.commit_from(snapshot); }
- Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
+ Ok(_) => {
+ self.commit_from(snapshot);
+ }
+ Err(_) => {
+ self.rollback_to("commit_if_ok -- error", snapshot);
+ }
}
r
}
// Execute `f` in a snapshot, and commit the bindings it creates
- pub fn in_snapshot<T, F>(&self, f: F) -> T where
- F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T
+ pub fn in_snapshot<T, F>(&self, f: F) -> T
+ where
+ F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T,
{
debug!("in_snapshot()");
let snapshot = self.start_snapshot();
}
/// Execute `f` then unroll any bindings it creates
- pub fn probe<R, F>(&self, f: F) -> R where
+ pub fn probe<R, F>(&self, f: F) -> R
+ where
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
{
debug!("probe()");
r
}
- pub fn add_given(&self,
- sub: ty::Region<'tcx>,
- sup: ty::RegionVid)
- {
+ pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
self.borrow_region_constraints().add_given(sub, sup);
}
- pub fn can_sub<T>(&self,
- param_env: ty::ParamEnv<'tcx>,
- a: T,
- b: T)
- -> UnitResult<'tcx>
- where T: at::ToTrace<'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(|_| {
- self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
- // Ignore obligations, since we are unrolling
- // everything anyway.
- })
+ self.at(origin, param_env)
+ .sub(a, b)
+ .map(|InferOk { obligations: _, .. }| {
+ // Ignore obligations, since we are unrolling
+ // everything anyway.
+ })
})
}
- pub fn can_eq<T>(&self,
- param_env: ty::ParamEnv<'tcx>,
- a: T,
- b: T)
- -> UnitResult<'tcx>
- where T: at::ToTrace<'tcx>
+ pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx>
+ where
+ T: at::ToTrace<'tcx>,
{
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.
- })
+ 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: ty::Region<'tcx>,
- b: ty::Region<'tcx>) {
+ pub fn sub_regions(
+ &self,
+ origin: SubregionOrigin<'tcx>,
+ a: ty::Region<'tcx>,
+ b: ty::Region<'tcx>,
+ ) {
debug!("sub_regions({:?} <: {:?})", a, b);
- self.borrow_region_constraints().make_subregion(origin, a, b);
+ self.borrow_region_constraints()
+ .make_subregion(origin, a, b);
}
- pub fn subtype_predicate(&self,
- cause: &ObligationCause<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- predicate: &ty::PolySubtypePredicate<'tcx>)
- -> Option<InferResult<'tcx, ()>>
- {
+ pub fn subtype_predicate(
+ &self,
+ cause: &ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ predicate: &ty::PolySubtypePredicate<'tcx>,
+ ) -> Option<InferResult<'tcx, ()>> {
// Subtle: it's ok to skip the binder here and resolve because
// `shallow_resolve` just ignores anything that is not a type
// variable, and because type variable's can't (at present, at
}
Some(self.commit_if_ok(|snapshot| {
- let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
- self.skolemize_late_bound_regions(predicate);
+ let (
+ ty::SubtypePredicate {
+ a_is_expected,
+ a,
+ b,
+ },
+ skol_map,
+ ) = self.skolemize_late_bound_regions(predicate);
let cause_span = cause.span;
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
}))
}
- pub fn region_outlives_predicate(&self,
- cause: &traits::ObligationCause<'tcx>,
- predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
- -> UnitResult<'tcx>
- {
+ pub fn region_outlives_predicate(
+ &self,
+ cause: &traits::ObligationCause<'tcx>,
+ predicate: &ty::PolyRegionOutlivesPredicate<'tcx>,
+ ) -> UnitResult<'tcx> {
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
self.skolemize_late_bound_regions(predicate);
- let origin =
- SubregionOrigin::from_obligation_cause(cause,
- || RelateRegionParamBound(cause.span));
+ let origin = SubregionOrigin::from_obligation_cause(cause, || {
+ RelateRegionParamBound(cause.span)
+ });
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
self.leak_check(false, cause.span, &skol_map, snapshot)?;
Ok(self.pop_skolemized(skol_map, snapshot))
}
pub fn next_int_var_id(&self) -> IntVid {
- self.int_unification_table
- .borrow_mut()
- .new_key(None)
+ self.int_unification_table.borrow_mut().new_key(None)
}
pub fn next_float_var_id(&self) -> FloatVid {
- self.float_unification_table
- .borrow_mut()
- .new_key(None)
+ self.float_unification_table.borrow_mut().new_key(None)
}
/// Create a fresh region variable with the next available index.
///
/// - `origin`: information about why we created this variable, for use
/// during diagnostics / error-reporting.
- pub fn next_region_var(&self, origin: RegionVariableOrigin)
- -> ty::Region<'tcx> {
+ pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> {
let region_var = self.borrow_region_constraints()
.new_region_var(self.universe(), origin);
self.tcx.mk_region(ty::ReVar(region_var))
}
/// Just a convenient wrapper of `next_region_var` for using during NLL.
- pub fn next_nll_region_var(&self, origin: NLLRegionVariableOrigin)
- -> ty::Region<'tcx> {
+ pub fn next_nll_region_var(&self, origin: NLLRegionVariableOrigin) -> ty::Region<'tcx> {
self.next_region_var(RegionVariableOrigin::NLL(origin))
}
- pub fn var_for_def(&self,
- span: Span,
- param: &ty::GenericParamDef)
- -> Kind<'tcx> {
+ pub fn var_for_def(&self, span: Span, param: &ty::GenericParamDef) -> Kind<'tcx> {
match param.kind {
GenericParamDefKind::Lifetime => {
// Create a region inference variable for the given
// region parameter definition.
- self.next_region_var(EarlyBoundRegion(span, param.name)).into()
+ self.next_region_var(EarlyBoundRegion(span, param.name))
+ .into()
}
- GenericParamDefKind::Type {..} => {
+ GenericParamDefKind::Type { .. } => {
// Create a type inference variable for the given
// type parameter definition. The substitutions are
// for actual parameters that may be referred to by
// used in a path such as `Foo::<T, U>::new()` will
// use an inference variable for `C` with `[T, U]`
// as the substitutions for the default, `(T, U)`.
- let ty_var_id =
- self.type_variables
- .borrow_mut()
- .new_var(self.universe(),
- false,
- TypeVariableOrigin::TypeParameterDefinition(span, param.name));
+ let ty_var_id = self.type_variables.borrow_mut().new_var(
+ self.universe(),
+ false,
+ TypeVariableOrigin::TypeParameterDefinition(span, param.name),
+ );
self.tcx.mk_var(ty_var_id).into()
}
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
- pub fn fresh_substs_for_item(&self,
- span: Span,
- def_id: DefId)
- -> &'tcx Substs<'tcx> {
- Substs::for_item(self.tcx, def_id, |param, _| {
- self.var_for_def(span, param)
- })
+ pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> &'tcx Substs<'tcx> {
+ Substs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
}
/// True if errors have been reported since this infcx was
/// errors, but where it's hard to be 100% sure (e.g., unresolved
/// inference variables, regionck errors).
pub fn is_tainted_by_errors(&self) -> bool {
- debug!("is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
- tainted_by_errors_flag={})",
- self.tcx.sess.err_count(),
- self.err_count_on_creation,
- self.tainted_by_errors_flag.get());
+ debug!(
+ "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
+ tainted_by_errors_flag={})",
+ self.tcx.sess.err_count(),
+ self.err_count_on_creation,
+ self.tainted_by_errors_flag.get()
+ );
if self.tcx.sess.err_count() > self.err_count_on_creation {
return true; // errors reported since this infcx was made
region_map: ®ion::ScopeTree,
outlives_env: &OutlivesEnvironment<'tcx>,
) {
- self.resolve_regions_and_report_errors_inner(
- region_context,
- region_map,
- outlives_env,
- true,
- )
+ self.resolve_regions_and_report_errors_inner(region_context, region_map, outlives_env, true)
}
fn resolve_regions_and_report_errors_inner(
outlives_env: &OutlivesEnvironment<'tcx>,
will_later_be_reported_by_nll: bool,
) {
- assert!(self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
- "region_obligations not empty: {:#?}",
- self.region_obligations.borrow());
-
- let region_rels = &RegionRelations::new(self.tcx,
- region_context,
- region_map,
- outlives_env.free_region_map());
- let (var_infos, data) = self.region_constraints.borrow_mut()
- .take()
- .expect("regions already resolved")
- .into_infos_and_data();
+ assert!(
+ self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
+ "region_obligations not empty: {:#?}",
+ self.region_obligations.borrow()
+ );
+
+ let region_rels = &RegionRelations::new(
+ self.tcx,
+ region_context,
+ region_map,
+ outlives_env.free_region_map(),
+ );
+ let (var_infos, data) = self.region_constraints
+ .borrow_mut()
+ .take()
+ .expect("regions already resolved")
+ .into_infos_and_data();
let (lexical_region_resolutions, errors) =
lexical_region_resolve::resolve(region_rels, var_infos, data);
- let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
+ let old_value = self.lexical_region_resolutions
+ .replace(Some(lexical_region_resolutions));
assert!(old_value.is_none());
if !self.is_tainted_by_errors() {
/// translate them into the form that the NLL solver
/// understands. See the NLL module for mode details.
pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> {
- assert!(self.region_obligations.borrow().is_empty(),
- "region_obligations not empty: {:#?}",
- self.region_obligations.borrow());
+ assert!(
+ self.region_obligations.borrow().is_empty(),
+ "region_obligations not empty: {:#?}",
+ self.region_obligations.borrow()
+ );
self.borrow_region_constraints().take_and_reset_data()
}
/// called. This is used only during NLL processing to "hand off" ownership
/// of the set of region vairables into the NLL region context.
pub fn take_region_var_origins(&self) -> VarInfos {
- let (var_infos, data) = self.region_constraints.borrow_mut()
- .take()
- .expect("regions already resolved")
- .into_infos_and_data();
+ let (var_infos, data) = self.region_constraints
+ .borrow_mut()
+ .take()
+ .expect("regions already resolved")
+ .into_infos_and_data();
assert!(data.is_empty());
var_infos
}
// structurally), and we prevent cycles in any case,
// so this recursion should always be of very limited
// depth.
- self.type_variables.borrow_mut()
- .probe(v)
- .known()
- .map(|t| self.shallow_resolve(t))
- .unwrap_or(typ)
- }
-
- ty::Infer(ty::IntVar(v)) => {
- self.int_unification_table
+ self.type_variables
.borrow_mut()
- .probe_value(v)
- .map(|v| v.to_type(self.tcx))
+ .probe(v)
+ .known()
+ .map(|t| self.shallow_resolve(t))
.unwrap_or(typ)
}
- ty::Infer(ty::FloatVar(v)) => {
- self.float_unification_table
- .borrow_mut()
- .probe_value(v)
- .map(|v| v.to_type(self.tcx))
- .unwrap_or(typ)
- }
+ ty::Infer(ty::IntVar(v)) => self.int_unification_table
+ .borrow_mut()
+ .probe_value(v)
+ .map(|v| v.to_type(self.tcx))
+ .unwrap_or(typ),
- _ => {
- typ
- }
+ ty::Infer(ty::FloatVar(v)) => self.float_unification_table
+ .borrow_mut()
+ .probe_value(v)
+ .map(|v| v.to_type(self.tcx))
+ .unwrap_or(typ),
+
+ _ => typ,
}
}
}
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
- where T: TypeFoldable<'tcx>
+ where
+ T: TypeFoldable<'tcx>,
{
/*!
* Where possible, replaces type/int/float variables in
/// resolved type, so it's more efficient than
/// `resolve_type_vars_if_possible()`.
pub fn any_unresolved_type_vars<T>(&self, value: &T) -> bool
- where T: TypeFoldable<'tcx>
+ where
+ T: TypeFoldable<'tcx>,
{
let mut r = resolve::UnresolvedTypeFinder::new(self);
value.visit_with(&mut r)
}
pub fn resolve_type_and_region_vars_if_possible<T>(&self, value: &T) -> T
- where T: TypeFoldable<'tcx>
+ where
+ T: TypeFoldable<'tcx>,
{
let mut r = resolve::OpportunisticTypeAndRegionResolver::new(self);
value.fold_with(&mut r)
}
- pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
+ pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
/*!
* Attempts to resolve all type/region variables in
* `value`. Region inference must have been run already (e.g.,
// types using one of these methods, and should not call span_err directly for such
// errors.
- pub fn type_error_struct_with_diag<M>(&self,
- sp: Span,
- mk_diag: M,
- actual_ty: Ty<'tcx>)
- -> DiagnosticBuilder<'tcx>
- where M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
+ pub fn type_error_struct_with_diag<M>(
+ &self,
+ sp: Span,
+ mk_diag: M,
+ actual_ty: Ty<'tcx>,
+ ) -> DiagnosticBuilder<'tcx>
+ where
+ M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
{
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
mk_diag(self.ty_to_string(actual_ty))
}
- pub fn report_mismatched_types(&self,
- cause: &ObligationCause<'tcx>,
- expected: Ty<'tcx>,
- actual: Ty<'tcx>,
- err: TypeError<'tcx>)
- -> DiagnosticBuilder<'tcx> {
+ pub fn report_mismatched_types(
+ &self,
+ cause: &ObligationCause<'tcx>,
+ expected: Ty<'tcx>,
+ actual: Ty<'tcx>,
+ err: TypeError<'tcx>,
+ ) -> DiagnosticBuilder<'tcx> {
let trace = TypeTrace::types(cause, true, expected, actual);
self.report_and_explain_type_error(trace, &err)
}
&self,
span: Span,
lbrct: LateBoundRegionConversionTime,
- value: &ty::Binder<T>)
- -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
- where T : TypeFoldable<'tcx>
+ value: &ty::Binder<T>,
+ ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
+ where
+ T: TypeFoldable<'tcx>,
{
- self.tcx.replace_late_bound_regions(
- value,
- |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
+ self.tcx.replace_late_bound_regions(value, |br| {
+ self.next_region_var(LateBoundRegion(span, br, lbrct))
+ })
}
/// Given a higher-ranked projection predicate like:
///
/// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
/// 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>>>
- {
+ 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(self.tcx), p.ty));
let trace = TypeTrace {
cause,
- values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
+ values: TraitRefs(ExpectedFound::new(
+ true,
+ match_pair.skip_binder().0,
+ match_b,
+ )),
};
let mut combine = self.combine_fields(trace, param_env);
let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
- Ok(InferOk { value: result, obligations: combine.obligations })
+ Ok(InferOk {
+ value: result,
+ obligations: combine.obligations,
+ })
}
/// See `verify_generic_bound` method in `region_constraints`
- pub fn verify_generic_bound(&self,
- origin: SubregionOrigin<'tcx>,
- kind: GenericKind<'tcx>,
- a: ty::Region<'tcx>,
- bound: VerifyBound<'tcx>) {
- debug!("verify_generic_bound({:?}, {:?} <: {:?})",
- kind,
- a,
- bound);
-
- self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound);
- }
-
- pub fn type_moves_by_default(&self,
- param_env: ty::ParamEnv<'tcx>,
- ty: Ty<'tcx>,
- span: Span)
- -> bool {
+ pub fn verify_generic_bound(
+ &self,
+ origin: SubregionOrigin<'tcx>,
+ kind: GenericKind<'tcx>,
+ a: ty::Region<'tcx>,
+ bound: VerifyBound<'tcx>,
+ ) {
+ debug!("verify_generic_bound({:?}, {:?} <: {:?})", kind, a, bound);
+
+ self.borrow_region_constraints()
+ .verify_generic_bound(origin, kind, a, bound);
+ }
+
+ 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);
// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.
/// Obtains the latest type of the given closure; this may be a
/// closure in the current function, in which case its
/// `ClosureKind` may not yet be known.
- pub fn closure_kind(&self,
- closure_def_id: DefId,
- closure_substs: ty::ClosureSubsts<'tcx>)
- -> Option<ty::ClosureKind>
- {
+ pub fn closure_kind(
+ &self,
+ closure_def_id: DefId,
+ closure_substs: ty::ClosureSubsts<'tcx>,
+ ) -> Option<ty::ClosureKind> {
let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
let closure_kind_ty = self.shallow_resolve(&closure_kind_ty);
closure_kind_ty.to_opt_closure_kind()
pub fn closure_sig(
&self,
def_id: DefId,
- substs: ty::ClosureSubsts<'tcx>
+ substs: ty::ClosureSubsts<'tcx>,
) -> ty::PolyFnSig<'tcx> {
let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
/// Normalizes associated types in `value`, potentially returning
/// new obligations that must further be processed.
- pub fn partially_normalize_associated_types_in<T>(&self,
- span: Span,
- body_id: ast::NodeId,
- param_env: ty::ParamEnv<'tcx>,
- value: &T)
- -> InferOk<'tcx, T>
- where T : TypeFoldable<'tcx>
+ pub fn partially_normalize_associated_types_in<T>(
+ &self,
+ span: Span,
+ body_id: ast::NodeId,
+ param_env: ty::ParamEnv<'tcx>,
+ value: &T,
+ ) -> InferOk<'tcx, T>
+ where
+ T: TypeFoldable<'tcx>,
{
debug!("partially_normalize_associated_types_in(value={:?})", value);
let mut selcx = traits::SelectionContext::new(self);
let cause = ObligationCause::misc(span, body_id);
let traits::Normalized { value, obligations } =
traits::normalize(&mut selcx, param_env, cause, value);
- debug!("partially_normalize_associated_types_in: result={:?} predicates={:?}",
- value,
- obligations);
+ debug!(
+ "partially_normalize_associated_types_in: result={:?} predicates={:?}",
+ value, obligations
+ );
InferOk { value, obligations }
}
pub fn borrow_region_constraints(&self) -> RefMut<'_, RegionConstraintCollector<'tcx>> {
- RefMut::map(
- self.region_constraints.borrow_mut(),
- |c| c.as_mut().expect("region constraints already solved"))
+ RefMut::map(self.region_constraints.borrow_mut(), |c| {
+ c.as_mut().expect("region constraints already solved")
+ })
}
/// Clears the selection, evaluation, and projection cachesThis is useful when
self.cause.span
}
- pub fn types(cause: &ObligationCause<'tcx>,
- a_is_expected: bool,
- a: Ty<'tcx>,
- b: Ty<'tcx>)
- -> TypeTrace<'tcx> {
+ pub fn types(
+ cause: &ObligationCause<'tcx>,
+ a_is_expected: bool,
+ a: Ty<'tcx>,
+ b: Ty<'tcx>,
+ ) -> TypeTrace<'tcx> {
TypeTrace {
cause: cause.clone(),
- values: Types(ExpectedFound::new(a_is_expected, a, b))
+ values: Types(ExpectedFound::new(a_is_expected, a, b)),
}
}
values: Types(ExpectedFound {
expected: tcx.types.err,
found: tcx.types.err,
- })
+ }),
}
}
}
}
}
- pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>,
- default: F)
- -> Self
- where F: FnOnce() -> Self
+ pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>, default: F) -> Self
+ where
+ F: FnOnce() -> Self,
{
match cause.code {
- traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) =>
- SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span),
-
- traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
- impl_item_def_id,
- trait_item_def_id, } =>
- SubregionOrigin::CompareImplMethodObligation {
- span: cause.span,
- item_name,
- impl_item_def_id,
- trait_item_def_id,
- },
+ traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) => {
+ SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
+ }
+
+ traits::ObligationCauseCode::CompareImplMethodObligation {
+ item_name,
+ impl_item_def_id,
+ trait_item_def_id,
+ } => SubregionOrigin::CompareImplMethodObligation {
+ span: cause.span,
+ item_name,
+ impl_item_def_id,
+ trait_item_def_id,
+ },
_ => default(),
}
impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
- self.sub_region,
- self.sup_type)
+ write!(
+ f,
+ "RegionObligation(sub_region={:?}, sup_type={:?})",
+ self.sub_region, self.sup_type
+ )
}
}