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::resolve::resolve_and_force_all_but_regions;
23 pub use self::resolve::{force_all, not_regions};
24 pub use self::resolve::{force_ivar};
25 pub use self::resolve::{force_tvar, force_rvar};
26 pub use self::resolve::{resolve_ivar, resolve_all};
27 pub use self::resolve::{resolve_nested_tvar};
28 pub use self::resolve::{resolve_rvar};
29 pub use self::skolemize::TypeSkolemizer;
32 use middle::subst::Substs;
33 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
34 use middle::ty::replace_late_bound_regions;
35 use middle::ty::{mod, Ty};
36 use middle::ty_fold::{HigherRankedFoldable, TypeFolder, TypeFoldable};
37 use std::cell::{RefCell};
41 use syntax::codemap::Span;
42 use util::common::indent;
43 use util::nodemap::FnvHashMap;
44 use util::ppaux::{ty_to_string};
45 use util::ppaux::{trait_ref_to_string, Repr};
47 use self::coercion::Coerce;
48 use self::combine::{Combine, CombineFields};
49 use self::region_inference::{RegionVarBindings, RegionSnapshot};
50 use self::resolve::{resolver};
51 use self::equate::Equate;
54 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
55 use self::error_reporting::ErrorReporting;
61 pub mod error_reporting;
63 pub mod higher_ranked;
66 pub mod region_inference;
70 pub mod type_variable;
73 pub type Bound<T> = Option<T>;
75 pub type cres<'tcx, T> = Result<T,ty::type_err<'tcx>>; // "combine result"
76 pub type ures<'tcx> = cres<'tcx, ()>; // "unify result"
77 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
78 pub type CoerceResult<'tcx> = cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
80 pub struct InferCtxt<'a, 'tcx: 'a> {
81 pub tcx: &'a ty::ctxt<'tcx>,
83 // We instantiate UnificationTable with bounds<Ty> because the
84 // types that might instantiate a general type variable have an
85 // order, represented by its upper and lower bounds.
86 type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
88 // Map from integral variable to the kind of integer it represents
89 int_unification_table:
90 RefCell<UnificationTable<ty::IntVid, Option<IntVarValue>>>,
92 // Map from floating variable to the kind of float it represents
93 float_unification_table:
94 RefCell<UnificationTable<ty::FloatVid, Option<ast::FloatTy>>>,
96 // For region variables.
98 RegionVarBindings<'a, 'tcx>,
101 /// Why did we require that the two types be related?
103 /// See `error_reporting.rs` for more details
104 #[deriving(Clone, Show)]
105 pub enum TypeOrigin {
106 // Not yet categorized in a better way
109 // Checking that method of impl is compatible with trait
110 MethodCompatCheck(Span),
112 // Checking that this expression can be assigned where it needs to be
113 // FIXME(eddyb) #11161 is the original Expr required?
114 ExprAssignable(Span),
116 // Relating trait refs when resolving vtables
117 RelateTraitRefs(Span),
119 // Relating self types when resolving vtables
120 RelateSelfType(Span),
122 // Relating trait type parameters to those found in impl etc
123 RelateOutputImplTypes(Span),
125 // Computing common supertype in the arms of a match expression
126 MatchExpressionArm(Span, Span),
128 // Computing common supertype in an if expression
131 // Computing common supertype of an if expression with no else counter-part
132 IfExpressionWithNoElse(Span)
135 /// See `error_reporting.rs` for more details
136 #[deriving(Clone, Show)]
137 pub enum ValuePairs<'tcx> {
138 Types(ty::expected_found<Ty<'tcx>>),
139 TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>),
142 /// The trace designates the path through inference that we took to
143 /// encounter an error or subtyping constraint.
145 /// See `error_reporting.rs` for more details.
146 #[deriving(Clone, Show)]
147 pub struct TypeTrace<'tcx> {
149 values: ValuePairs<'tcx>,
152 /// The origin of a `r1 <= r2` constraint.
154 /// See `error_reporting.rs` for more details
155 #[deriving(Clone, Show)]
156 pub enum SubregionOrigin<'tcx> {
157 // Arose from a subtyping relation
158 Subtype(TypeTrace<'tcx>),
160 // Stack-allocated closures cannot outlive innermost loop
161 // or function so as to ensure we only require finite stack
162 InfStackClosure(Span),
164 // Invocation of closure must be within its lifetime
167 // Dereference of reference must be within its lifetime
170 // Closure bound must not outlive captured free variables
171 FreeVariable(Span, ast::NodeId),
173 // Proc upvars must be 'static
174 ProcCapture(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 // When closing over a variable in a closure/proc, ensure that the
184 // type of the variable outlives the lifetime bound.
185 RelateProcBound(Span, ast::NodeId, Ty<'tcx>),
187 // Some type parameter was instantiated with the given type,
188 // and that type must outlive some region.
189 RelateParamBound(Span, Ty<'tcx>),
191 // The given region parameter was instantiated with a region
192 // that must outlive some other region.
193 RelateRegionParamBound(Span),
195 // A bound placed on type parameters that states that must outlive
196 // the moment of their instantiation.
197 RelateDefaultParamBound(Span, Ty<'tcx>),
199 // Creating a pointer `b` to contents of another reference
202 // Creating a pointer `b` to contents of an upvar
203 ReborrowUpvar(Span, ty::UpvarId),
205 // (&'a &'b T) where a >= b
206 ReferenceOutlivesReferent(Ty<'tcx>, Span),
208 // The type T of an expression E must outlive the lifetime for E.
209 ExprTypeIsNotInScope(Ty<'tcx>, Span),
211 // A `ref b` whose region does not enclose the decl site
212 BindingTypeIsNotValidAtDecl(Span),
214 // Regions appearing in a method receiver must outlive method call
217 // Regions appearing in a function argument must outlive func call
220 // Region in return type of invoked fn must enclose call
223 // Region resulting from a `&` expr must enclose the `&` expr
226 // An auto-borrow that does not enclose the expr where it occurs
230 /// Times when we replace late-bound regions with variables:
231 #[deriving(Clone, Show)]
232 pub enum LateBoundRegionConversionTime {
233 /// when a fn is called
236 /// when two higher-ranked types are compared
240 /// Reasons to create a region inference variable
242 /// See `error_reporting.rs` for more details
243 #[deriving(Clone, Show)]
244 pub enum RegionVariableOrigin<'tcx> {
245 // Region variables created for ill-categorized reasons,
246 // mostly indicates places in need of refactoring
249 // Regions created by a `&P` or `[...]` pattern
252 // Regions created by `&` operator
255 // Regions created by `&[...]` literal
258 // Regions created as part of an autoref of a method receiver
261 // Regions created as part of an automatic coercion
262 Coercion(TypeTrace<'tcx>),
264 // Region variables created as the values for early-bound regions
265 EarlyBoundRegion(Span, ast::Name),
267 // Region variables created for bound regions
268 // in a function or method that is called
269 LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
271 UpvarRegion(ty::UpvarId, Span),
273 BoundRegionInCoherence(ast::Name),
278 unresolved_int_ty(IntVid),
279 unresolved_float_ty(FloatVid),
283 pub fn fixup_err_to_string(f: fixup_err) -> String {
285 unresolved_int_ty(_) => {
286 "cannot determine the type of this integer; add a suffix to \
287 specify the type explicitly".to_string()
289 unresolved_float_ty(_) => {
290 "cannot determine the type of this number; add a suffix to specify \
291 the type explicitly".to_string()
293 unresolved_ty(_) => "unconstrained type".to_string(),
297 pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
298 -> InferCtxt<'a, 'tcx> {
301 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
302 int_unification_table: RefCell::new(UnificationTable::new()),
303 float_unification_table: RefCell::new(UnificationTable::new()),
304 region_vars: RegionVarBindings::new(tcx),
308 pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
316 * Computes the least upper-bound of `a` and `b`. If this is
317 * not possible, reports an error and returns ty::err.
320 debug!("common_supertype({}, {})",
321 a.repr(cx.tcx), b.repr(cx.tcx));
323 let trace = TypeTrace {
325 values: Types(expected_found(a_is_expected, a, b))
329 cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
333 cx.report_and_explain_type_error(trace, err);
339 pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
346 debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
348 cx.sub_types(a_is_expected, origin, a, b)
352 pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
356 debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
358 let trace = TypeTrace {
359 origin: Misc(codemap::DUMMY_SP),
360 values: Types(expected_found(true, a, b))
362 cx.sub(true, trace).tys(a, b).to_ures()
366 pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
367 a: Ty<'tcx>, b: Ty<'tcx>)
369 debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
371 let trace = TypeTrace {
372 origin: Misc(codemap::DUMMY_SP),
373 values: Types(expected_found(true, a, b))
375 cx.equate(true, trace).tys(a, b)
379 pub fn mk_subr<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
380 origin: SubregionOrigin<'tcx>,
383 debug!("mk_subr({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
384 let snapshot = cx.region_vars.start_snapshot();
385 cx.region_vars.make_subregion(origin, a, b);
386 cx.region_vars.commit(snapshot);
389 pub fn verify_param_bound<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
390 origin: SubregionOrigin<'tcx>,
391 param_ty: ty::ParamTy,
393 bs: Vec<ty::Region>) {
394 debug!("verify_param_bound({}, {} <: {})",
395 param_ty.repr(cx.tcx),
399 cx.region_vars.verify_param_bound(origin, param_ty, a, bs);
402 pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
409 debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
411 || cx.eq_types(a_is_expected, origin, a, b))
414 pub fn mk_sub_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
417 a: Rc<ty::TraitRef<'tcx>>,
418 b: Rc<ty::TraitRef<'tcx>>)
421 debug!("mk_sub_trait_refs({} <: {})",
422 a.repr(cx.tcx), b.repr(cx.tcx));
424 || cx.sub_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
427 fn expected_found<T>(a_is_expected: bool,
430 -> ty::expected_found<T>
433 ty::expected_found {expected: a, found: b}
435 ty::expected_found {expected: b, found: a}
439 pub fn mk_coercety<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
444 -> CoerceResult<'tcx> {
445 debug!("mk_coercety({} -> {})", a.repr(cx.tcx), b.repr(cx.tcx));
448 let trace = TypeTrace {
450 values: Types(expected_found(a_is_expected, a, b))
452 Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b)
457 // See comment on the type `resolve_state` below
458 pub fn resolve_type<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
463 let mut resolver = resolver(cx, modes, span);
464 cx.commit_unconditionally(|| resolver.resolve_type_chk(a))
467 pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
468 -> fres<ty::Region> {
469 let mut resolver = resolver(cx, modes, None);
470 resolver.resolve_region_chk(r)
474 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
475 -> Result<T,ty::type_err<'tcx>>;
478 impl<'tcx> then<'tcx> for ures<'tcx> {
479 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err<'tcx>>)
480 -> Result<T,ty::type_err<'tcx>> {
481 self.and_then(|_i| f())
486 fn to_ures(&self) -> ures<'tcx>;
489 impl<'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
490 fn to_ures(&self) -> ures<'tcx> {
492 Ok(ref _v) => Ok(()),
493 Err(ref e) => Err((*e))
498 trait CresCompare<'tcx, T> {
499 fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T>;
502 impl<'tcx, T:Clone + PartialEq> CresCompare<'tcx, T> for cres<'tcx, T> {
503 fn compare(&self, t: T, f: || -> ty::type_err<'tcx>) -> cres<'tcx, T> {
504 (*self).clone().and_then(|s| {
514 pub fn uok<'tcx>() -> ures<'tcx> {
518 pub struct CombinedSnapshot {
519 type_snapshot: type_variable::Snapshot,
520 int_snapshot: unify::Snapshot<ty::IntVid>,
521 float_snapshot: unify::Snapshot<ty::FloatVid>,
522 region_vars_snapshot: RegionSnapshot,
525 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
526 pub fn skolemize<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
527 t.fold_with(&mut self.skolemizer())
530 pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
532 ty::ty_infer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
537 pub fn skolemizer<'a>(&'a self) -> TypeSkolemizer<'a, 'tcx> {
538 skolemize::TypeSkolemizer::new(self)
541 pub fn combine_fields<'a>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
542 -> CombineFields<'a, 'tcx> {
543 CombineFields {infcx: self,
544 a_is_expected: a_is_expected,
548 pub fn equate<'a>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
549 -> Equate<'a, 'tcx> {
550 Equate(self.combine_fields(a_is_expected, trace))
553 pub fn sub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
555 Sub(self.combine_fields(a_is_expected, trace))
558 pub fn lub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
560 Lub(self.combine_fields(a_is_expected, trace))
563 fn start_snapshot(&self) -> CombinedSnapshot {
565 type_snapshot: self.type_variables.borrow_mut().snapshot(),
566 int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
567 float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
568 region_vars_snapshot: self.region_vars.start_snapshot(),
572 fn rollback_to(&self, snapshot: CombinedSnapshot) {
574 let CombinedSnapshot { type_snapshot,
577 region_vars_snapshot } = snapshot;
581 .rollback_to(type_snapshot);
582 self.int_unification_table
584 .rollback_to(int_snapshot);
585 self.float_unification_table
587 .rollback_to(float_snapshot);
589 .rollback_to(region_vars_snapshot);
592 fn commit_from(&self, snapshot: CombinedSnapshot) {
593 debug!("commit_from!");
594 let CombinedSnapshot { type_snapshot,
597 region_vars_snapshot } = snapshot;
601 .commit(type_snapshot);
602 self.int_unification_table
604 .commit(int_snapshot);
605 self.float_unification_table
607 .commit(float_snapshot);
609 .commit(region_vars_snapshot);
612 /// Execute `f` and commit the bindings
613 pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
615 let snapshot = self.start_snapshot();
617 self.commit_from(snapshot);
621 /// Execute `f` and commit the bindings if successful
622 pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
623 self.commit_unconditionally(|| self.try(|| f()))
626 /// Execute `f`, unroll bindings on panic
627 pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
629 let snapshot = self.start_snapshot();
631 debug!("try() -- r.is_ok() = {}", r.is_ok());
634 self.commit_from(snapshot);
637 self.rollback_to(snapshot);
643 /// Execute `f` then unroll any bindings it creates
644 pub fn probe<R>(&self, f: || -> R) -> R {
646 let snapshot = self.start_snapshot();
648 self.rollback_to(snapshot);
652 pub fn add_given(&self,
656 self.region_vars.add_given(sub, sup);
659 pub fn sub_types(&self,
666 debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
667 self.commit_if_ok(|| {
668 let trace = TypeTrace {
670 values: Types(expected_found(a_is_expected, a, b))
672 self.sub(a_is_expected, trace).tys(a, b).to_ures()
676 pub fn eq_types(&self,
683 self.commit_if_ok(|| {
684 let trace = TypeTrace {
686 values: Types(expected_found(a_is_expected, a, b))
688 self.equate(a_is_expected, trace).tys(a, b).to_ures()
692 pub fn sub_trait_refs(&self,
695 a: Rc<ty::TraitRef<'tcx>>,
696 b: Rc<ty::TraitRef<'tcx>>)
699 debug!("sub_trait_refs({} <: {})",
702 self.commit_if_ok(|| {
703 let trace = TypeTrace {
705 values: TraitRefs(expected_found(a_is_expected,
706 a.clone(), b.clone()))
708 self.sub(a_is_expected, trace).trait_refs(&*a, &*b).to_ures()
713 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
714 pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
720 pub fn next_ty_var(&self) -> Ty<'tcx> {
721 ty::mk_var(self.tcx, self.next_ty_var_id(false))
724 pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
725 ty::mk_var(self.tcx, self.next_ty_var_id(true))
728 pub fn next_ty_vars(&self, n: uint) -> Vec<Ty<'tcx>> {
729 Vec::from_fn(n, |_i| self.next_ty_var())
732 pub fn next_int_var_id(&self) -> IntVid {
733 self.int_unification_table
738 pub fn next_float_var_id(&self) -> FloatVid {
739 self.float_unification_table
744 pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>) -> ty::Region {
745 ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
748 pub fn region_vars_for_defs(&self,
750 defs: &[ty::RegionParameterDef])
753 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
757 pub fn fresh_substs_for_generics(&self,
759 generics: &ty::Generics<'tcx>)
760 -> subst::Substs<'tcx>
763 * Given a set of generics defined on a type or impl, returns
764 * a substitution mapping each type/region parameter to a
765 * fresh inference variable.
770 |_| self.next_ty_var());
772 generics.regions.map(
773 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
774 subst::Substs::new(type_params, region_params)
777 pub fn fresh_substs_for_trait(&self,
779 generics: &ty::Generics<'tcx>,
781 -> subst::Substs<'tcx>
784 * Given a set of generics defined on a trait, returns a
785 * substitution mapping each output type/region parameter to a
786 * fresh inference variable, and mapping the self type to
790 assert!(generics.types.len(subst::SelfSpace) == 1);
791 assert!(generics.types.len(subst::FnSpace) == 0);
792 assert!(generics.regions.len(subst::SelfSpace) == 0);
793 assert!(generics.regions.len(subst::FnSpace) == 0);
795 let type_parameter_count = generics.types.len(subst::TypeSpace);
796 let type_parameters = self.next_ty_vars(type_parameter_count);
798 let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
799 let regions = self.region_vars_for_defs(span, region_param_defs);
801 let assoc_type_parameter_count = generics.types.len(subst::AssocSpace);
802 let assoc_type_parameters = self.next_ty_vars(assoc_type_parameter_count);
804 subst::Substs::new_trait(type_parameters, regions, assoc_type_parameters, self_ty)
807 pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {
808 self.region_vars.new_bound(debruijn)
811 pub fn resolve_regions_and_report_errors(&self) {
812 let errors = self.region_vars.resolve_regions();
813 self.report_region_errors(&errors); // see error_reporting.rs
816 pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
817 ty_to_string(self.tcx,
818 self.resolve_type_vars_if_possible(t))
821 pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
822 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
823 format!("({})", tstrs.connect(", "))
826 pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
827 let t = self.resolve_type_vars_in_trait_ref_if_possible(&**t);
828 trait_ref_to_string(self.tcx, &t)
831 pub fn contains_unbound_type_variables(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
832 match resolve_type(self,
834 typ, resolve_nested_tvar | resolve_ivar) {
835 Ok(new_type) => new_type,
840 pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
842 ty::ty_infer(ty::TyVar(v)) => {
843 self.type_variables.borrow()
848 ty::ty_infer(ty::IntVar(v)) => {
853 ty::ty_infer(ty::FloatVar(v)) => {
864 pub fn resolve_type_vars_if_possible(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
865 match resolve_type(self,
867 typ, resolve_nested_tvar | resolve_ivar) {
868 Ok(new_type) => new_type,
873 pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
874 trait_ref: &ty::TraitRef<'tcx>)
875 -> ty::TraitRef<'tcx> {
876 // make up a dummy type just to reuse/abuse the resolve machinery
877 let dummy0 = ty::mk_trait(self.tcx,
878 (*trait_ref).clone(),
879 ty::region_existential_bound(ty::ReStatic));
880 let dummy1 = self.resolve_type_vars_if_possible(dummy0);
882 ty::ty_trait(box ty::TyTrait { ref principal, .. }) => {
887 format!("resolve_type_vars_if_possible() yielded {} \
888 when supplied with {}",
889 self.ty_to_string(dummy0),
890 self.ty_to_string(dummy1)).as_slice());
895 // [Note-Type-error-reporting]
896 // An invariant is that anytime the expected or actual type is ty_err (the special
897 // error type, meaning that an error occurred when typechecking this expression),
898 // this is a derived error. The error cascaded from another error (that was already
899 // reported), so it's not useful to display it to the user.
900 // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
901 // type_error_message, and report_mismatched_types -- implement this logic.
902 // They check if either the actual or expected type is ty_err, and don't print the error
903 // in this case. The typechecker should only ever report type errors involving mismatched
904 // types using one of these four methods, and should not call span_err directly for such
906 pub fn type_error_message_str(&self,
908 mk_msg: |Option<String>, String| -> String,
910 err: Option<&ty::type_err<'tcx>>) {
911 self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
914 pub fn type_error_message_str_with_expected(&self,
916 mk_msg: |Option<String>,
919 expected_ty: Option<Ty<'tcx>>,
921 err: Option<&ty::type_err<'tcx>>) {
922 debug!("hi! expected_ty = {}, actual_ty = {}", expected_ty, actual_ty);
924 let resolved_expected = expected_ty.map(|e_ty| {
925 self.resolve_type_vars_if_possible(e_ty)
928 match resolved_expected {
929 Some(t) if ty::type_is_error(t) => (),
931 let error_str = err.map_or("".to_string(), |t_err| {
932 format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
935 self.tcx.sess.span_err(sp, format!("{}{}",
936 mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
937 error_str).as_slice());
939 for err in err.iter() {
940 ty::note_and_explain_type_err(self.tcx, *err)
946 pub fn type_error_message(&self,
948 mk_msg: |String| -> String,
950 err: Option<&ty::type_err<'tcx>>) {
951 let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
953 // Don't report an error if actual type is ty_err.
954 if ty::type_is_error(actual_ty) {
958 self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
961 pub fn report_mismatched_types(&self,
965 err: &ty::type_err<'tcx>) {
966 let trace = TypeTrace {
968 values: Types(ty::expected_found {
973 self.report_and_explain_type_error(trace, err);
976 pub fn replace_late_bound_regions_with_fresh_var<T>(
979 lbrct: LateBoundRegionConversionTime,
981 -> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
982 where T : HigherRankedFoldable<'tcx>
984 ty::replace_late_bound_regions(
987 |br, _| self.next_region_var(LateBoundRegion(span, br, lbrct)))
991 impl<'tcx> TypeTrace<'tcx> {
992 pub fn span(&self) -> Span {
996 pub fn dummy() -> TypeTrace<'tcx> {
998 origin: Misc(codemap::DUMMY_SP),
999 values: Types(ty::expected_found {
1000 expected: ty::mk_err(),
1001 found: ty::mk_err(),
1007 impl<'tcx> Repr<'tcx> for TypeTrace<'tcx> {
1008 fn repr(&self, tcx: &ty::ctxt) -> String {
1009 format!("TypeTrace({})", self.origin.repr(tcx))
1014 pub fn span(&self) -> Span {
1016 MethodCompatCheck(span) => span,
1017 ExprAssignable(span) => span,
1019 RelateTraitRefs(span) => span,
1020 RelateSelfType(span) => span,
1021 RelateOutputImplTypes(span) => span,
1022 MatchExpressionArm(match_span, _) => match_span,
1023 IfExpression(span) => span,
1024 IfExpressionWithNoElse(span) => span
1029 impl<'tcx> Repr<'tcx> for TypeOrigin {
1030 fn repr(&self, tcx: &ty::ctxt) -> String {
1032 MethodCompatCheck(a) => {
1033 format!("MethodCompatCheck({})", a.repr(tcx))
1035 ExprAssignable(a) => {
1036 format!("ExprAssignable({})", a.repr(tcx))
1038 Misc(a) => format!("Misc({})", a.repr(tcx)),
1039 RelateTraitRefs(a) => {
1040 format!("RelateTraitRefs({})", a.repr(tcx))
1042 RelateSelfType(a) => {
1043 format!("RelateSelfType({})", a.repr(tcx))
1045 RelateOutputImplTypes(a) => {
1046 format!("RelateOutputImplTypes({})", a.repr(tcx))
1048 MatchExpressionArm(a, b) => {
1049 format!("MatchExpressionArm({}, {})", a.repr(tcx), b.repr(tcx))
1051 IfExpression(a) => {
1052 format!("IfExpression({})", a.repr(tcx))
1054 IfExpressionWithNoElse(a) => {
1055 format!("IfExpressionWithNoElse({})", a.repr(tcx))
1061 impl<'tcx> SubregionOrigin<'tcx> {
1062 pub fn span(&self) -> Span {
1064 Subtype(ref a) => a.span(),
1065 InfStackClosure(a) => a,
1066 InvokeClosure(a) => a,
1067 DerefPointer(a) => a,
1068 FreeVariable(a, _) => a,
1069 ProcCapture(a, _) => a,
1071 RelateObjectBound(a) => a,
1072 RelateProcBound(a, _, _) => a,
1073 RelateParamBound(a, _) => a,
1074 RelateRegionParamBound(a) => a,
1075 RelateDefaultParamBound(a, _) => a,
1077 ReborrowUpvar(a, _) => a,
1078 ReferenceOutlivesReferent(_, a) => a,
1079 ExprTypeIsNotInScope(_, a) => a,
1080 BindingTypeIsNotValidAtDecl(a) => a,
1090 impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
1091 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1094 format!("Subtype({})", a.repr(tcx))
1096 InfStackClosure(a) => {
1097 format!("InfStackClosure({})", a.repr(tcx))
1099 InvokeClosure(a) => {
1100 format!("InvokeClosure({})", a.repr(tcx))
1102 DerefPointer(a) => {
1103 format!("DerefPointer({})", a.repr(tcx))
1105 FreeVariable(a, b) => {
1106 format!("FreeVariable({}, {})", a.repr(tcx), b)
1108 ProcCapture(a, b) => {
1109 format!("ProcCapture({}, {})", a.repr(tcx), b)
1112 format!("IndexSlice({})", a.repr(tcx))
1114 RelateObjectBound(a) => {
1115 format!("RelateObjectBound({})", a.repr(tcx))
1117 RelateProcBound(a, b, c) => {
1118 format!("RelateProcBound({},{},{})",
1123 RelateParamBound(a, b) => {
1124 format!("RelateParamBound({},{})",
1128 RelateRegionParamBound(a) => {
1129 format!("RelateRegionParamBound({})",
1132 RelateDefaultParamBound(a, b) => {
1133 format!("RelateDefaultParamBound({},{})",
1137 Reborrow(a) => format!("Reborrow({})", a.repr(tcx)),
1138 ReborrowUpvar(a, b) => {
1139 format!("ReborrowUpvar({},{})", a.repr(tcx), b)
1141 ReferenceOutlivesReferent(_, a) => {
1142 format!("ReferenceOutlivesReferent({})", a.repr(tcx))
1144 ExprTypeIsNotInScope(a, b) => {
1145 format!("ExprTypeIsNotInScope({}, {})",
1149 BindingTypeIsNotValidAtDecl(a) => {
1150 format!("BindingTypeIsNotValidAtDecl({})", a.repr(tcx))
1152 CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
1153 CallArg(a) => format!("CallArg({})", a.repr(tcx)),
1154 CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
1155 AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
1156 AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
1161 impl<'tcx> RegionVariableOrigin<'tcx> {
1162 pub fn span(&self) -> Span {
1164 MiscVariable(a) => a,
1165 PatternRegion(a) => a,
1166 AddrOfRegion(a) => a,
1167 AddrOfSlice(a) => a,
1169 Coercion(ref a) => a.span(),
1170 EarlyBoundRegion(a, _) => a,
1171 LateBoundRegion(a, _, _) => a,
1172 BoundRegionInCoherence(_) => codemap::DUMMY_SP,
1173 UpvarRegion(_, a) => a
1178 impl<'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
1179 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1181 MiscVariable(a) => {
1182 format!("MiscVariable({})", a.repr(tcx))
1184 PatternRegion(a) => {
1185 format!("PatternRegion({})", a.repr(tcx))
1187 AddrOfRegion(a) => {
1188 format!("AddrOfRegion({})", a.repr(tcx))
1190 AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)),
1191 Autoref(a) => format!("Autoref({})", a.repr(tcx)),
1192 Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
1193 EarlyBoundRegion(a, b) => {
1194 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1196 LateBoundRegion(a, b, c) => {
1197 format!("LateBoundRegion({},{},{})", a.repr(tcx), b.repr(tcx), c)
1199 BoundRegionInCoherence(a) => {
1200 format!("bound_regionInCoherence({})", a.repr(tcx))
1202 UpvarRegion(a, b) => {
1203 format!("UpvarRegion({}, {})", a.repr(tcx), b.repr(tcx))