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 middle::typeck::infer::resolve::resolve_and_force_all_but_regions;
17 pub use middle::typeck::infer::resolve::{force_all, not_regions};
18 pub use middle::typeck::infer::resolve::{force_ivar};
19 pub use middle::typeck::infer::resolve::{force_tvar, force_rvar};
20 pub use middle::typeck::infer::resolve::{resolve_ivar, resolve_all};
21 pub use middle::typeck::infer::resolve::{resolve_nested_tvar};
22 pub use middle::typeck::infer::resolve::{resolve_rvar};
24 use collections::HashMap;
25 use collections::SmallIntMap;
26 use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, Vid};
29 use middle::ty_fold::TypeFolder;
30 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
31 use middle::typeck::infer::coercion::Coerce;
32 use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
33 use middle::typeck::infer::region_inference::{RegionVarBindings};
34 use middle::typeck::infer::resolve::{resolver};
35 use middle::typeck::infer::sub::Sub;
36 use middle::typeck::infer::lub::Lub;
37 use middle::typeck::infer::to_str::InferStr;
38 use middle::typeck::infer::unify::{ValsAndBindings, Root};
39 use middle::typeck::infer::error_reporting::ErrorReporting;
40 use std::cell::{Cell, RefCell};
44 use syntax::codemap::Span;
45 use syntax::owned_slice::OwnedSlice;
46 use util::common::indent;
47 use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr};
55 pub mod region_inference;
61 pub mod error_reporting;
63 pub type Bound<T> = Option<T>;
66 pub struct Bounds<T> {
71 pub type cres<T> = Result<T,ty::type_err>; // "combine result"
72 pub type ures = cres<()>; // "unify result"
73 pub type fres<T> = Result<T, fixup_err>; // "fixup result"
74 pub type CoerceResult = cres<Option<ty::AutoAdjustment>>;
76 pub struct InferCtxt<'a> {
77 pub tcx: &'a ty::ctxt,
79 // We instantiate ValsAndBindings with bounds<ty::t> because the
80 // types that might instantiate a general type variable have an
81 // order, represented by its upper and lower bounds.
82 pub ty_var_bindings: RefCell<ValsAndBindings<ty::TyVid, Bounds<ty::t>>>,
83 pub ty_var_counter: Cell<uint>,
85 // Map from integral variable to the kind of integer it represents
86 pub int_var_bindings: RefCell<ValsAndBindings<ty::IntVid,
87 Option<IntVarValue>>>,
88 pub int_var_counter: Cell<uint>,
90 // Map from floating variable to the kind of float it represents
91 pub float_var_bindings: RefCell<ValsAndBindings<ty::FloatVid,
92 Option<ast::FloatTy>>>,
93 pub float_var_counter: Cell<uint>,
95 // For region variables.
96 pub region_vars: RegionVarBindings<'a>,
99 /// Why did we require that the two types be related?
101 /// See `error_reporting.rs` for more details
103 pub enum TypeOrigin {
104 // Not yet categorized in a better way
107 // Checking that method of impl is compatible with trait
108 MethodCompatCheck(Span),
110 // Checking that this expression can be assigned where it needs to be
111 // FIXME(eddyb) #11161 is the original Expr required?
112 ExprAssignable(Span),
114 // Relating trait refs when resolving vtables
115 RelateTraitRefs(Span),
117 // Relating trait refs when resolving vtables
118 RelateSelfType(Span),
120 // Computing common supertype in a match expression
121 MatchExpression(Span),
123 // Computing common supertype in an if expression
127 /// See `error_reporting.rs` for more details
129 pub enum ValuePairs {
130 Types(ty::expected_found<ty::t>),
131 TraitRefs(ty::expected_found<Rc<ty::TraitRef>>),
134 /// The trace designates the path through inference that we took to
135 /// encounter an error or subtyping constraint.
137 /// See `error_reporting.rs` for more details.
139 pub struct TypeTrace {
144 /// The origin of a `r1 <= r2` constraint.
146 /// See `error_reporting.rs` for more details
148 pub enum SubregionOrigin {
149 // Arose from a subtyping relation
152 // Stack-allocated closures cannot outlive innermost loop
153 // or function so as to ensure we only require finite stack
154 InfStackClosure(Span),
156 // Invocation of closure must be within its lifetime
159 // Dereference of reference must be within its lifetime
162 // Closure bound must not outlive captured free variables
163 FreeVariable(Span, ast::NodeId),
165 // Index into slice must be within its lifetime
168 // When casting `&'a T` to an `&'b Trait` object,
169 // relating `'a` to `'b`
170 RelateObjectBound(Span),
172 // Creating a pointer `b` to contents of another reference
175 // Creating a pointer `b` to contents of an upvar
176 ReborrowUpvar(Span, ty::UpvarId),
178 // (&'a &'b T) where a >= b
179 ReferenceOutlivesReferent(ty::t, Span),
181 // A `ref b` whose region does not enclose the decl site
182 BindingTypeIsNotValidAtDecl(Span),
184 // Regions appearing in a method receiver must outlive method call
187 // Regions appearing in a function argument must outlive func call
190 // Region in return type of invoked fn must enclose call
193 // Region resulting from a `&` expr must enclose the `&` expr
196 // An auto-borrow that does not enclose the expr where it occurs
200 /// Reasons to create a region inference variable
202 /// See `error_reporting.rs` for more details
204 pub enum RegionVariableOrigin {
205 // Region variables created for ill-categorized reasons,
206 // mostly indicates places in need of refactoring
209 // Regions created by a `&P` or `[...]` pattern
212 // Regions created by `&` operator
215 // Regions created by `&[...]` literal
218 // Regions created as part of an autoref of a method receiver
221 // Regions created as part of an automatic coercion
224 // Region variables created as the values for early-bound regions
225 EarlyBoundRegion(Span, ast::Name),
227 // Region variables created for bound regions
228 // in a function or method that is called
229 LateBoundRegion(Span, ty::BoundRegion),
231 // Region variables created for bound regions
232 // when doing subtyping/lub/glb computations
233 BoundRegionInFnType(Span, ty::BoundRegion),
235 UpvarRegion(ty::UpvarId, Span),
237 BoundRegionInCoherence(ast::Name),
241 unresolved_int_ty(IntVid),
242 unresolved_ty(TyVid),
244 unresolved_region(RegionVid),
245 region_var_bound_by_region_var(RegionVid, RegionVid)
248 pub fn fixup_err_to_str(f: fixup_err) -> String {
250 unresolved_int_ty(_) => "unconstrained integral type".to_string(),
251 unresolved_ty(_) => "unconstrained type".to_string(),
252 cyclic_ty(_) => "cyclic type of infinite size".to_string(),
253 unresolved_region(_) => "unconstrained region".to_string(),
254 region_var_bound_by_region_var(r1, r2) => {
255 format_strbuf!("region var {:?} bound by another region var {:?}; \
256 this is a bug in rustc",
263 fn new_ValsAndBindings<V:Clone,T:Clone>() -> ValsAndBindings<V, T> {
265 vals: SmallIntMap::new(),
270 pub fn new_infer_ctxt<'a>(tcx: &'a ty::ctxt) -> InferCtxt<'a> {
274 ty_var_bindings: RefCell::new(new_ValsAndBindings()),
275 ty_var_counter: Cell::new(0),
277 int_var_bindings: RefCell::new(new_ValsAndBindings()),
278 int_var_counter: Cell::new(0),
280 float_var_bindings: RefCell::new(new_ValsAndBindings()),
281 float_var_counter: Cell::new(0),
283 region_vars: RegionVarBindings(tcx),
287 pub fn common_supertype(cx: &InferCtxt,
294 * Computes the least upper-bound of `a` and `b`. If this is
295 * not possible, reports an error and returns ty::err.
298 debug!("common_supertype({}, {})", a.inf_str(cx), b.inf_str(cx));
300 let trace = TypeTrace {
302 values: Types(expected_found(a_is_expected, a, b))
305 let result = cx.commit(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
309 cx.report_and_explain_type_error(trace, err);
315 pub fn mk_subty(cx: &InferCtxt,
321 debug!("mk_subty({} <: {})", a.inf_str(cx), b.inf_str(cx));
324 let trace = TypeTrace {
326 values: Types(expected_found(a_is_expected, a, b))
328 cx.sub(a_is_expected, trace).tys(a, b)
333 pub fn can_mk_subty(cx: &InferCtxt, a: ty::t, b: ty::t) -> ures {
334 debug!("can_mk_subty({} <: {})", a.inf_str(cx), b.inf_str(cx));
337 let trace = TypeTrace {
338 origin: Misc(codemap::DUMMY_SP),
339 values: Types(expected_found(true, a, b))
341 cx.sub(true, trace).tys(a, b)
346 pub fn mk_subr(cx: &InferCtxt,
347 _a_is_expected: bool,
348 origin: SubregionOrigin,
351 debug!("mk_subr({} <: {})", a.inf_str(cx), b.inf_str(cx));
352 cx.region_vars.start_snapshot();
353 cx.region_vars.make_subregion(origin, a, b);
354 cx.region_vars.commit();
357 pub fn mk_eqty(cx: &InferCtxt,
363 debug!("mk_eqty({} <: {})", a.inf_str(cx), b.inf_str(cx));
366 let trace = TypeTrace {
368 values: Types(expected_found(a_is_expected, a, b))
370 let suber = cx.sub(a_is_expected, trace);
376 pub fn mk_sub_trait_refs(cx: &InferCtxt,
383 debug!("mk_sub_trait_refs({} <: {})",
384 a.inf_str(cx), b.inf_str(cx));
387 let trace = TypeTrace {
389 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
391 let suber = cx.sub(a_is_expected, trace);
392 suber.trait_refs(&*a, &*b)
397 fn expected_found<T>(a_is_expected: bool,
399 b: T) -> ty::expected_found<T> {
401 ty::expected_found {expected: a, found: b}
403 ty::expected_found {expected: b, found: a}
407 pub fn mk_coercety(cx: &InferCtxt,
413 debug!("mk_coercety({} -> {})", a.inf_str(cx), b.inf_str(cx));
416 let trace = TypeTrace {
418 values: Types(expected_found(a_is_expected, a, b))
420 Coerce(cx.combine_fields(a_is_expected, trace)).tys(a, b)
425 // See comment on the type `resolve_state` below
426 pub fn resolve_type(cx: &InferCtxt,
430 let mut resolver = resolver(cx, modes);
431 resolver.resolve_type_chk(a)
434 pub fn resolve_region(cx: &InferCtxt, r: ty::Region, modes: uint)
435 -> fres<ty::Region> {
436 let mut resolver = resolver(cx, modes);
437 resolver.resolve_region_chk(r)
441 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
442 -> Result<T,ty::type_err>;
446 fn then<T:Clone>(&self, f: || -> Result<T,ty::type_err>)
447 -> Result<T,ty::type_err> {
448 self.and_then(|_i| f())
453 fn to_ures(&self) -> ures;
456 impl<T> ToUres for cres<T> {
457 fn to_ures(&self) -> ures {
459 Ok(ref _v) => Ok(()),
460 Err(ref e) => Err((*e))
465 trait CresCompare<T> {
466 fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T>;
469 impl<T:Clone + Eq> CresCompare<T> for cres<T> {
470 fn compare(&self, t: T, f: || -> ty::type_err) -> cres<T> {
471 (*self).clone().and_then(|s| {
481 pub fn uok() -> ures {
485 fn rollback_to<V:Clone + Vid,T:Clone>(vb: &mut ValsAndBindings<V, T>,
487 while vb.bindings.len() != len {
488 let (vid, old_v) = vb.bindings.pop().unwrap();
489 vb.vals.insert(vid.to_uint(), old_v);
493 pub struct Snapshot {
494 ty_var_bindings_len: uint,
495 int_var_bindings_len: uint,
496 float_var_bindings_len: uint,
497 region_vars_snapshot: uint,
500 impl<'a> InferCtxt<'a> {
501 pub fn combine_fields<'a>(&'a self, a_is_expected: bool, trace: TypeTrace)
502 -> CombineFields<'a> {
503 CombineFields {infcx: self,
504 a_is_expected: a_is_expected,
508 pub fn sub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Sub<'a> {
509 Sub(self.combine_fields(a_is_expected, trace))
512 pub fn lub<'a>(&'a self, a_is_expected: bool, trace: TypeTrace) -> Lub<'a> {
513 Lub(self.combine_fields(a_is_expected, trace))
516 pub fn in_snapshot(&self) -> bool {
517 self.region_vars.in_snapshot()
520 pub fn start_snapshot(&self) -> Snapshot {
522 ty_var_bindings_len: self.ty_var_bindings.borrow().bindings.len(),
523 int_var_bindings_len: self.int_var_bindings.borrow().bindings.len(),
524 float_var_bindings_len: self.float_var_bindings.borrow().bindings.len(),
525 region_vars_snapshot: self.region_vars.start_snapshot(),
529 pub fn rollback_to(&self, snapshot: &Snapshot) {
531 rollback_to(&mut *self.ty_var_bindings.borrow_mut(),
532 snapshot.ty_var_bindings_len);
533 rollback_to(&mut *self.int_var_bindings.borrow_mut(),
534 snapshot.int_var_bindings_len);
535 rollback_to(&mut *self.float_var_bindings.borrow_mut(),
536 snapshot.float_var_bindings_len);
538 self.region_vars.rollback_to(snapshot.region_vars_snapshot);
541 /// Execute `f` and commit the bindings if successful
542 pub fn commit<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
543 assert!(!self.in_snapshot());
547 let r = self.try(|| f());
549 self.ty_var_bindings.borrow_mut().bindings.truncate(0);
550 self.int_var_bindings.borrow_mut().bindings.truncate(0);
551 self.region_vars.commit();
556 /// Execute `f`, unroll bindings on failure
557 pub fn try<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
559 let snapshot = self.start_snapshot();
562 Ok(_) => { debug!("success"); }
564 debug!("error: {:?}", *e);
565 self.rollback_to(&snapshot)
571 /// Execute `f` then unroll any bindings it creates
572 pub fn probe<T,E>(&self, f: || -> Result<T,E>) -> Result<T,E> {
575 let snapshot = self.start_snapshot();
577 self.rollback_to(&snapshot);
583 fn next_simple_var<V:Clone,T:Clone>(counter: &mut uint,
584 bindings: &mut ValsAndBindings<V,
589 bindings.vals.insert(id, Root(None, 0));
593 impl<'a> InferCtxt<'a> {
594 pub fn next_ty_var_id(&self) -> TyVid {
595 let id = self.ty_var_counter.get();
596 self.ty_var_counter.set(id + 1);
598 let mut ty_var_bindings = self.ty_var_bindings.borrow_mut();
599 let vals = &mut ty_var_bindings.vals;
600 vals.insert(id, Root(Bounds { lb: None, ub: None }, 0u));
605 pub fn next_ty_var(&self) -> ty::t {
606 ty::mk_var(self.tcx, self.next_ty_var_id())
609 pub fn next_ty_vars(&self, n: uint) -> Vec<ty::t> {
610 Vec::from_fn(n, |_i| self.next_ty_var())
613 pub fn next_int_var_id(&self) -> IntVid {
614 let mut int_var_counter = self.int_var_counter.get();
615 let mut int_var_bindings = self.int_var_bindings.borrow_mut();
616 let result = IntVid(next_simple_var(&mut int_var_counter,
617 &mut *int_var_bindings));
618 self.int_var_counter.set(int_var_counter);
622 pub fn next_float_var_id(&self) -> FloatVid {
623 let mut float_var_counter = self.float_var_counter.get();
624 let mut float_var_bindings = self.float_var_bindings.borrow_mut();
625 let result = FloatVid(next_simple_var(&mut float_var_counter,
626 &mut *float_var_bindings));
627 self.float_var_counter.set(float_var_counter);
631 pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
632 ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
635 pub fn region_vars_for_defs(&self,
637 defs: &[ty::RegionParameterDef])
638 -> OwnedSlice<ty::Region> {
640 .map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
644 pub fn fresh_bound_region(&self, binder_id: ast::NodeId) -> ty::Region {
645 self.region_vars.new_bound(binder_id)
648 pub fn resolve_regions_and_report_errors(&self) {
649 let errors = self.region_vars.resolve_regions();
650 self.report_region_errors(&errors); // see error_reporting.rs
653 pub fn ty_to_str(&self, t: ty::t) -> String {
655 self.resolve_type_vars_if_possible(t))
658 pub fn tys_to_str(&self, ts: &[ty::t]) -> String {
659 let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_str(*t)).collect();
660 format_strbuf!("({})", tstrs.connect(", "))
663 pub fn trait_ref_to_str(&self, t: &ty::TraitRef) -> String {
664 let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
665 trait_ref_to_str(self.tcx, &t)
668 pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
669 match resolve_type(self, typ, resolve_nested_tvar | resolve_ivar) {
670 Ok(new_type) => new_type,
675 pub fn resolve_type_vars_in_trait_ref_if_possible(&self,
679 // make up a dummy type just to reuse/abuse the resolve machinery
680 let dummy0 = ty::mk_trait(self.tcx,
682 trait_ref.substs.clone(),
684 ty::EmptyBuiltinBounds());
685 let dummy1 = self.resolve_type_vars_if_possible(dummy0);
686 match ty::get(dummy1).sty {
687 ty::ty_trait(box ty::TyTrait { ref def_id, ref substs, .. }) => {
690 substs: (*substs).clone(),
695 format!("resolve_type_vars_if_possible() yielded {} \
696 when supplied with {}",
697 self.ty_to_str(dummy0),
698 self.ty_to_str(dummy1)).as_slice());
703 // [Note-Type-error-reporting]
704 // An invariant is that anytime the expected or actual type is ty_err (the special
705 // error type, meaning that an error occurred when typechecking this expression),
706 // this is a derived error. The error cascaded from another error (that was already
707 // reported), so it's not useful to display it to the user.
708 // The following four methods -- type_error_message_str, type_error_message_str_with_expected,
709 // type_error_message, and report_mismatched_types -- implement this logic.
710 // They check if either the actual or expected type is ty_err, and don't print the error
711 // in this case. The typechecker should only ever report type errors involving mismatched
712 // types using one of these four methods, and should not call span_err directly for such
714 pub fn type_error_message_str(&self,
716 mk_msg: |Option<String>, String| -> String,
718 err: Option<&ty::type_err>) {
719 self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
722 pub fn type_error_message_str_with_expected(&self,
724 mk_msg: |Option<String>,
727 expected_ty: Option<ty::t>,
729 err: Option<&ty::type_err>) {
730 debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
732 let error_str = err.map_or("".to_string(), |t_err| {
733 format!(" ({})", ty::type_err_to_str(self.tcx, t_err))
735 let resolved_expected = expected_ty.map(|e_ty| {
736 self.resolve_type_vars_if_possible(e_ty)
738 if !resolved_expected.map_or(false, |e| { ty::type_is_error(e) }) {
739 match resolved_expected {
745 mk_msg(None, actual_ty),
746 error_str).as_slice())
749 self.tcx.sess.span_err(sp,
751 mk_msg(Some(self.ty_to_str(e)), actual_ty),
752 error_str).as_slice());
755 for err in err.iter() {
756 ty::note_and_explain_type_err(self.tcx, *err)
761 pub fn type_error_message(&self,
763 mk_msg: |String| -> String,
765 err: Option<&ty::type_err>) {
766 let actual_ty = self.resolve_type_vars_if_possible(actual_ty);
768 // Don't report an error if actual type is ty_err.
769 if ty::type_is_error(actual_ty) {
773 self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
776 pub fn report_mismatched_types(&self,
780 err: &ty::type_err) {
781 let resolved_expected =
782 self.resolve_type_vars_if_possible(e);
783 let mk_msg = match ty::get(resolved_expected).sty {
784 // Don't report an error if expected is ty_err
785 ty::ty_err => return,
787 // if I leave out : String, it infers &str and complains
789 format_strbuf!("mismatched types: expected `{}` but \
791 self.ty_to_str(resolved_expected),
796 self.type_error_message(sp, mk_msg, a, Some(err));
799 pub fn replace_late_bound_regions_with_fresh_regions(&self,
803 HashMap<ty::BoundRegion,
806 replace_late_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
807 let rvar = self.next_region_var(
808 BoundRegionInFnType(trace.origin.span(), br));
809 debug!("Bound region {} maps to {:?}",
810 bound_region_to_str(self.tcx, "", false, br),
818 pub fn fold_regions_in_sig(tcx: &ty::ctxt,
820 fldr: |r: ty::Region| -> ty::Region)
822 ty_fold::RegionFolder::regions(tcx, fldr).fold_sig(fn_sig)
826 pub fn span(&self) -> Span {
831 impl Repr for TypeTrace {
832 fn repr(&self, tcx: &ty::ctxt) -> String {
833 format_strbuf!("TypeTrace({})", self.origin.repr(tcx))
838 pub fn span(&self) -> Span {
840 MethodCompatCheck(span) => span,
841 ExprAssignable(span) => span,
843 RelateTraitRefs(span) => span,
844 RelateSelfType(span) => span,
845 MatchExpression(span) => span,
846 IfExpression(span) => span,
851 impl Repr for TypeOrigin {
852 fn repr(&self, tcx: &ty::ctxt) -> String {
854 MethodCompatCheck(a) => {
855 format_strbuf!("MethodCompatCheck({})", a.repr(tcx))
857 ExprAssignable(a) => {
858 format_strbuf!("ExprAssignable({})", a.repr(tcx))
860 Misc(a) => format_strbuf!("Misc({})", a.repr(tcx)),
861 RelateTraitRefs(a) => {
862 format_strbuf!("RelateTraitRefs({})", a.repr(tcx))
864 RelateSelfType(a) => {
865 format_strbuf!("RelateSelfType({})", a.repr(tcx))
867 MatchExpression(a) => {
868 format_strbuf!("MatchExpression({})", a.repr(tcx))
871 format_strbuf!("IfExpression({})", a.repr(tcx))
877 impl SubregionOrigin {
878 pub fn span(&self) -> Span {
880 Subtype(ref a) => a.span(),
881 InfStackClosure(a) => a,
882 InvokeClosure(a) => a,
883 DerefPointer(a) => a,
884 FreeVariable(a, _) => a,
886 RelateObjectBound(a) => a,
888 ReborrowUpvar(a, _) => a,
889 ReferenceOutlivesReferent(_, a) => a,
890 BindingTypeIsNotValidAtDecl(a) => a,
900 impl Repr for SubregionOrigin {
901 fn repr(&self, tcx: &ty::ctxt) -> String {
904 format_strbuf!("Subtype({})", a.repr(tcx))
906 InfStackClosure(a) => {
907 format_strbuf!("InfStackClosure({})", a.repr(tcx))
909 InvokeClosure(a) => {
910 format_strbuf!("InvokeClosure({})", a.repr(tcx))
913 format_strbuf!("DerefPointer({})", a.repr(tcx))
915 FreeVariable(a, b) => {
916 format_strbuf!("FreeVariable({}, {})", a.repr(tcx), b)
919 format_strbuf!("IndexSlice({})", a.repr(tcx))
921 RelateObjectBound(a) => {
922 format_strbuf!("RelateObjectBound({})", a.repr(tcx))
924 Reborrow(a) => format_strbuf!("Reborrow({})", a.repr(tcx)),
925 ReborrowUpvar(a, b) => {
926 format_strbuf!("ReborrowUpvar({},{:?})", a.repr(tcx), b)
928 ReferenceOutlivesReferent(_, a) => {
929 format_strbuf!("ReferenceOutlivesReferent({})", a.repr(tcx))
931 BindingTypeIsNotValidAtDecl(a) => {
932 format_strbuf!("BindingTypeIsNotValidAtDecl({})", a.repr(tcx))
934 CallRcvr(a) => format_strbuf!("CallRcvr({})", a.repr(tcx)),
935 CallArg(a) => format_strbuf!("CallArg({})", a.repr(tcx)),
936 CallReturn(a) => format_strbuf!("CallReturn({})", a.repr(tcx)),
937 AddrOf(a) => format_strbuf!("AddrOf({})", a.repr(tcx)),
938 AutoBorrow(a) => format_strbuf!("AutoBorrow({})", a.repr(tcx)),
943 impl RegionVariableOrigin {
944 pub fn span(&self) -> Span {
946 MiscVariable(a) => a,
947 PatternRegion(a) => a,
948 AddrOfRegion(a) => a,
951 Coercion(ref a) => a.span(),
952 EarlyBoundRegion(a, _) => a,
953 LateBoundRegion(a, _) => a,
954 BoundRegionInFnType(a, _) => a,
955 BoundRegionInCoherence(_) => codemap::DUMMY_SP,
956 UpvarRegion(_, a) => a
961 impl Repr for RegionVariableOrigin {
962 fn repr(&self, tcx: &ty::ctxt) -> String {
965 format_strbuf!("MiscVariable({})", a.repr(tcx))
967 PatternRegion(a) => {
968 format_strbuf!("PatternRegion({})", a.repr(tcx))
971 format_strbuf!("AddrOfRegion({})", a.repr(tcx))
973 AddrOfSlice(a) => format_strbuf!("AddrOfSlice({})", a.repr(tcx)),
974 Autoref(a) => format_strbuf!("Autoref({})", a.repr(tcx)),
975 Coercion(ref a) => format_strbuf!("Coercion({})", a.repr(tcx)),
976 EarlyBoundRegion(a, b) => {
977 format_strbuf!("EarlyBoundRegion({},{})",
981 LateBoundRegion(a, b) => {
982 format_strbuf!("LateBoundRegion({},{})",
986 BoundRegionInFnType(a, b) => {
987 format_strbuf!("bound_regionInFnType({},{})",
991 BoundRegionInCoherence(a) => {
992 format_strbuf!("bound_regionInCoherence({})", a.repr(tcx))
994 UpvarRegion(a, b) => {
995 format_strbuf!("UpvarRegion({}, {})",