1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! See doc.rs for documentation
13 #![allow(non_camel_case_types)]
15 pub use self::LateBoundRegionConversionTime::*;
16 pub use self::RegionVariableOrigin::*;
17 pub use self::SubregionOrigin::*;
18 pub use self::TypeOrigin::*;
19 pub use self::ValuePairs::*;
20 pub use self::fixup_err::*;
21 pub use middle::ty::IntVarValue;
22 pub use self::freshen::TypeFreshener;
25 use middle::subst::Substs;
26 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
27 use middle::ty::replace_late_bound_regions;
28 use middle::ty::{mod, Ty};
29 use middle::ty_fold::{TypeFolder, TypeFoldable};
30 use std::cell::{RefCell};
34 use syntax::codemap::Span;
35 use util::common::indent;
36 use util::nodemap::FnvHashMap;
37 use util::ppaux::{ty_to_string};
38 use util::ppaux::{Repr, UserString};
40 use self::coercion::Coerce;
41 use self::combine::{Combine, CombineFields};
42 use self::region_inference::{RegionVarBindings, RegionSnapshot};
43 use self::equate::Equate;
46 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
47 use self::error_reporting::ErrorReporting;
53 pub mod error_reporting;
58 pub mod region_inference;
62 pub mod type_variable;
65 pub type Bound<T> = Option<T>;
67 pub type cres<'tcx, T> = Result<T,ty::type_err<'tcx>>; // "combine result"
68 pub type ures<'tcx> = cres<'tcx, ()>; // "unify result"
69 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
70 pub type CoerceResult<'tcx> = cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
72 pub struct InferCtxt<'a, 'tcx: 'a> {
73 pub tcx: &'a ty::ctxt<'tcx>,
75 // We instantiate UnificationTable with bounds<Ty> because the
76 // types that might instantiate a general type variable have an
77 // order, represented by its upper and lower bounds.
78 type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
80 // Map from integral variable to the kind of integer it represents
81 int_unification_table:
82 RefCell<UnificationTable<ty::IntVid, Option<IntVarValue>>>,
84 // Map from floating variable to the kind of float it represents
85 float_unification_table:
86 RefCell<UnificationTable<ty::FloatVid, Option<ast::FloatTy>>>,
88 // For region variables.
90 RegionVarBindings<'a, 'tcx>,
93 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
94 /// region that each late-bound region was replaced with.
95 pub type SkolemizationMap = FnvHashMap<ty::BoundRegion,ty::Region>;
97 /// Why did we require that the two types be related?
99 /// See `error_reporting.rs` for more details
100 #[deriving(Clone, Copy, Show)]
101 pub enum TypeOrigin {
102 // Not yet categorized in a better way
105 // Checking that method of impl is compatible with trait
106 MethodCompatCheck(Span),
108 // Checking that this expression can be assigned where it needs to be
109 // FIXME(eddyb) #11161 is the original Expr required?
110 ExprAssignable(Span),
112 // Relating trait refs when resolving vtables
113 RelateTraitRefs(Span),
115 // Relating self types when resolving vtables
116 RelateSelfType(Span),
118 // Relating trait type parameters to those found in impl etc
119 RelateOutputImplTypes(Span),
121 // Computing common supertype in the arms of a match expression
122 MatchExpressionArm(Span, Span),
124 // Computing common supertype in an if expression
127 // Computing common supertype of an if expression with no else counter-part
128 IfExpressionWithNoElse(Span),
130 // Computing common supertype in a range expression
131 RangeExpression(Span),
134 EquatePredicate(Span),
137 /// See `error_reporting.rs` for more details
138 #[deriving(Clone, Show)]
139 pub enum ValuePairs<'tcx> {
140 Types(ty::expected_found<Ty<'tcx>>),
141 TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>),
142 PolyTraitRefs(ty::expected_found<ty::PolyTraitRef<'tcx>>),
145 /// The trace designates the path through inference that we took to
146 /// encounter an error or subtyping constraint.
148 /// See `error_reporting.rs` for more details.
149 #[deriving(Clone, Show)]
150 pub struct TypeTrace<'tcx> {
152 values: ValuePairs<'tcx>,
155 /// The origin of a `r1 <= r2` constraint.
157 /// See `error_reporting.rs` for more details
158 #[deriving(Clone, Show)]
159 pub enum SubregionOrigin<'tcx> {
160 // Arose from a subtyping relation
161 Subtype(TypeTrace<'tcx>),
163 // Stack-allocated closures cannot outlive innermost loop
164 // or function so as to ensure we only require finite stack
165 InfStackClosure(Span),
167 // Invocation of closure must be within its lifetime
170 // Dereference of reference must be within its lifetime
173 // Closure bound must not outlive captured free variables
174 FreeVariable(Span, ast::NodeId),
176 // Index into slice must be within its lifetime
179 // When casting `&'a T` to an `&'b Trait` object,
180 // relating `'a` to `'b`
181 RelateObjectBound(Span),
183 // Some type parameter was instantiated with the given type,
184 // and that type must outlive some region.
185 RelateParamBound(Span, Ty<'tcx>),
187 // The given region parameter was instantiated with a region
188 // that must outlive some other region.
189 RelateRegionParamBound(Span),
191 // A bound placed on type parameters that states that must outlive
192 // the moment of their instantiation.
193 RelateDefaultParamBound(Span, Ty<'tcx>),
195 // Creating a pointer `b` to contents of another reference
198 // Creating a pointer `b` to contents of an upvar
199 ReborrowUpvar(Span, ty::UpvarId),
201 // (&'a &'b T) where a >= b
202 ReferenceOutlivesReferent(Ty<'tcx>, Span),
204 // The type T of an expression E must outlive the lifetime for E.
205 ExprTypeIsNotInScope(Ty<'tcx>, Span),
207 // A `ref b` whose region does not enclose the decl site
208 BindingTypeIsNotValidAtDecl(Span),
210 // Regions appearing in a method receiver must outlive method call
213 // Regions appearing in a function argument must outlive func call
216 // Region in return type of invoked fn must enclose call
219 // Region resulting from a `&` expr must enclose the `&` expr
222 // An auto-borrow that does not enclose the expr where it occurs
226 /// Times when we replace late-bound regions with variables:
227 #[deriving(Clone, Copy, Show)]
228 pub enum LateBoundRegionConversionTime {
229 /// when a fn is called
232 /// when two higher-ranked types are compared
235 /// when projecting an associated type
236 AssocTypeProjection(ast::Name),
239 /// Reasons to create a region inference variable
241 /// See `error_reporting.rs` for more details
242 #[deriving(Clone, Show)]
243 pub enum RegionVariableOrigin<'tcx> {
244 // Region variables created for ill-categorized reasons,
245 // mostly indicates places in need of refactoring
248 // Regions created by a `&P` or `[...]` pattern
251 // Regions created by `&` operator
254 // Regions created by `&[...]` literal
257 // Regions created as part of an autoref of a method receiver
260 // Regions created as part of an automatic coercion
261 Coercion(TypeTrace<'tcx>),
263 // Region variables created as the values for early-bound regions
264 EarlyBoundRegion(Span, ast::Name),
266 // Region variables created for bound regions
267 // in a function or method that is called
268 LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
270 UpvarRegion(ty::UpvarId, Span),
272 BoundRegionInCoherence(ast::Name),
275 #[deriving(Copy, Show)]
277 unresolved_int_ty(IntVid),
278 unresolved_float_ty(FloatVid),
282 pub fn fixup_err_to_string(f: fixup_err) -> String {
284 unresolved_int_ty(_) => {
285 "cannot determine the type of this integer; add a suffix to \
286 specify the type explicitly".to_string()
288 unresolved_float_ty(_) => {
289 "cannot determine the type of this number; add a suffix to specify \
290 the type explicitly".to_string()
292 unresolved_ty(_) => "unconstrained type".to_string(),
296 pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
297 -> InferCtxt<'a, 'tcx> {
300 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
301 int_unification_table: RefCell::new(UnificationTable::new()),
302 float_unification_table: RefCell::new(UnificationTable::new()),
303 region_vars: RegionVarBindings::new(tcx),
307 /// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and
309 pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
316 debug!("common_supertype({}, {})",
317 a.repr(cx.tcx), b.repr(cx.tcx));
319 let trace = TypeTrace {
321 values: Types(expected_found(a_is_expected, a, b))
325 cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
329 cx.report_and_explain_type_error(trace, err);
335 pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
342 debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
344 cx.sub_types(a_is_expected, origin, a, b)
348 pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
352 debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
354 let trace = TypeTrace {
355 origin: Misc(codemap::DUMMY_SP),
356 values: Types(expected_found(true, a, b))
358 cx.sub(true, trace).tys(a, b).to_ures()
362 pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
363 a: Ty<'tcx>, b: Ty<'tcx>)
365 debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
367 let trace = TypeTrace {
368 origin: Misc(codemap::DUMMY_SP),
369 values: Types(expected_found(true, a, b))
371 cx.equate(true, trace).tys(a, b)
375 pub fn mk_subr<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
376 origin: SubregionOrigin<'tcx>,
379 debug!("mk_subr({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
380 let snapshot = cx.region_vars.start_snapshot();
381 cx.region_vars.make_subregion(origin, a, b);
382 cx.region_vars.commit(snapshot);
385 pub fn verify_param_bound<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
386 origin: SubregionOrigin<'tcx>,
387 param_ty: ty::ParamTy,
389 bs: Vec<ty::Region>) {
390 debug!("verify_param_bound({}, {} <: {})",
391 param_ty.repr(cx.tcx),
395 cx.region_vars.verify_param_bound(origin, param_ty, a, bs);
398 pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
405 debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
407 || cx.eq_types(a_is_expected, origin, a, b))
410 pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
413 a: ty::PolyTraitRef<'tcx>,
414 b: ty::PolyTraitRef<'tcx>)
417 debug!("mk_sub_trait_refs({} <: {})",
418 a.repr(cx.tcx), b.repr(cx.tcx));
420 || cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
423 fn expected_found<T>(a_is_expected: bool,
426 -> ty::expected_found<T>
429 ty::expected_found {expected: a, found: b}
431 ty::expected_found {expected: b, found: a}
435 pub fn mk_coercety<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
440 -> CoerceResult<'tcx> {
441 debug!("mk_coercety({} -> {})", a.repr(cx.tcx), b.repr(cx.tcx));
444 let trace = TypeTrace {
446 values: Types(expected_found(a_is_expected, a, b))
448 Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b)
454 fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
456 F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
459 impl<'tcx> then<'tcx> for ures<'tcx> {
460 fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
462 F: FnOnce() -> Result<T, ty::type_err<'tcx>>,
464 self.and_then(move |_| f())
469 fn to_ures(&self) -> ures<'tcx>;
472 impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
473 fn to_ures(&self) -> ures<'tcx> {
475 Ok(ref _v) => Ok(()),
476 Err(ref e) => Err((*e))
481 trait CresCompare<'tcx, T> {
482 fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
483 F: FnOnce() -> ty::type_err<'tcx>;
486 impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
487 fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
488 F: FnOnce() -> ty::type_err<'tcx>,
490 (*self).clone().and_then(move |s| {
500 pub fn uok<'tcx>() -> ures<'tcx> {
504 #[must_use = "once you start a snapshot, you should always consume it"]
505 pub struct CombinedSnapshot {
506 type_snapshot: type_variable::Snapshot,
507 int_snapshot: unify::Snapshot<ty::IntVid>,
508 float_snapshot: unify::Snapshot<ty::FloatVid>,
509 region_vars_snapshot: RegionSnapshot,
512 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
513 pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
514 t.fold_with(&mut self.freshener())
517 pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
519 ty::ty_infer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
524 pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
525 freshen::TypeFreshener::new(self)
528 pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
529 use middle::ty::UnconstrainedNumeric::{Neither, UnconstrainedInt, UnconstrainedFloat};
531 ty::ty_infer(ty::IntVar(vid)) => {
532 match self.int_unification_table.borrow_mut().get(self.tcx, vid).value {
533 None => UnconstrainedInt,
537 ty::ty_infer(ty::FloatVar(vid)) => {
538 match self.float_unification_table.borrow_mut().get(self.tcx, vid).value {
539 None => return UnconstrainedFloat,
547 pub fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
548 -> CombineFields<'b, 'tcx> {
549 CombineFields {infcx: self,
550 a_is_expected: a_is_expected,
554 pub fn equate<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
555 -> Equate<'b, 'tcx> {
556 Equate(self.combine_fields(a_is_expected, trace))
559 pub fn sub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
561 Sub(self.combine_fields(a_is_expected, trace))
564 pub fn lub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
566 Lub(self.combine_fields(a_is_expected, trace))
569 fn start_snapshot(&self) -> CombinedSnapshot {
571 type_snapshot: self.type_variables.borrow_mut().snapshot(),
572 int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
573 float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
574 region_vars_snapshot: self.region_vars.start_snapshot(),
578 fn rollback_to(&self, snapshot: CombinedSnapshot) {
580 let CombinedSnapshot { type_snapshot,
583 region_vars_snapshot } = snapshot;
587 .rollback_to(type_snapshot);
588 self.int_unification_table
590 .rollback_to(int_snapshot);
591 self.float_unification_table
593 .rollback_to(float_snapshot);
595 .rollback_to(region_vars_snapshot);
598 fn commit_from(&self, snapshot: CombinedSnapshot) {
599 debug!("commit_from!");
600 let CombinedSnapshot { type_snapshot,
603 region_vars_snapshot } = snapshot;
607 .commit(type_snapshot);
608 self.int_unification_table
610 .commit(int_snapshot);
611 self.float_unification_table
613 .commit(float_snapshot);
615 .commit(region_vars_snapshot);
618 /// Execute `f` and commit the bindings
619 pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
623 let snapshot = self.start_snapshot();
625 self.commit_from(snapshot);
629 /// Execute `f` and commit the bindings if successful
630 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
631 F: FnOnce() -> Result<T, E>
633 self.commit_unconditionally(move || self.try(move |_| f()))
636 /// Execute `f`, unroll bindings on panic
637 pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
638 F: FnOnce(&CombinedSnapshot) -> Result<T, E>
641 let snapshot = self.start_snapshot();
642 let r = f(&snapshot);
643 debug!("try() -- r.is_ok() = {}", r.is_ok());
646 self.commit_from(snapshot);
649 self.rollback_to(snapshot);
655 /// Execute `f` then unroll any bindings it creates
656 pub fn probe<R, F>(&self, f: F) -> R where
657 F: FnOnce(&CombinedSnapshot) -> R,
660 let snapshot = self.start_snapshot();
661 let r = f(&snapshot);
662 self.rollback_to(snapshot);
666 pub fn add_given(&self,
670 self.region_vars.add_given(sub, sup);
673 pub fn sub_types(&self,
680 debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
681 self.commit_if_ok(|| {
682 let trace = TypeTrace {
684 values: Types(expected_found(a_is_expected, a, b))
686 self.sub(a_is_expected, trace).tys(a, b).to_ures()
690 pub fn eq_types(&self,
697 self.commit_if_ok(|| {
698 let trace = TypeTrace {
700 values: Types(expected_found(a_is_expected, a, b))
702 self.equate(a_is_expected, trace).tys(a, b).to_ures()
706 pub fn sub_trait_refs(&self,
709 a: Rc<ty::TraitRef<'tcx>>,
710 b: Rc<ty::TraitRef<'tcx>>)
713 debug!("sub_trait_refs({} <: {})",
716 self.commit_if_ok(|| {
717 let trace = TypeTrace {
719 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
721 self.sub(a_is_expected, trace).trait_refs(&*a, &*b).to_ures()
725 pub fn sub_poly_trait_refs(&self,
728 a: ty::PolyTraitRef<'tcx>,
729 b: ty::PolyTraitRef<'tcx>)
732 debug!("sub_poly_trait_refs({} <: {})",
735 self.commit_if_ok(|| {
736 let trace = TypeTrace {
738 values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
740 self.sub(a_is_expected, trace).binders(&a, &b).to_ures()
744 pub fn skolemize_late_bound_regions<T>(&self,
745 value: &ty::Binder<T>,
746 snapshot: &CombinedSnapshot)
747 -> (T, SkolemizationMap)
748 where T : TypeFoldable<'tcx> + Repr<'tcx>
750 /*! See `higher_ranked::skolemize_late_bound_regions` */
752 higher_ranked::skolemize_late_bound_regions(self, value, snapshot)
755 pub fn leak_check(&self,
756 skol_map: &SkolemizationMap,
757 snapshot: &CombinedSnapshot)
760 /*! See `higher_ranked::leak_check` */
762 match higher_ranked::leak_check(self, skol_map, snapshot) {
764 Err((br, r)) => Err(ty::terr_regions_insufficiently_polymorphic(br, r))
768 pub fn plug_leaks<T>(&self,
769 skol_map: SkolemizationMap,
770 snapshot: &CombinedSnapshot,
773 where T : TypeFoldable<'tcx> + Repr<'tcx>
775 /*! See `higher_ranked::plug_leaks` */
777 higher_ranked::plug_leaks(self, skol_map, snapshot, value)
780 pub fn equality_predicate(&self,
782 predicate: &ty::PolyEquatePredicate<'tcx>)
784 self.try(|snapshot| {
785 let (ty::EquatePredicate(a, b), skol_map) =
786 self.skolemize_late_bound_regions(predicate, snapshot);
787 let origin = EquatePredicate(span);
788 let () = try!(mk_eqty(self, false, origin, a, b));
789 self.leak_check(&skol_map, snapshot)
793 pub fn region_outlives_predicate(&self,
795 predicate: &ty::PolyRegionOutlivesPredicate)
797 self.try(|snapshot| {
798 let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
799 self.skolemize_late_bound_regions(predicate, snapshot);
800 let origin = RelateRegionParamBound(span);
801 let () = mk_subr(self, origin, r_b, r_a); // `b : a` ==> `a <= b`
802 self.leak_check(&skol_map, snapshot)
806 pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
812 pub fn next_ty_var(&self) -> Ty<'tcx> {
813 ty::mk_var(self.tcx, self.next_ty_var_id(false))
816 pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
817 ty::mk_var(self.tcx, self.next_ty_var_id(true))
820 pub fn next_ty_vars(&self, n: uint) -> Vec<Ty<'tcx>> {
821 range(0, n).map(|_i| self.next_ty_var()).collect()
824 pub fn next_int_var_id(&self) -> IntVid {
825 self.int_unification_table
830 pub fn next_float_var_id(&self) -> FloatVid {
831 self.float_unification_table
836 pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> ty::Region {
837 ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
840 pub fn region_vars_for_defs(&self,
842 defs: &[ty::RegionParameterDef])
845 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
849 /// Given a set of generics defined on a type or impl, returns a substitution mapping each
850 /// type/region parameter to a fresh inference variable.
851 pub fn fresh_substs_for_generics(&self,
853 generics: &ty::Generics<'tcx>)
854 -> subst::Substs<'tcx>
858 |_| self.next_ty_var());
860 generics.regions.map(
861 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
862 subst::Substs::new(type_params, region_params)
865 /// Given a set of generics defined on a trait, returns a substitution mapping each output
866 /// type/region parameter to a fresh inference variable, and mapping the self type to
868 pub fn fresh_substs_for_trait(&self,
870 generics: &ty::Generics<'tcx>,
872 -> subst::Substs<'tcx>
875 assert!(generics.types.len(subst::SelfSpace) == 1);
876 assert!(generics.types.len(subst::FnSpace) == 0);
877 assert!(generics.regions.len(subst::SelfSpace) == 0);
878 assert!(generics.regions.len(subst::FnSpace) == 0);
880 let type_parameter_count = generics.types.len(subst::TypeSpace);
881 let type_parameters = self.next_ty_vars(type_parameter_count);
883 let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
884 let regions = self.region_vars_for_defs(span, region_param_defs);
886 subst::Substs::new_trait(type_parameters, regions, self_ty)
889 pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
890 self.region_vars.new_bound(debruijn)
893 pub fn resolve_regions_and_report_errors(&self, subject_node_id: ast::NodeId) {
894 let errors = self.region_vars.resolve_regions(subject_node_id);
895 self.report_region_errors(&errors); // see error_reporting.rs
898 pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
899 ty_to_string(self.tcx,
900 self.resolve_type_vars_if_possible(&t))
903 pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
904 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
905 format!("({})", tstrs.connect(", "))
908 pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
909 let t = self.resolve_type_vars_if_possible(&**t);
910 t.user_string(self.tcx)
913 pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
915 ty::ty_infer(ty::TyVar(v)) => {
916 // Not entirely obvious: if `typ` is a type variable,
917 // it can be resolved to an int/float variable, which
918 // can then be recursively resolved, hence the
919 // recursion. Note though that we prevent type
920 // variables from unifying to other type variables
921 // directly (though they may be embedded
922 // structurally), and we prevent cycles in any case,
923 // so this recursion should always be of very limited
925 self.type_variables.borrow()
927 .map(|t| self.shallow_resolve(t))
931 ty::ty_infer(ty::IntVar(v)) => {
936 ty::ty_infer(ty::FloatVar(v)) => {
947 pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) -> T {
949 * Where possible, replaces type/int/float variables in
950 * `value` with their final value. Note that region variables
951 * are unaffected. If a type variable has not been unified, it
952 * is left as is. This is an idempotent operation that does
953 * not affect inference state in any way and so you can do it
957 let mut r = resolve::OpportunisticTypeResolver::new(self);
958 value.fold_with(&mut r)
961 pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> fres<T> {
963 * Attempts to resolve all type/region variables in
964 * `value`. Region inference must have been run already (e.g.,
965 * by calling `resolve_regions_and_report_errors`). If some
966 * variable was never unified, an `Err` results.
968 * This method is idempotent, but it not typically not invoked
969 * except during the writeback phase.
972 resolve::fully_resolve(self, value)
975 // [Note-Type-error-reporting]
976 // An invariant is that anytime the expected or actual type is ty_err (the special
977 // error type, meaning that an error occurred when typechecking this expression),
978 // this is a derived error. The error cascaded from another error (that was already
979 // reported), so it's not useful to display it to the user.
980 // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
981 // type_error_message, and report_mismatched_types -- implement this logic.
982 // They check if either the actual or expected type is ty_err, and don't print the error
983 // in this case. The typechecker should only ever report type errors involving mismatched
984 // types using one of these four methods, and should not call span_err directly for such
986 pub fn type_error_message_str<M>(&self,
990 err: Option<&ty::type_err<'tcx>>) where
991 M: FnOnce(Option<String>, String) -> String,
993 self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
996 pub fn type_error_message_str_with_expected<M>(&self,
999 expected_ty: Option<Ty<'tcx>>,
1001 err: Option<&ty::type_err<'tcx>>) where
1002 M: FnOnce(Option<String>, String) -> String,
1004 debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty);
1006 let resolved_expected = expected_ty.map(|e_ty| self.resolve_type_vars_if_possible(&e_ty));
1008 match resolved_expected {
1009 Some(t) if ty::type_is_error(t) => (),
1011 let error_str = err.map_or("".to_string(), |t_err| {
1012 format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
1015 self.tcx.sess.span_err(sp, format!("{}{}",
1016 mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
1019 for err in err.iter() {
1020 ty::note_and_explain_type_err(self.tcx, *err)
1026 pub fn type_error_message<M>(&self,
1029 actual_ty: Ty<'tcx>,
1030 err: Option<&ty::type_err<'tcx>>) where
1031 M: FnOnce(String) -> String,
1033 let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
1035 // Don't report an error if actual type is ty_err.
1036 if ty::type_is_error(actual_ty) {
1040 self.type_error_message_str(sp,
1041 move |_e, a| { mk_msg(a) },
1042 self.ty_to_string(actual_ty), err);
1045 pub fn report_mismatched_types(&self,
1049 err: &ty::type_err<'tcx>) {
1050 let trace = TypeTrace {
1052 values: Types(ty::expected_found {
1057 self.report_and_explain_type_error(trace, err);
1060 pub fn replace_late_bound_regions_with_fresh_var<T>(
1063 lbrct: LateBoundRegionConversionTime,
1064 value: &ty::Binder<T>)
1065 -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
1066 where T : TypeFoldable<'tcx> + Repr<'tcx>
1068 ty::replace_late_bound_regions(
1071 |br, _| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1075 impl<'tcx> TypeTrace<'tcx> {
1076 pub fn span(&self) -> Span {
1080 pub fn dummy(tcx: &ty::ctxt<'tcx>) -> TypeTrace<'tcx> {
1082 origin: Misc(codemap::DUMMY_SP),
1083 values: Types(ty::expected_found {
1084 expected: tcx.types.err,
1085 found: tcx.types.err,
1091 impl<'tcx> Repr<'tcx> for TypeTrace<'tcx> {
1092 fn repr(&self, tcx: &ty::ctxt) -> String {
1093 format!("TypeTrace({})", self.origin.repr(tcx))
1098 pub fn span(&self) -> Span {
1100 MethodCompatCheck(span) => span,
1101 ExprAssignable(span) => span,
1103 RelateTraitRefs(span) => span,
1104 RelateSelfType(span) => span,
1105 RelateOutputImplTypes(span) => span,
1106 MatchExpressionArm(match_span, _) => match_span,
1107 IfExpression(span) => span,
1108 IfExpressionWithNoElse(span) => span,
1109 RangeExpression(span) => span,
1110 EquatePredicate(span) => span,
1115 impl<'tcx> Repr<'tcx> for TypeOrigin {
1116 fn repr(&self, tcx: &ty::ctxt) -> String {
1118 MethodCompatCheck(a) => {
1119 format!("MethodCompatCheck({})", a.repr(tcx))
1121 ExprAssignable(a) => {
1122 format!("ExprAssignable({})", a.repr(tcx))
1124 Misc(a) => format!("Misc({})", a.repr(tcx)),
1125 RelateTraitRefs(a) => {
1126 format!("RelateTraitRefs({})", a.repr(tcx))
1128 RelateSelfType(a) => {
1129 format!("RelateSelfType({})", a.repr(tcx))
1131 RelateOutputImplTypes(a) => {
1132 format!("RelateOutputImplTypes({})", a.repr(tcx))
1134 MatchExpressionArm(a, b) => {
1135 format!("MatchExpressionArm({}, {})", a.repr(tcx), b.repr(tcx))
1137 IfExpression(a) => {
1138 format!("IfExpression({})", a.repr(tcx))
1140 IfExpressionWithNoElse(a) => {
1141 format!("IfExpressionWithNoElse({})", a.repr(tcx))
1143 RangeExpression(a) => {
1144 format!("RangeExpression({})", a.repr(tcx))
1146 EquatePredicate(a) => {
1147 format!("EquatePredicate({})", a.repr(tcx))
1153 impl<'tcx> SubregionOrigin<'tcx> {
1154 pub fn span(&self) -> Span {
1156 Subtype(ref a) => a.span(),
1157 InfStackClosure(a) => a,
1158 InvokeClosure(a) => a,
1159 DerefPointer(a) => a,
1160 FreeVariable(a, _) => a,
1162 RelateObjectBound(a) => a,
1163 RelateParamBound(a, _) => a,
1164 RelateRegionParamBound(a) => a,
1165 RelateDefaultParamBound(a, _) => a,
1167 ReborrowUpvar(a, _) => a,
1168 ReferenceOutlivesReferent(_, a) => a,
1169 ExprTypeIsNotInScope(_, a) => a,
1170 BindingTypeIsNotValidAtDecl(a) => a,
1180 impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
1181 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1184 format!("Subtype({})", a.repr(tcx))
1186 InfStackClosure(a) => {
1187 format!("InfStackClosure({})", a.repr(tcx))
1189 InvokeClosure(a) => {
1190 format!("InvokeClosure({})", a.repr(tcx))
1192 DerefPointer(a) => {
1193 format!("DerefPointer({})", a.repr(tcx))
1195 FreeVariable(a, b) => {
1196 format!("FreeVariable({}, {})", a.repr(tcx), b)
1199 format!("IndexSlice({})", a.repr(tcx))
1201 RelateObjectBound(a) => {
1202 format!("RelateObjectBound({})", a.repr(tcx))
1204 RelateParamBound(a, b) => {
1205 format!("RelateParamBound({},{})",
1209 RelateRegionParamBound(a) => {
1210 format!("RelateRegionParamBound({})",
1213 RelateDefaultParamBound(a, b) => {
1214 format!("RelateDefaultParamBound({},{})",
1218 Reborrow(a) => format!("Reborrow({})", a.repr(tcx)),
1219 ReborrowUpvar(a, b) => {
1220 format!("ReborrowUpvar({},{})", a.repr(tcx), b)
1222 ReferenceOutlivesReferent(_, a) => {
1223 format!("ReferenceOutlivesReferent({})", a.repr(tcx))
1225 ExprTypeIsNotInScope(a, b) => {
1226 format!("ExprTypeIsNotInScope({}, {})",
1230 BindingTypeIsNotValidAtDecl(a) => {
1231 format!("BindingTypeIsNotValidAtDecl({})", a.repr(tcx))
1233 CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
1234 CallArg(a) => format!("CallArg({})", a.repr(tcx)),
1235 CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
1236 AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
1237 AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
1242 impl<'tcx> RegionVariableOrigin<'tcx> {
1243 pub fn span(&self) -> Span {
1245 MiscVariable(a) => a,
1246 PatternRegion(a) => a,
1247 AddrOfRegion(a) => a,
1248 AddrOfSlice(a) => a,
1250 Coercion(ref a) => a.span(),
1251 EarlyBoundRegion(a, _) => a,
1252 LateBoundRegion(a, _, _) => a,
1253 BoundRegionInCoherence(_) => codemap::DUMMY_SP,
1254 UpvarRegion(_, a) => a
1259 impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
1260 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1262 MiscVariable(a) => {
1263 format!("MiscVariable({})", a.repr(tcx))
1265 PatternRegion(a) => {
1266 format!("PatternRegion({})", a.repr(tcx))
1268 AddrOfRegion(a) => {
1269 format!("AddrOfRegion({})", a.repr(tcx))
1271 AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)),
1272 Autoref(a) => format!("Autoref({})", a.repr(tcx)),
1273 Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
1274 EarlyBoundRegion(a, b) => {
1275 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1277 LateBoundRegion(a, b, c) => {
1278 format!("LateBoundRegion({},{},{})", a.repr(tcx), b.repr(tcx), c)
1280 BoundRegionInCoherence(a) => {
1281 format!("bound_regionInCoherence({})", a.repr(tcx))
1283 UpvarRegion(a, b) => {
1284 format!("UpvarRegion({}, {})", a.repr(tcx), b.repr(tcx))