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 middle::ty::IntVarValue;
16 pub use self::resolve::resolve_and_force_all_but_regions;
17 pub use self::resolve::{force_all, not_regions};
18 pub use self::resolve::{force_ivar};
19 pub use self::resolve::{force_tvar, force_rvar};
20 pub use self::resolve::{resolve_ivar, resolve_all};
21 pub use self::resolve::{resolve_nested_tvar};
22 pub use self::resolve::{resolve_rvar};
23 pub use self::skolemize::TypeSkolemizer;
26 use middle::subst::Substs;
27 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
30 use middle::ty_fold::TypeFolder;
31 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
32 use middle::typeck::infer::coercion::Coerce;
33 use middle::typeck::infer::combine::{Combine, CombineFields};
34 use middle::typeck::infer::region_inference::{RegionVarBindings,
36 use middle::typeck::infer::resolve::{resolver};
37 use middle::typeck::infer::equate::Equate;
38 use middle::typeck::infer::sub::Sub;
39 use middle::typeck::infer::lub::Lub;
40 use middle::typeck::infer::unify::{UnificationTable};
41 use middle::typeck::infer::error_reporting::ErrorReporting;
42 use std::cell::{RefCell};
43 use std::collections::HashMap;
47 use syntax::codemap::Span;
48 use util::common::indent;
49 use util::ppaux::{bound_region_to_string, ty_to_string, trait_ref_to_string, Repr};
55 pub mod error_reporting;
59 pub mod region_inference;
64 pub mod type_variable;
67 pub type Bound<T> = Option<T>;
69 pub type cres<T> = Result<T,ty::type_err>; // "combine result"
70 pub type ures = cres<()>; // "unify result"
71 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
72 pub type CoerceResult = cres<Option<ty::AutoAdjustment>>;
74 pub struct InferCtxt<'a, 'tcx: 'a> {
75 pub tcx: &'a ty::ctxt<'tcx>,
77 // We instantiate UnificationTable with bounds<ty::t> because the
78 // types that might instantiate a general type variable have an
79 // order, represented by its upper and lower bounds.
80 type_variables: RefCell<type_variable::TypeVariableTable>,
82 // Map from integral variable to the kind of integer it represents
83 int_unification_table:
84 RefCell<UnificationTable<ty::IntVid, Option<IntVarValue>>>,
86 // Map from floating variable to the kind of float it represents
87 float_unification_table:
88 RefCell<UnificationTable<ty::FloatVid, Option<ast::FloatTy>>>,
90 // For region variables.
92 RegionVarBindings<'a, 'tcx>,
95 /// Why did we require that the two types be related?
97 /// See `error_reporting.rs` for more details
100 // Not yet categorized in a better way
103 // Checking that method of impl is compatible with trait
104 MethodCompatCheck(Span),
106 // Checking that this expression can be assigned where it needs to be
107 // FIXME(eddyb) #11161 is the original Expr required?
108 ExprAssignable(Span),
110 // Relating trait refs when resolving vtables
111 RelateTraitRefs(Span),
113 // Relating self types when resolving vtables
114 RelateSelfType(Span),
116 // Relating trait type parameters to those found in impl etc
117 RelateOutputImplTypes(Span),
119 // Computing common supertype in the arms of a match expression
120 MatchExpressionArm(Span, Span),
122 // Computing common supertype in an if expression
126 /// See `error_reporting.rs` for more details
128 pub enum ValuePairs {
129 Types(ty::expected_found<ty::t>),
130 TraitRefs(ty::expected_found<Rc<ty::TraitRef>>),
133 /// The trace designates the path through inference that we took to
134 /// encounter an error or subtyping constraint.
136 /// See `error_reporting.rs` for more details.
138 pub struct TypeTrace {
143 /// The origin of a `r1 <= r2` constraint.
145 /// See `error_reporting.rs` for more details
147 pub enum SubregionOrigin {
148 // Arose from a subtyping relation
151 // Stack-allocated closures cannot outlive innermost loop
152 // or function so as to ensure we only require finite stack
153 InfStackClosure(Span),
155 // Invocation of closure must be within its lifetime
158 // Dereference of reference must be within its lifetime
161 // Closure bound must not outlive captured free variables
162 FreeVariable(Span, ast::NodeId),
164 // Proc upvars must be 'static
165 ProcCapture(Span, ast::NodeId),
167 // Index into slice must be within its lifetime
170 // When casting `&'a T` to an `&'b Trait` object,
171 // relating `'a` to `'b`
172 RelateObjectBound(Span),
174 // When closing over a variable in a closure/proc, ensure that the
175 // type of the variable outlives the lifetime bound.
176 RelateProcBound(Span, ast::NodeId, ty::t),
178 // The given type parameter was instantiated with the given type,
179 // and that type must outlive some region.
180 RelateParamBound(Span, ty::ParamTy, ty::t),
182 // The given region parameter was instantiated with a region
183 // that must outlive some other region.
184 RelateRegionParamBound(Span),
186 // A bound placed on type parameters that states that must outlive
187 // the moment of their instantiation.
188 RelateDefaultParamBound(Span, ty::t),
190 // Creating a pointer `b` to contents of another reference
193 // Creating a pointer `b` to contents of an upvar
194 ReborrowUpvar(Span, ty::UpvarId),
196 // (&'a &'b T) where a >= b
197 ReferenceOutlivesReferent(ty::t, Span),
199 // The type T of an expression E must outlive the lifetime for E.
200 ExprTypeIsNotInScope(ty::t, Span),
202 // A `ref b` whose region does not enclose the decl site
203 BindingTypeIsNotValidAtDecl(Span),
205 // Regions appearing in a method receiver must outlive method call
208 // Regions appearing in a function argument must outlive func call
211 // Region in return type of invoked fn must enclose call
214 // Region resulting from a `&` expr must enclose the `&` expr
217 // An auto-borrow that does not enclose the expr where it occurs
220 // Managed data cannot contain borrowed pointers.
224 /// Reasons to create a region inference variable
226 /// See `error_reporting.rs` for more details
228 pub enum RegionVariableOrigin {
229 // Region variables created for ill-categorized reasons,
230 // mostly indicates places in need of refactoring
233 // Regions created by a `&P` or `[...]` pattern
236 // Regions created by `&` operator
239 // Regions created by `&[...]` literal
242 // Regions created as part of an autoref of a method receiver
245 // Regions created as part of an automatic coercion
248 // Region variables created as the values for early-bound regions
249 EarlyBoundRegion(Span, ast::Name),
251 // Region variables created for bound regions
252 // in a function or method that is called
253 LateBoundRegion(Span, ty::BoundRegion),
255 // Region variables created for bound regions
256 // when doing subtyping/lub/glb computations
257 BoundRegionInFnType(Span, ty::BoundRegion),
259 UpvarRegion(ty::UpvarId, Span),
261 BoundRegionInCoherence(ast::Name),
266 unresolved_int_ty(IntVid),
267 unresolved_float_ty(FloatVid),
271 pub fn fixup_err_to_string(f: fixup_err) -> String {
273 unresolved_int_ty(_) => {
274 "cannot determine the type of this integer; add a suffix to \
275 specify the type explicitly".to_string()
277 unresolved_float_ty(_) => {
278 "cannot determine the type of this number; add a suffix to specify \
279 the type explicitly".to_string()
281 unresolved_ty(_) => "unconstrained type".to_string(),
285 pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
286 -> InferCtxt<'a, 'tcx> {
289 type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
290 int_unification_table: RefCell::new(UnificationTable::new()),
291 float_unification_table: RefCell::new(UnificationTable::new()),
292 region_vars: RegionVarBindings::new(tcx),
296 pub fn common_supertype(cx: &InferCtxt,
304 * Computes the least upper-bound of `a` and `b`. If this is
305 * not possible, reports an error and returns ty::err.
308 debug!("common_supertype({}, {})",
309 a.repr(cx.tcx), b.repr(cx.tcx));
311 let trace = TypeTrace {
313 values: Types(expected_found(a_is_expected, a, b))
317 cx.commit_if_ok(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
321 cx.report_and_explain_type_error(trace, err);
327 pub fn mk_subty(cx: &InferCtxt,
334 debug!("mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
336 cx.sub_types(a_is_expected, origin, a, b)
340 pub fn can_mk_subty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
341 debug!("can_mk_subty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
343 let trace = TypeTrace {
344 origin: Misc(codemap::DUMMY_SP),
345 values: Types(expected_found(true, a, b))
347 cx.sub(true, trace).tys(a, b).to_ures()
351 pub fn can_mk_eqty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
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.equate(true, trace).tys(a, b)
362 pub fn mk_subr(cx: &InferCtxt,
363 origin: SubregionOrigin,
366 debug!("mk_subr({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
367 let snapshot = cx.region_vars.start_snapshot();
368 cx.region_vars.make_subregion(origin, a, b);
369 cx.region_vars.commit(snapshot);
372 pub fn verify_param_bound(cx: &InferCtxt,
373 origin: SubregionOrigin,
374 param_ty: ty::ParamTy,
376 bs: Vec<ty::Region>) {
377 debug!("verify_param_bound({}, {} <: {})",
378 param_ty.repr(cx.tcx),
382 cx.region_vars.verify_param_bound(origin, param_ty, a, bs);
385 pub fn mk_eqty(cx: &InferCtxt,
392 debug!("mk_eqty({} <: {})", a.repr(cx.tcx), b.repr(cx.tcx));
394 || cx.eq_types(a_is_expected, origin, a, b))
397 pub fn mk_sub_trait_refs(cx: &InferCtxt,
404 debug!("mk_sub_trait_refs({} <: {})",
405 a.repr(cx.tcx), b.repr(cx.tcx));
407 || cx.sub_trait_refs(a_is_expected, origin, a.clone(), b.clone()))
410 fn expected_found<T>(a_is_expected: bool,
413 -> ty::expected_found<T>
416 ty::expected_found {expected: a, found: b}
418 ty::expected_found {expected: b, found: a}
422 pub fn mk_coercety(cx: &InferCtxt,
428 debug!("mk_coercety({} -> {})", a.repr(cx.tcx), b.repr(cx.tcx));
431 let trace = TypeTrace {
433 values: Types(expected_found(a_is_expected, a, b))
435 Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b)
440 // See comment on the type `resolve_state` below
441 pub fn resolve_type(cx: &InferCtxt,
446 let mut resolver = resolver(cx, modes, span);
447 cx.commit_unconditionally(|| resolver.resolve_type_chk(a))
450 pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
451 -> fres<ty::Region> {
452 let mut resolver = resolver(cx, modes, None);
453 resolver.resolve_region_chk(r)
457 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
458 -> Result<T,ty::type_err>;
462 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
463 -> Result<T,ty::type_err> {
464 self.and_then(|_i| f())
469 fn to_ures(&self) -> ures;
472 impl<T> ToUres for cres<T> {
473 fn to_ures(&self) -> ures {
475 Ok(ref _v) => Ok(()),
476 Err(ref e) => Err((*e))
481 trait CresCompare<T> {
482 fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T>;
485 impl<T:Clone + PartialEq> CresCompare<T> for cres<T> {
486 fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T> {
487 (*self).clone().and_then(|s| {
497 pub fn uok() -> ures {
501 pub struct CombinedSnapshot {
502 type_snapshot: type_variable::Snapshot,
503 int_snapshot: unify::Snapshot<ty::IntVid>,
504 float_snapshot: unify::Snapshot<ty::FloatVid>,
505 region_vars_snapshot: RegionSnapshot,
508 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
509 pub fn skolemizer<'a>(&'a self) -> TypeSkolemizer<'a, 'tcx> {
510 skolemize::TypeSkolemizer::new(self)
513 pub fn combine_fields<'a>(&'a self, a_is_expected: bool, trace: TypeTrace)
514 -> CombineFields<'a, 'tcx> {
515 CombineFields {infcx: self,
516 a_is_expected: a_is_expected,
520 pub fn equate<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Equate<'a, 'tcx> {
521 Equate(self.combine_fields(a_is_expected, trace))
524 pub fn sub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Sub<'a, 'tcx> {
525 Sub(self.combine_fields(a_is_expected, trace))
528 pub fn lub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Lub<'a, 'tcx> {
529 Lub(self.combine_fields(a_is_expected, trace))
532 fn start_snapshot(&self) -> CombinedSnapshot {
534 type_snapshot: self.type_variables.borrow_mut().snapshot(),
535 int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
536 float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
537 region_vars_snapshot: self.region_vars.start_snapshot(),
541 fn rollback_to(&self, snapshot: CombinedSnapshot) {
543 let CombinedSnapshot { type_snapshot,
546 region_vars_snapshot } = snapshot;
550 .rollback_to(type_snapshot);
551 self.int_unification_table
553 .rollback_to(int_snapshot);
554 self.float_unification_table
556 .rollback_to(float_snapshot);
558 .rollback_to(region_vars_snapshot);
561 fn commit_from(&self, snapshot: CombinedSnapshot) {
562 debug!("commit_from!");
563 let CombinedSnapshot { type_snapshot,
566 region_vars_snapshot } = snapshot;
570 .commit(type_snapshot);
571 self.int_unification_table
573 .commit(int_snapshot);
574 self.float_unification_table
576 .commit(float_snapshot);
578 .commit(region_vars_snapshot);
581 /// Execute `f` and commit the bindings
582 pub fn commit_unconditionally<R>(&self, f: || -> R) -> R {
584 let snapshot = self.start_snapshot();
586 self.commit_from(snapshot);
590 /// Execute `f` and commit the bindings if successful
591 pub fn commit_if_ok<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
592 self.commit_unconditionally(|| self.try(|| f()))
595 /// Execute `f`, unroll bindings on failure
596 pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
598 let snapshot = self.start_snapshot();
600 debug!("try() -- r.is_ok() = {}", r.is_ok());
603 self.commit_from(snapshot);
606 self.rollback_to(snapshot);
612 /// Execute `f` then unroll any bindings it creates
613 pub fn probe<R>(&self, f: || -> R) -> R {
615 let snapshot = self.start_snapshot();
617 self.rollback_to(snapshot);
621 pub fn add_given(&self,
625 self.region_vars.add_given(sub, sup);
628 pub fn sub_types(&self,
635 debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
636 let trace = TypeTrace {
638 values: Types(expected_found(a_is_expected, a, b))
640 self.sub(a_is_expected, trace).tys(a, b).to_ures()
643 pub fn eq_types(&self,
650 let trace = TypeTrace {
652 values: Types(expected_found(a_is_expected, a, b))
654 self.equate(a_is_expected, trace).tys(a, b).to_ures()
657 pub fn sub_trait_refs(&self,
664 debug!("sub_trait_refs({} <: {})",
667 let trace = TypeTrace {
669 values: TraitRefs(expected_found(a_is_expected,
670 a.clone(), b.clone()))
672 let suber = self.sub(a_is_expected, trace);
673 suber.trait_refs(&*a, &*b).to_ures()
677 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
678 pub fn next_ty_var_id(&self) -> TyVid {
684 pub fn next_ty_var(&self) -> ty::t {
685 ty::mk_var(self.tcx, self.next_ty_var_id())
688 pub fn next_ty_vars(&self, n: uint) -> Vec<ty::t> {
689 Vec::from_fn(n, |_i| self.next_ty_var())
692 pub fn next_int_var_id(&self) -> IntVid {
693 self.int_unification_table
698 pub fn next_float_var_id(&self) -> FloatVid {
699 self.float_unification_table
704 pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
705 ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
708 pub fn region_vars_for_defs(&self,
710 defs: &[ty::RegionParameterDef])
713 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
717 pub fn fresh_substs_for_generics(&self,
719 generics: &ty::Generics)
723 * Given a set of generics defined on a type or impl, returns
724 * a substitution mapping each type/region parameter to a
725 * fresh inference variable.
730 |_| self.next_ty_var());
732 generics.regions.map(
733 |d| self.next_region_var(EarlyBoundRegion(span, d.name)));
734 subst::Substs::new(type_params, region_params)
737 pub fn fresh_substs_for_trait(&self,
739 generics: &ty::Generics,
744 * Given a set of generics defined on a trait, returns a
745 * substitution mapping each output type/region parameter to a
746 * fresh inference variable, and mapping the self type to
750 assert!(generics.types.len(subst::SelfSpace) == 1);
751 assert!(generics.types.len(subst::FnSpace) == 0);
752 assert!(generics.regions.len(subst::SelfSpace) == 0);
753 assert!(generics.regions.len(subst::FnSpace) == 0);
755 let type_parameter_count = generics.types.len(subst::TypeSpace);
756 let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
757 let regions = self.region_vars_for_defs(span, region_param_defs);
758 let type_parameters = self.next_ty_vars(type_parameter_count);
759 subst::Substs::new_trait(type_parameters, regions, self_ty)
762 pub fn fresh_bound_region(&self, binder_id: ast::NodeId) -> ty::Region {
763 self.region_vars.new_bound(binder_id)
766 pub fn resolve_regions_and_report_errors(&self) {
767 let errors = self.region_vars.resolve_regions();
768 self.report_region_errors(&errors); // see error_reporting.rs
771 pub fn ty_to_string(&self, t: ty::t) -> String {
772 ty_to_string(self.tcx,
773 self.resolve_type_vars_if_possible(t))
776 pub fn tys_to_string(&self, ts: &[ty::t]) -> String {
777 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
778 format!("({})", tstrs.connect(", "))
781 pub fn trait_ref_to_string(&self, t: &ty::TraitRef) -> String {
782 let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
783 trait_ref_to_string(self.tcx, &t)
786 pub fn contains_unbound_type_variables(&self, typ: ty::t) -> ty::t {
787 match resolve_type(self,
789 typ, resolve_nested_tvar | resolve_ivar) {
790 Ok(new_type) => new_type,
795 pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
796 match resolve_type(self,
798 typ, resolve_nested_tvar | resolve_ivar) {
799 Ok(new_type) => new_type,
804 pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
805 trait_ref: &ty::TraitRef)
807 // make up a dummy type just to reuse/abuse the resolve machinery
808 let dummy0 = ty::mk_trait(self.tcx,
810 trait_ref.substs.clone(),
811 ty::region_existential_bound(ty::ReStatic));
812 let dummy1 = self.resolve_type_vars_if_possible(dummy0);
813 match ty::get(dummy1).sty {
814 ty::ty_trait(box ty::TyTrait { ref def_id, ref substs, .. }) => {
817 substs: (*substs).clone(),
822 format!("resolve_type_vars_if_possible() yielded {} \
823 when supplied with {}",
824 self.ty_to_string(dummy0),
825 self.ty_to_string(dummy1)).as_slice());
830 // [Note-Type-error-reporting]
831 // An invariant is that anytime the expected or actual type is ty_err (the special
832 // error type, meaning that an error occurred when typechecking this expression),
833 // this is a derived error. The error cascaded from another error (that was already
834 // reported), so it's not useful to display it to the user.
835 // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
836 // type_error_message, and report_mismatched_types -- implement this logic.
837 // They check if either the actual or expected type is ty_err, and don't print the error
838 // in this case. The typechecker should only ever report type errors involving mismatched
839 // types using one of these four methods, and should not call span_err directly for such
841 pub fn type_error_message_str(&self,
843 mk_msg: |Option<String>, String| -> String,
845 err: Option<&ty::type_err>) {
846 self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
849 pub fn type_error_message_str_with_expected(&self,
851 mk_msg: |Option<String>,
854 expected_ty: Option<ty::t>,
856 err: Option<&ty::type_err>) {
857 debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
859 let error_str = err.map_or("".to_string(), |t_err| {
860 format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
862 let resolved_expected = expected_ty.map(|e_ty| {
863 self.resolve_type_vars_if_possible(e_ty)
865 if !resolved_expected.map_or(false, |e| { ty::type_is_error(e) }) {
866 match resolved_expected {
872 mk_msg(None, actual_ty),
873 error_str).as_slice())
876 self.tcx.sess.span_err(sp,
878 mk_msg(Some(self.ty_to_string(e)), actual_ty),
879 error_str).as_slice());
882 for err in err.iter() {
883 ty::note_and_explain_type_err(self.tcx, *err)
888 pub fn type_error_message(&self,
890 mk_msg: |String| -> String,
892 err: Option<&ty::type_err>) {
893 let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
895 // Don't report an error if actual type is ty_err.
896 if ty::type_is_error(actual_ty) {
900 self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
903 pub fn report_mismatched_types(&self,
907 err: &ty::type_err) {
908 let resolved_expected =
909 self.resolve_type_vars_if_possible(e);
910 let mk_msg = match ty::get(resolved_expected).sty {
911 // Don't report an error if expected is ty_err
912 ty::ty_err => return,
914 // if I leave out : String, it infers &str and complains
916 format!("mismatched types: expected `{}`, found `{}`",
917 self.ty_to_string(resolved_expected),
922 self.type_error_message(sp, mk_msg, a, Some(err));
925 pub fn replace_late_bound_regions_with_fresh_regions(&self,
929 HashMap<ty::BoundRegion,
932 replace_late_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
933 let rvar = self.next_region_var(
934 BoundRegionInFnType(trace.origin.span(), br));
935 debug!("Bound region {} maps to {:?}",
936 bound_region_to_string(self.tcx, "", false, br),
944 pub fn fold_regions_in_sig(tcx: &ty::ctxt,
946 fldr: |r: ty::Region| -> ty::Region)
948 ty_fold::RegionFolder::regions(tcx, fldr).fold_sig(fn_sig)
952 pub fn span(&self) -> Span {
957 impl Repr for TypeTrace {
958 fn repr(&self, tcx: &ty::ctxt) -> String {
959 format!("TypeTrace({})", self.origin.repr(tcx))
964 pub fn span(&self) -> Span {
966 MethodCompatCheck(span) => span,
967 ExprAssignable(span) => span,
969 RelateTraitRefs(span) => span,
970 RelateSelfType(span) => span,
971 RelateOutputImplTypes(span) => span,
972 MatchExpressionArm(match_span, _) => match_span,
973 IfExpression(span) => span,
978 impl Repr for TypeOrigin {
979 fn repr(&self, tcx: &ty::ctxt) -> String {
981 MethodCompatCheck(a) => {
982 format!("MethodCompatCheck({})", a.repr(tcx))
984 ExprAssignable(a) => {
985 format!("ExprAssignable({})", a.repr(tcx))
987 Misc(a) => format!("Misc({})", a.repr(tcx)),
988 RelateTraitRefs(a) => {
989 format!("RelateTraitRefs({})", a.repr(tcx))
991 RelateSelfType(a) => {
992 format!("RelateSelfType({})", a.repr(tcx))
994 RelateOutputImplTypes(a) => {
995 format!("RelateOutputImplTypes({})", a.repr(tcx))
997 MatchExpressionArm(a, b) => {
998 format!("MatchExpressionArm({}, {})", a.repr(tcx), b.repr(tcx))
1000 IfExpression(a) => {
1001 format!("IfExpression({})", a.repr(tcx))
1007 impl SubregionOrigin {
1008 pub fn span(&self) -> Span {
1010 Subtype(ref a) => a.span(),
1011 InfStackClosure(a) => a,
1012 InvokeClosure(a) => a,
1013 DerefPointer(a) => a,
1014 FreeVariable(a, _) => a,
1015 ProcCapture(a, _) => a,
1017 RelateObjectBound(a) => a,
1018 RelateProcBound(a, _, _) => a,
1019 RelateParamBound(a, _, _) => a,
1020 RelateRegionParamBound(a) => a,
1021 RelateDefaultParamBound(a, _) => a,
1023 ReborrowUpvar(a, _) => a,
1024 ReferenceOutlivesReferent(_, a) => a,
1025 ExprTypeIsNotInScope(_, a) => a,
1026 BindingTypeIsNotValidAtDecl(a) => a,
1037 impl Repr for SubregionOrigin {
1038 fn repr(&self, tcx: &ty::ctxt) -> String {
1041 format!("Subtype({})", a.repr(tcx))
1043 InfStackClosure(a) => {
1044 format!("InfStackClosure({})", a.repr(tcx))
1046 InvokeClosure(a) => {
1047 format!("InvokeClosure({})", a.repr(tcx))
1049 DerefPointer(a) => {
1050 format!("DerefPointer({})", a.repr(tcx))
1052 FreeVariable(a, b) => {
1053 format!("FreeVariable({}, {})", a.repr(tcx), b)
1055 ProcCapture(a, b) => {
1056 format!("ProcCapture({}, {})", a.repr(tcx), b)
1059 format!("IndexSlice({})", a.repr(tcx))
1061 RelateObjectBound(a) => {
1062 format!("RelateObjectBound({})", a.repr(tcx))
1064 RelateProcBound(a, b, c) => {
1065 format!("RelateProcBound({},{},{})",
1070 RelateParamBound(a, b, c) => {
1071 format!("RelateParamBound({},{},{})",
1076 RelateRegionParamBound(a) => {
1077 format!("RelateRegionParamBound({})",
1080 RelateDefaultParamBound(a, b) => {
1081 format!("RelateDefaultParamBound({},{})",
1085 Reborrow(a) => format!("Reborrow({})", a.repr(tcx)),
1086 ReborrowUpvar(a, b) => {
1087 format!("ReborrowUpvar({},{:?})", a.repr(tcx), b)
1089 ReferenceOutlivesReferent(_, a) => {
1090 format!("ReferenceOutlivesReferent({})", a.repr(tcx))
1092 ExprTypeIsNotInScope(a, b) => {
1093 format!("ExprTypeIsNotInScope({}, {})",
1097 BindingTypeIsNotValidAtDecl(a) => {
1098 format!("BindingTypeIsNotValidAtDecl({})", a.repr(tcx))
1100 CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
1101 CallArg(a) => format!("CallArg({})", a.repr(tcx)),
1102 CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
1103 AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
1104 AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
1105 Managed(a) => format!("Managed({})", a.repr(tcx)),
1110 impl RegionVariableOrigin {
1111 pub fn span(&self) -> Span {
1113 MiscVariable(a) => a,
1114 PatternRegion(a) => a,
1115 AddrOfRegion(a) => a,
1116 AddrOfSlice(a) => a,
1118 Coercion(ref a) => a.span(),
1119 EarlyBoundRegion(a, _) => a,
1120 LateBoundRegion(a, _) => a,
1121 BoundRegionInFnType(a, _) => a,
1122 BoundRegionInCoherence(_) => codemap::DUMMY_SP,
1123 UpvarRegion(_, a) => a
1128 impl Repr for RegionVariableOrigin {
1129 fn repr(&self, tcx: &ty::ctxt) -> String {
1131 MiscVariable(a) => {
1132 format!("MiscVariable({})", a.repr(tcx))
1134 PatternRegion(a) => {
1135 format!("PatternRegion({})", a.repr(tcx))
1137 AddrOfRegion(a) => {
1138 format!("AddrOfRegion({})", a.repr(tcx))
1140 AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)),
1141 Autoref(a) => format!("Autoref({})", a.repr(tcx)),
1142 Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
1143 EarlyBoundRegion(a, b) => {
1144 format!("EarlyBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1146 LateBoundRegion(a, b) => {
1147 format!("LateBoundRegion({},{})", a.repr(tcx), b.repr(tcx))
1149 BoundRegionInFnType(a, b) => {
1150 format!("bound_regionInFnType({},{})", a.repr(tcx),
1153 BoundRegionInCoherence(a) => {
1154 format!("bound_regionInCoherence({})", a.repr(tcx))
1156 UpvarRegion(a, b) => {
1157 format!("UpvarRegion({}, {})", a.repr(tcx), b.repr(tcx))