diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index a092bac51878..66aa7d6d8eaf 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -10,41 +10,41 @@ //! 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; @@ -54,16 +54,16 @@ pub mod canonical; 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; @@ -80,7 +80,7 @@ pub type Bound = Option; pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" pub type FixupResult = Result; // "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` @@ -314,10 +314,10 @@ pub enum SubregionOrigin<'tcx> { /// 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: @@ -400,7 +400,7 @@ impl NLLRegionVariableOrigin { pub enum FixupError { UnresolvedIntTy(IntVid), UnresolvedFloatTy(FloatVid), - UnresolvedTy(TyVid) + UnresolvedTy(TyVid), } /// See the `region_obligations` field for more information. @@ -416,15 +416,17 @@ impl fmt::Display for FixupError { 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"), } } } @@ -432,7 +434,7 @@ impl fmt::Display for FixupError { /// 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>>, @@ -444,7 +446,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { global_tcx: self, arena: SyncDroplessArena::new(), fresh_tables: None, - } } } @@ -458,7 +459,8 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { } pub fn enter(&'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, @@ -466,40 +468,51 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, '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 ExpectedFound { 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` @@ -523,7 +536,7 @@ impl<'tcx> InferOk<'tcx, ()> { } #[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>, @@ -540,14 +553,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.in_snapshot.get() } - pub fn freshen>(&self, t: T) -> T { + pub fn freshen>(&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, } } @@ -557,22 +570,30 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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, } } @@ -590,17 +611,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (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, @@ -627,7 +653,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // escaping obligations in the main cx. In those cases, you can // use this function. pub fn save_and_restore_in_snapshot_flag(&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); @@ -653,23 +680,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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); @@ -677,9 +704,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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); @@ -695,27 +720,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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); @@ -724,7 +747,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// Execute `f` and commit the bindings - pub fn commit_unconditionally(&self, f: F) -> R where + pub fn commit_unconditionally(&self, f: F) -> R + where F: FnOnce() -> R, { debug!("commit()"); @@ -735,23 +759,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)` - pub fn commit_if_ok(&self, f: F) -> Result where - F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result + pub fn commit_if_ok(&self, f: F) -> Result + where + F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result, { 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(&self, f: F) -> T where - F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T + pub fn in_snapshot(&self, f: F) -> T + where + F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T, { debug!("in_snapshot()"); let snapshot = self.start_snapshot(); @@ -761,7 +791,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// Execute `f` then unroll any bindings it creates - pub fn probe(&self, f: F) -> R where + pub fn probe(&self, f: F) -> R + where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, { debug!("probe()"); @@ -771,59 +802,57 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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(&self, - param_env: ty::ParamEnv<'tcx>, - a: T, - b: T) - -> UnitResult<'tcx> - where T: at::ToTrace<'tcx> + pub fn can_sub(&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(&self, - param_env: ty::ParamEnv<'tcx>, - a: T, - b: T) - -> UnitResult<'tcx> - where T: at::ToTrace<'tcx> + pub fn can_eq(&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> - { + pub fn subtype_predicate( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + predicate: &ty::PolySubtypePredicate<'tcx>, + ) -> Option> { // 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 @@ -845,8 +874,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } 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)?; @@ -856,17 +891,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { })) } - 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)) @@ -888,15 +923,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } 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. @@ -905,8 +936,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// /// - `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)) @@ -918,22 +948,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } /// 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 @@ -942,12 +969,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // used in a path such as `Foo::::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() } @@ -956,13 +982,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// 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 @@ -971,11 +992,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// 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 @@ -1018,12 +1041,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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( @@ -1033,22 +1051,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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()); + 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 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() { @@ -1072,9 +1096,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// 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() } @@ -1095,10 +1121,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// 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 } @@ -1132,32 +1159,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // 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, } } @@ -1166,7 +1188,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } pub fn resolve_type_vars_if_possible(&self, value: &T) -> T - where T: TypeFoldable<'tcx> + where + T: TypeFoldable<'tcx>, { /*! * Where possible, replaces type/int/float variables in @@ -1190,20 +1213,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// resolved type, so it's more efficient than /// `resolve_type_vars_if_possible()`. pub fn any_unresolved_type_vars(&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(&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>(&self, value: &T) -> FixupResult { + pub fn fully_resolve>(&self, value: &T) -> FixupResult { /*! * Attempts to resolve all type/region variables in * `value`. Region inference must have been run already (e.g., @@ -1228,12 +1253,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // types using one of these methods, and should not call span_err directly for such // errors. - pub fn type_error_struct_with_diag(&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( + &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); @@ -1246,12 +1273,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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) } @@ -1260,13 +1288,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { &self, span: Span, lbrct: LateBoundRegionConversionTime, - value: &ty::Binder) - -> (T, BTreeMap>) - where T : TypeFoldable<'tcx> + value: &ty::Binder, + ) -> (T, BTreeMap>) + 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: @@ -1284,43 +1313,51 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// /// 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>> - { + 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>> { 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); + 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); + 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 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. @@ -1342,11 +1379,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// 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 - { + pub fn closure_kind( + &self, + closure_def_id: DefId, + closure_substs: ty::ClosureSubsts<'tcx>, + ) -> Option { 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() @@ -1359,7 +1396,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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); @@ -1368,29 +1405,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Normalizes associated types in `value`, potentially returning /// new obligations that must further be processed. - pub fn partially_normalize_associated_types_in(&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( + &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 @@ -1423,14 +1463,15 @@ impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> { 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)), } } @@ -1440,7 +1481,7 @@ impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> { values: Types(ExpectedFound { expected: tcx.types.err, found: tcx.types.err, - }) + }), } } } @@ -1482,24 +1523,25 @@ impl<'tcx> SubregionOrigin<'tcx> { } } - pub fn from_obligation_cause(cause: &traits::ObligationCause<'tcx>, - default: F) - -> Self - where F: FnOnce() -> Self + pub fn from_obligation_cause(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::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::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(), } @@ -1534,8 +1576,10 @@ EnumTypeFoldableImpl! { 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 + ) } }