]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/mod.rs
Rollup merge of #51765 - jonas-schievink:patch-1, r=KodrAus
[rust.git] / src / librustc / infer / mod.rs
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.
4 //
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.
10
11 //! See the Book for more information.
12
13 pub use self::LateBoundRegionConversionTime::*;
14 pub use self::RegionVariableOrigin::*;
15 pub use self::SubregionOrigin::*;
16 pub use self::ValuePairs::*;
17 pub use ty::IntVarValue;
18 pub use self::freshen::TypeFreshener;
19
20 use hir::def_id::DefId;
21 use middle::free_region::RegionRelations;
22 use middle::region;
23 use middle::lang_items;
24 use ty::subst::{Kind, Substs};
25 use ty::{TyVid, IntVid, FloatVid};
26 use ty::{self, Ty, TyCtxt, GenericParamDefKind};
27 use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
28 use ty::fold::TypeFoldable;
29 use ty::relate::RelateResult;
30 use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
31 use rustc_data_structures::unify as ut;
32 use std::cell::{Cell, RefCell, Ref, RefMut};
33 use std::collections::BTreeMap;
34 use std::fmt;
35 use syntax::ast;
36 use errors::DiagnosticBuilder;
37 use syntax_pos::{self, Span};
38 use syntax_pos::symbol::InternedString;
39 use util::nodemap::FxHashMap;
40 use arena::SyncDroplessArena;
41
42 use self::combine::CombineFields;
43 use self::higher_ranked::HrMatchResult;
44 use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
45 use self::region_constraints::{GenericKind, VerifyBound, RegionConstraintData, VarInfos};
46 use self::lexical_region_resolve::LexicalRegionResolutions;
47 use self::outlives::env::OutlivesEnvironment;
48 use self::type_variable::TypeVariableOrigin;
49 use self::unify_key::ToType;
50
51 pub mod anon_types;
52 pub mod at;
53 pub mod canonical;
54 mod combine;
55 mod equate;
56 pub mod error_reporting;
57 mod fudge;
58 mod glb;
59 mod higher_ranked;
60 pub mod lattice;
61 mod lub;
62 pub mod region_constraints;
63 mod lexical_region_resolve;
64 pub mod outlives;
65 pub mod resolve;
66 mod freshen;
67 mod sub;
68 pub mod type_variable;
69 pub mod unify_key;
70
71 #[must_use]
72 #[derive(Debug)]
73 pub struct InferOk<'tcx, T> {
74     pub value: T,
75     pub obligations: PredicateObligations<'tcx>,
76 }
77 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
78
79 pub type Bound<T> = Option<T>;
80 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
81 pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
82
83 pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
84     pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
85
86     /// During type-checking/inference of a body, `in_progress_tables`
87     /// contains a reference to the tables being built up, which are
88     /// used for reading closure kinds/signatures as they are inferred,
89     /// and for error reporting logic to read arbitrary node types.
90     pub in_progress_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
91
92     // Cache for projections. This cache is snapshotted along with the
93     // infcx.
94     //
95     // Public so that `traits::project` can use it.
96     pub projection_cache: RefCell<traits::ProjectionCache<'tcx>>,
97
98     // We instantiate UnificationTable with bounds<Ty> because the
99     // types that might instantiate a general type variable have an
100     // order, represented by its upper and lower bounds.
101     pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
102
103     // Map from integral variable to the kind of integer it represents
104     int_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::IntVid>>>,
105
106     // Map from floating variable to the kind of float it represents
107     float_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::FloatVid>>>,
108
109     // Tracks the set of region variables and the constraints between
110     // them.  This is initially `Some(_)` but when
111     // `resolve_regions_and_report_errors` is invoked, this gets set
112     // to `None` -- further attempts to perform unification etc may
113     // fail if new region constraints would've been added.
114     region_constraints: RefCell<Option<RegionConstraintCollector<'tcx>>>,
115
116     // Once region inference is done, the values for each variable.
117     lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
118
119     /// Caches the results of trait selection. This cache is used
120     /// for things that have to do with the parameters in scope.
121     pub selection_cache: traits::SelectionCache<'tcx>,
122
123     /// Caches the results of trait evaluation.
124     pub evaluation_cache: traits::EvaluationCache<'tcx>,
125
126     // the set of predicates on which errors have been reported, to
127     // avoid reporting the same error twice.
128     pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>,
129
130     // When an error occurs, we want to avoid reporting "derived"
131     // errors that are due to this original failure. Normally, we
132     // handle this with the `err_count_on_creation` count, which
133     // basically just tracks how many errors were reported when we
134     // started type-checking a fn and checks to see if any new errors
135     // have been reported since then. Not great, but it works.
136     //
137     // However, when errors originated in other passes -- notably
138     // resolve -- this heuristic breaks down. Therefore, we have this
139     // auxiliary flag that one can set whenever one creates a
140     // type-error that is due to an error in a prior pass.
141     //
142     // Don't read this flag directly, call `is_tainted_by_errors()`
143     // and `set_tainted_by_errors()`.
144     tainted_by_errors_flag: Cell<bool>,
145
146     // Track how many errors were reported when this infcx is created.
147     // If the number of errors increases, that's also a sign (line
148     // `tained_by_errors`) to avoid reporting certain kinds of errors.
149     err_count_on_creation: usize,
150
151     // This flag is true while there is an active snapshot.
152     in_snapshot: Cell<bool>,
153
154     // A set of constraints that regionck must validate. Each
155     // constraint has the form `T:'a`, meaning "some type `T` must
156     // outlive the lifetime 'a". These constraints derive from
157     // instantiated type parameters. So if you had a struct defined
158     // like
159     //
160     //     struct Foo<T:'static> { ... }
161     //
162     // then in some expression `let x = Foo { ... }` it will
163     // instantiate the type parameter `T` with a fresh type `$0`. At
164     // the same time, it will record a region obligation of
165     // `$0:'static`. This will get checked later by regionck. (We
166     // can't generally check these things right away because we have
167     // to wait until types are resolved.)
168     //
169     // These are stored in a map keyed to the id of the innermost
170     // enclosing fn body / static initializer expression. This is
171     // because the location where the obligation was incurred can be
172     // relevant with respect to which sublifetime assumptions are in
173     // place. The reason that we store under the fn-id, and not
174     // something more fine-grained, is so that it is easier for
175     // regionck to be sure that it has found *all* the region
176     // obligations (otherwise, it's easy to fail to walk to a
177     // particular node-id).
178     //
179     // Before running `resolve_regions_and_report_errors`, the creator
180     // of the inference context is expected to invoke
181     // `process_region_obligations` (defined in `self::region_obligations`)
182     // for each body-id in this map, which will process the
183     // obligations within. This is expected to be done 'late enough'
184     // that all type inference variables have been bound and so forth.
185     pub region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
186
187     /// What is the innermost universe we have created? Starts out as
188     /// `UniverseIndex::root()` but grows from there as we enter
189     /// universal quantifiers.
190     ///
191     /// NB: At present, we exclude the universal quantifiers on the
192     /// item we are type-checking, and just consider those names as
193     /// part of the root universe. So this would only get incremented
194     /// when we enter into a higher-ranked (`for<..>`) type or trait
195     /// bound.
196     universe: Cell<ty::UniverseIndex>,
197 }
198
199 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
200 /// region that each late-bound region was replaced with.
201 pub type SkolemizationMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
202
203 /// See `error_reporting` module for more details
204 #[derive(Clone, Debug)]
205 pub enum ValuePairs<'tcx> {
206     Types(ExpectedFound<Ty<'tcx>>),
207     Regions(ExpectedFound<ty::Region<'tcx>>),
208     TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
209     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
210 }
211
212 /// The trace designates the path through inference that we took to
213 /// encounter an error or subtyping constraint.
214 ///
215 /// See `error_reporting` module for more details.
216 #[derive(Clone)]
217 pub struct TypeTrace<'tcx> {
218     cause: ObligationCause<'tcx>,
219     values: ValuePairs<'tcx>,
220 }
221
222 /// The origin of a `r1 <= r2` constraint.
223 ///
224 /// See `error_reporting` module for more details
225 #[derive(Clone, Debug)]
226 pub enum SubregionOrigin<'tcx> {
227     // Arose from a subtyping relation
228     Subtype(TypeTrace<'tcx>),
229
230     // Stack-allocated closures cannot outlive innermost loop
231     // or function so as to ensure we only require finite stack
232     InfStackClosure(Span),
233
234     // Invocation of closure must be within its lifetime
235     InvokeClosure(Span),
236
237     // Dereference of reference must be within its lifetime
238     DerefPointer(Span),
239
240     // Closure bound must not outlive captured free variables
241     FreeVariable(Span, ast::NodeId),
242
243     // Index into slice must be within its lifetime
244     IndexSlice(Span),
245
246     // When casting `&'a T` to an `&'b Trait` object,
247     // relating `'a` to `'b`
248     RelateObjectBound(Span),
249
250     // Some type parameter was instantiated with the given type,
251     // and that type must outlive some region.
252     RelateParamBound(Span, Ty<'tcx>),
253
254     // The given region parameter was instantiated with a region
255     // that must outlive some other region.
256     RelateRegionParamBound(Span),
257
258     // A bound placed on type parameters that states that must outlive
259     // the moment of their instantiation.
260     RelateDefaultParamBound(Span, Ty<'tcx>),
261
262     // Creating a pointer `b` to contents of another reference
263     Reborrow(Span),
264
265     // Creating a pointer `b` to contents of an upvar
266     ReborrowUpvar(Span, ty::UpvarId),
267
268     // Data with type `Ty<'tcx>` was borrowed
269     DataBorrowed(Ty<'tcx>, Span),
270
271     // (&'a &'b T) where a >= b
272     ReferenceOutlivesReferent(Ty<'tcx>, Span),
273
274     // Type or region parameters must be in scope.
275     ParameterInScope(ParameterOrigin, Span),
276
277     // The type T of an expression E must outlive the lifetime for E.
278     ExprTypeIsNotInScope(Ty<'tcx>, Span),
279
280     // A `ref b` whose region does not enclose the decl site
281     BindingTypeIsNotValidAtDecl(Span),
282
283     // Regions appearing in a method receiver must outlive method call
284     CallRcvr(Span),
285
286     // Regions appearing in a function argument must outlive func call
287     CallArg(Span),
288
289     // Region in return type of invoked fn must enclose call
290     CallReturn(Span),
291
292     // Operands must be in scope
293     Operand(Span),
294
295     // Region resulting from a `&` expr must enclose the `&` expr
296     AddrOf(Span),
297
298     // An auto-borrow that does not enclose the expr where it occurs
299     AutoBorrow(Span),
300
301     // Region constraint arriving from destructor safety
302     SafeDestructor(Span),
303
304     // Comparing the signature and requirements of an impl method against
305     // the containing trait.
306     CompareImplMethodObligation {
307         span: Span,
308         item_name: ast::Name,
309         impl_item_def_id: DefId,
310         trait_item_def_id: DefId,
311     },
312 }
313
314 /// Places that type/region parameters can appear.
315 #[derive(Clone, Copy, Debug)]
316 pub enum ParameterOrigin {
317     Path, // foo::bar
318     MethodCall, // foo.bar() <-- parameters on impl providing bar()
319     OverloadedOperator, // a + b when overloaded
320     OverloadedDeref, // *a when overloaded
321 }
322
323 /// Times when we replace late-bound regions with variables:
324 #[derive(Clone, Copy, Debug)]
325 pub enum LateBoundRegionConversionTime {
326     /// when a fn is called
327     FnCall,
328
329     /// when two higher-ranked types are compared
330     HigherRankedType,
331
332     /// when projecting an associated type
333     AssocTypeProjection(DefId),
334 }
335
336 /// Reasons to create a region inference variable
337 ///
338 /// See `error_reporting` module for more details
339 #[derive(Copy, Clone, Debug)]
340 pub enum RegionVariableOrigin {
341     // Region variables created for ill-categorized reasons,
342     // mostly indicates places in need of refactoring
343     MiscVariable(Span),
344
345     // Regions created by a `&P` or `[...]` pattern
346     PatternRegion(Span),
347
348     // Regions created by `&` operator
349     AddrOfRegion(Span),
350
351     // Regions created as part of an autoref of a method receiver
352     Autoref(Span),
353
354     // Regions created as part of an automatic coercion
355     Coercion(Span),
356
357     // Region variables created as the values for early-bound regions
358     EarlyBoundRegion(Span, InternedString),
359
360     // Region variables created for bound regions
361     // in a function or method that is called
362     LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
363
364     UpvarRegion(ty::UpvarId, Span),
365
366     BoundRegionInCoherence(ast::Name),
367
368     // This origin is used for the inference variables that we create
369     // during NLL region processing.
370     NLL(NLLRegionVariableOrigin),
371 }
372
373 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
374 pub enum NLLRegionVariableOrigin {
375     // During NLL region processing, we create variables for free
376     // regions that we encounter in the function signature and
377     // elsewhere. This origin indices we've got one of those.
378     FreeRegion,
379
380     Inferred(::mir::visit::TyContext),
381 }
382
383 #[derive(Copy, Clone, Debug)]
384 pub enum FixupError {
385     UnresolvedIntTy(IntVid),
386     UnresolvedFloatTy(FloatVid),
387     UnresolvedTy(TyVid)
388 }
389
390 /// See the `region_obligations` field for more information.
391 #[derive(Clone)]
392 pub struct RegionObligation<'tcx> {
393     pub sub_region: ty::Region<'tcx>,
394     pub sup_type: Ty<'tcx>,
395     pub cause: ObligationCause<'tcx>,
396 }
397
398 impl fmt::Display for FixupError {
399     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
400         use self::FixupError::*;
401
402         match *self {
403             UnresolvedIntTy(_) => {
404                 write!(f, "cannot determine the type of this integer; \
405                            add a suffix to specify the type explicitly")
406             }
407             UnresolvedFloatTy(_) => {
408                 write!(f, "cannot determine the type of this number; \
409                            add a suffix to specify the type explicitly")
410             }
411             UnresolvedTy(_) => write!(f, "unconstrained type")
412         }
413     }
414 }
415
416 /// Helper type of a temporary returned by tcx.infer_ctxt().
417 /// Necessary because we can't write the following bound:
418 /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>).
419 pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
420     global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
421     arena: SyncDroplessArena,
422     fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
423 }
424
425 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
426     pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
427         InferCtxtBuilder {
428             global_tcx: self,
429             arena: SyncDroplessArena::new(),
430             fresh_tables: None,
431
432         }
433     }
434 }
435
436 impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
437     /// Used only by `rustc_typeck` during body type-checking/inference,
438     /// will initialize `in_progress_tables` with fresh `TypeckTables`.
439     pub fn with_fresh_in_progress_tables(mut self, table_owner: DefId) -> Self {
440         self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty(Some(table_owner))));
441         self
442     }
443
444     pub fn enter<F, R>(&'tcx mut self, f: F) -> R
445         where F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R
446     {
447         let InferCtxtBuilder {
448             global_tcx,
449             ref arena,
450             ref fresh_tables,
451         } = *self;
452         let in_progress_tables = fresh_tables.as_ref();
453         global_tcx.enter_local(arena, |tcx| f(InferCtxt {
454             tcx,
455             in_progress_tables,
456             projection_cache: RefCell::new(traits::ProjectionCache::new()),
457             type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
458             int_unification_table: RefCell::new(ut::UnificationTable::new()),
459             float_unification_table: RefCell::new(ut::UnificationTable::new()),
460             region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
461             lexical_region_resolutions: RefCell::new(None),
462             selection_cache: traits::SelectionCache::new(),
463             evaluation_cache: traits::EvaluationCache::new(),
464             reported_trait_errors: RefCell::new(FxHashMap()),
465             tainted_by_errors_flag: Cell::new(false),
466             err_count_on_creation: tcx.sess.err_count(),
467             in_snapshot: Cell::new(false),
468             region_obligations: RefCell::new(vec![]),
469             universe: Cell::new(ty::UniverseIndex::ROOT),
470         }))
471     }
472 }
473
474 impl<T> ExpectedFound<T> {
475     pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
476         if a_is_expected {
477             ExpectedFound {expected: a, found: b}
478         } else {
479             ExpectedFound {expected: b, found: a}
480         }
481     }
482 }
483
484 impl<'tcx, T> InferOk<'tcx, T> {
485     pub fn unit(self) -> InferOk<'tcx, ()> {
486         InferOk { value: (), obligations: self.obligations }
487     }
488
489     /// Extract `value`, registering any obligations into `fulfill_cx`
490     pub fn into_value_registering_obligations(
491         self,
492         infcx: &InferCtxt<'_, '_, 'tcx>,
493         fulfill_cx: &mut impl TraitEngine<'tcx>,
494     ) -> T {
495         let InferOk { value, obligations } = self;
496         for obligation in obligations {
497             fulfill_cx.register_predicate_obligation(infcx, obligation);
498         }
499         value
500     }
501 }
502
503 impl<'tcx> InferOk<'tcx, ()> {
504     pub fn into_obligations(self) -> PredicateObligations<'tcx> {
505         self.obligations
506     }
507 }
508
509 #[must_use = "once you start a snapshot, you should always consume it"]
510 pub struct CombinedSnapshot<'a, 'tcx:'a> {
511     projection_cache_snapshot: traits::ProjectionCacheSnapshot,
512     type_snapshot: type_variable::Snapshot<'tcx>,
513     int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
514     float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
515     region_constraints_snapshot: RegionSnapshot,
516     region_obligations_snapshot: usize,
517     universe: ty::UniverseIndex,
518     was_in_snapshot: bool,
519     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
520 }
521
522 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
523     pub fn is_in_snapshot(&self) -> bool {
524         self.in_snapshot.get()
525     }
526
527     pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
528         t.fold_with(&mut self.freshener())
529     }
530
531     pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
532         match ty.sty {
533             ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
534             _ => false
535         }
536     }
537
538     pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'gcx, 'tcx> {
539         freshen::TypeFreshener::new(self)
540     }
541
542     pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
543         use ty::error::UnconstrainedNumeric::Neither;
544         use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
545         match ty.sty {
546             ty::TyInfer(ty::IntVar(vid)) => {
547                 if self.int_unification_table.borrow_mut().probe_value(vid).is_some() {
548                     Neither
549                 } else {
550                     UnconstrainedInt
551                 }
552             },
553             ty::TyInfer(ty::FloatVar(vid)) => {
554                 if self.float_unification_table.borrow_mut().probe_value(vid).is_some() {
555                     Neither
556                 } else {
557                     UnconstrainedFloat
558                 }
559             },
560             _ => Neither,
561         }
562     }
563
564     pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
565         let mut variables = Vec::new();
566
567         {
568             let mut type_variables = self.type_variables.borrow_mut();
569             variables.extend(
570                 type_variables
571                     .unsolved_variables()
572                     .into_iter()
573                     .map(|t| self.tcx.mk_var(t)));
574         }
575
576         {
577             let mut int_unification_table = self.int_unification_table.borrow_mut();
578             variables.extend(
579                 (0..int_unification_table.len())
580                     .map(|i| ty::IntVid { index: i as u32 })
581                     .filter(|&vid| int_unification_table.probe_value(vid).is_none())
582                     .map(|v| self.tcx.mk_int_var(v)));
583         }
584
585         {
586             let mut float_unification_table = self.float_unification_table.borrow_mut();
587             variables.extend(
588                 (0..float_unification_table.len())
589                     .map(|i| ty::FloatVid { index: i as u32 })
590                     .filter(|&vid| float_unification_table.probe_value(vid).is_none())
591                     .map(|v| self.tcx.mk_float_var(v)));
592         }
593
594         return variables;
595     }
596
597     fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)
598                       -> CombineFields<'a, 'gcx, 'tcx> {
599         CombineFields {
600             infcx: self,
601             trace,
602             cause: None,
603             param_env,
604             obligations: PredicateObligations::new(),
605         }
606     }
607
608     // Clear the "currently in a snapshot" flag, invoke the closure,
609     // then restore the flag to its original value. This flag is a
610     // debugging measure designed to detect cases where we start a
611     // snapshot, create type variables, and register obligations
612     // which may involve those type variables in the fulfillment cx,
613     // potentially leaving "dangling type variables" behind.
614     // In such cases, an assertion will fail when attempting to
615     // register obligations, within a snapshot. Very useful, much
616     // better than grovelling through megabytes of RUST_LOG output.
617     //
618     // HOWEVER, in some cases the flag is unhelpful. In particular, we
619     // sometimes create a "mini-fulfilment-cx" in which we enroll
620     // obligations. As long as this fulfillment cx is fully drained
621     // before we return, this is not a problem, as there won't be any
622     // escaping obligations in the main cx. In those cases, you can
623     // use this function.
624     pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
625         where F: FnOnce(&Self) -> R
626     {
627         let flag = self.in_snapshot.get();
628         self.in_snapshot.set(false);
629         let result = func(self);
630         self.in_snapshot.set(flag);
631         result
632     }
633
634     fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> {
635         debug!("start_snapshot()");
636
637         let in_snapshot = self.in_snapshot.get();
638         self.in_snapshot.set(true);
639
640         CombinedSnapshot {
641             projection_cache_snapshot: self.projection_cache.borrow_mut().snapshot(),
642             type_snapshot: self.type_variables.borrow_mut().snapshot(),
643             int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
644             float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
645             region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
646             region_obligations_snapshot: self.region_obligations.borrow().len(),
647             universe: self.universe(),
648             was_in_snapshot: in_snapshot,
649             // Borrow tables "in progress" (i.e. during typeck)
650             // to ban writes from within a snapshot to them.
651             _in_progress_tables: self.in_progress_tables.map(|tables| {
652                 tables.borrow()
653             })
654         }
655     }
656
657     fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) {
658         debug!("rollback_to(cause={})", cause);
659         let CombinedSnapshot { projection_cache_snapshot,
660                                type_snapshot,
661                                int_snapshot,
662                                float_snapshot,
663                                region_constraints_snapshot,
664                                region_obligations_snapshot,
665                                universe,
666                                was_in_snapshot,
667                                _in_progress_tables } = snapshot;
668
669         self.in_snapshot.set(was_in_snapshot);
670         self.universe.set(universe);
671
672         self.projection_cache
673             .borrow_mut()
674             .rollback_to(projection_cache_snapshot);
675         self.type_variables
676             .borrow_mut()
677             .rollback_to(type_snapshot);
678         self.int_unification_table
679             .borrow_mut()
680             .rollback_to(int_snapshot);
681         self.float_unification_table
682             .borrow_mut()
683             .rollback_to(float_snapshot);
684         self.region_obligations
685             .borrow_mut()
686             .truncate(region_obligations_snapshot);
687         self.borrow_region_constraints()
688             .rollback_to(region_constraints_snapshot);
689     }
690
691     fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
692         debug!("commit_from()");
693         let CombinedSnapshot { projection_cache_snapshot,
694                                type_snapshot,
695                                int_snapshot,
696                                float_snapshot,
697                                region_constraints_snapshot,
698                                region_obligations_snapshot: _,
699                                universe: _,
700                                was_in_snapshot,
701                                _in_progress_tables } = snapshot;
702
703         self.in_snapshot.set(was_in_snapshot);
704
705         self.projection_cache
706             .borrow_mut()
707             .commit(projection_cache_snapshot);
708         self.type_variables
709             .borrow_mut()
710             .commit(type_snapshot);
711         self.int_unification_table
712             .borrow_mut()
713             .commit(int_snapshot);
714         self.float_unification_table
715             .borrow_mut()
716             .commit(float_snapshot);
717         self.borrow_region_constraints()
718             .commit(region_constraints_snapshot);
719     }
720
721     /// Execute `f` and commit the bindings
722     pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
723         F: FnOnce() -> R,
724     {
725         debug!("commit()");
726         let snapshot = self.start_snapshot();
727         let r = f();
728         self.commit_from(snapshot);
729         r
730     }
731
732     /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
733     pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
734         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>
735     {
736         debug!("commit_if_ok()");
737         let snapshot = self.start_snapshot();
738         let r = f(&snapshot);
739         debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
740         match r {
741             Ok(_) => { self.commit_from(snapshot); }
742             Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
743         }
744         r
745     }
746
747     // Execute `f` in a snapshot, and commit the bindings it creates
748     pub fn in_snapshot<T, F>(&self, f: F) -> T where
749         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T
750     {
751         debug!("in_snapshot()");
752         let snapshot = self.start_snapshot();
753         let r = f(&snapshot);
754         self.commit_from(snapshot);
755         r
756     }
757
758     /// Execute `f` then unroll any bindings it creates
759     pub fn probe<R, F>(&self, f: F) -> R where
760         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
761     {
762         debug!("probe()");
763         let snapshot = self.start_snapshot();
764         let r = f(&snapshot);
765         self.rollback_to("probe", snapshot);
766         r
767     }
768
769     pub fn add_given(&self,
770                      sub: ty::Region<'tcx>,
771                      sup: ty::RegionVid)
772     {
773         self.borrow_region_constraints().add_given(sub, sup);
774     }
775
776     pub fn can_sub<T>(&self,
777                       param_env: ty::ParamEnv<'tcx>,
778                       a: T,
779                       b: T)
780                       -> UnitResult<'tcx>
781         where T: at::ToTrace<'tcx>
782     {
783         let origin = &ObligationCause::dummy();
784         self.probe(|_| {
785             self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
786                 // Ignore obligations, since we are unrolling
787                 // everything anyway.
788             })
789         })
790     }
791
792     pub fn can_eq<T>(&self,
793                       param_env: ty::ParamEnv<'tcx>,
794                       a: T,
795                       b: T)
796                       -> UnitResult<'tcx>
797         where T: at::ToTrace<'tcx>
798     {
799         let origin = &ObligationCause::dummy();
800         self.probe(|_| {
801             self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| {
802                 // Ignore obligations, since we are unrolling
803                 // everything anyway.
804             })
805         })
806     }
807
808     pub fn sub_regions(&self,
809                        origin: SubregionOrigin<'tcx>,
810                        a: ty::Region<'tcx>,
811                        b: ty::Region<'tcx>) {
812         debug!("sub_regions({:?} <: {:?})", a, b);
813         self.borrow_region_constraints().make_subregion(origin, a, b);
814     }
815
816     pub fn subtype_predicate(&self,
817                              cause: &ObligationCause<'tcx>,
818                              param_env: ty::ParamEnv<'tcx>,
819                              predicate: &ty::PolySubtypePredicate<'tcx>)
820         -> Option<InferResult<'tcx, ()>>
821     {
822         // Subtle: it's ok to skip the binder here and resolve because
823         // `shallow_resolve` just ignores anything that is not a type
824         // variable, and because type variable's can't (at present, at
825         // least) capture any of the things bound by this binder.
826         //
827         // Really, there is no *particular* reason to do this
828         // `shallow_resolve` here except as a
829         // micro-optimization. Naturally I could not
830         // resist. -nmatsakis
831         let two_unbound_type_vars = {
832             let a = self.shallow_resolve(predicate.skip_binder().a);
833             let b = self.shallow_resolve(predicate.skip_binder().b);
834             a.is_ty_var() && b.is_ty_var()
835         };
836
837         if two_unbound_type_vars {
838             // Two unbound type variables? Can't make progress.
839             return None;
840         }
841
842         Some(self.commit_if_ok(|snapshot| {
843             let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
844                 self.skolemize_late_bound_regions(predicate);
845
846             let cause_span = cause.span;
847             let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
848             self.leak_check(false, cause_span, &skol_map, snapshot)?;
849             self.pop_skolemized(skol_map, snapshot);
850             Ok(ok.unit())
851         }))
852     }
853
854     pub fn region_outlives_predicate(&self,
855                                      cause: &traits::ObligationCause<'tcx>,
856                                      predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
857         -> UnitResult<'tcx>
858     {
859         self.commit_if_ok(|snapshot| {
860             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
861                 self.skolemize_late_bound_regions(predicate);
862             let origin =
863                 SubregionOrigin::from_obligation_cause(cause,
864                                                        || RelateRegionParamBound(cause.span));
865             self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
866             self.leak_check(false, cause.span, &skol_map, snapshot)?;
867             Ok(self.pop_skolemized(skol_map, snapshot))
868         })
869     }
870
871     pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
872         self.type_variables
873             .borrow_mut()
874             .new_var(self.universe(), diverging, origin)
875     }
876
877     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
878         self.tcx.mk_var(self.next_ty_var_id(false, origin))
879     }
880
881     pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
882         self.tcx.mk_var(self.next_ty_var_id(true, origin))
883     }
884
885     pub fn next_int_var_id(&self) -> IntVid {
886         self.int_unification_table
887             .borrow_mut()
888             .new_key(None)
889     }
890
891     pub fn next_float_var_id(&self) -> FloatVid {
892         self.float_unification_table
893             .borrow_mut()
894             .new_key(None)
895     }
896
897     /// Create a fresh region variable with the next available index.
898     ///
899     /// # Parameters
900     ///
901     /// - `origin`: information about why we created this variable, for use
902     ///   during diagnostics / error-reporting.
903     pub fn next_region_var(&self, origin: RegionVariableOrigin)
904                            -> ty::Region<'tcx> {
905         let region_var = self.borrow_region_constraints()
906             .new_region_var(self.universe(), origin);
907         self.tcx.mk_region(ty::ReVar(region_var))
908     }
909
910     /// Number of region variables created so far.
911     pub fn num_region_vars(&self) -> usize {
912         self.borrow_region_constraints().num_region_vars()
913     }
914
915     /// Just a convenient wrapper of `next_region_var` for using during NLL.
916     pub fn next_nll_region_var(&self, origin: NLLRegionVariableOrigin)
917                                -> ty::Region<'tcx> {
918         self.next_region_var(RegionVariableOrigin::NLL(origin))
919     }
920
921     pub fn var_for_def(&self,
922                        span: Span,
923                        param: &ty::GenericParamDef)
924                        -> Kind<'tcx> {
925         match param.kind {
926             GenericParamDefKind::Lifetime => {
927                 // Create a region inference variable for the given
928                 // region parameter definition.
929                 self.next_region_var(EarlyBoundRegion(span, param.name)).into()
930             }
931             GenericParamDefKind::Type {..} => {
932                 // Create a type inference variable for the given
933                 // type parameter definition. The substitutions are
934                 // for actual parameters that may be referred to by
935                 // the default of this type parameter, if it exists.
936                 // E.g. `struct Foo<A, B, C = (A, B)>(...);` when
937                 // used in a path such as `Foo::<T, U>::new()` will
938                 // use an inference variable for `C` with `[T, U]`
939                 // as the substitutions for the default, `(T, U)`.
940                 let ty_var_id =
941                     self.type_variables
942                         .borrow_mut()
943                         .new_var(self.universe(),
944                                     false,
945                                     TypeVariableOrigin::TypeParameterDefinition(span, param.name));
946
947                 self.tcx.mk_var(ty_var_id).into()
948             }
949         }
950     }
951
952     /// Given a set of generics defined on a type or impl, returns a substitution mapping each
953     /// type/region parameter to a fresh inference variable.
954     pub fn fresh_substs_for_item(&self,
955                                  span: Span,
956                                  def_id: DefId)
957                                  -> &'tcx Substs<'tcx> {
958         Substs::for_item(self.tcx, def_id, |param, _| {
959             self.var_for_def(span, param)
960         })
961     }
962
963     /// True if errors have been reported since this infcx was
964     /// created.  This is sometimes used as a heuristic to skip
965     /// reporting errors that often occur as a result of earlier
966     /// errors, but where it's hard to be 100% sure (e.g., unresolved
967     /// inference variables, regionck errors).
968     pub fn is_tainted_by_errors(&self) -> bool {
969         debug!("is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
970                 tainted_by_errors_flag={})",
971                self.tcx.sess.err_count(),
972                self.err_count_on_creation,
973                self.tainted_by_errors_flag.get());
974
975         if self.tcx.sess.err_count() > self.err_count_on_creation {
976             return true; // errors reported since this infcx was made
977         }
978         self.tainted_by_errors_flag.get()
979     }
980
981     /// Set the "tainted by errors" flag to true. We call this when we
982     /// observe an error from a prior pass.
983     pub fn set_tainted_by_errors(&self) {
984         debug!("set_tainted_by_errors()");
985         self.tainted_by_errors_flag.set(true)
986     }
987
988     /// Process the region constraints and report any errors that
989     /// result. After this, no more unification operations should be
990     /// done -- or the compiler will panic -- but it is legal to use
991     /// `resolve_type_vars_if_possible` as well as `fully_resolve`.
992     pub fn resolve_regions_and_report_errors(
993         &self,
994         region_context: DefId,
995         region_map: &region::ScopeTree,
996         outlives_env: &OutlivesEnvironment<'tcx>,
997     ) {
998         self.resolve_regions_and_report_errors_inner(
999             region_context,
1000             region_map,
1001             outlives_env,
1002             false,
1003         )
1004     }
1005
1006     /// Like `resolve_regions_and_report_errors`, but skips error
1007     /// reporting if NLL is enabled.  This is used for fn bodies where
1008     /// the same error may later be reported by the NLL-based
1009     /// inference.
1010     pub fn resolve_regions_and_report_errors_unless_nll(
1011         &self,
1012         region_context: DefId,
1013         region_map: &region::ScopeTree,
1014         outlives_env: &OutlivesEnvironment<'tcx>,
1015     ) {
1016         self.resolve_regions_and_report_errors_inner(
1017             region_context,
1018             region_map,
1019             outlives_env,
1020             true,
1021         )
1022     }
1023
1024     fn resolve_regions_and_report_errors_inner(
1025         &self,
1026         region_context: DefId,
1027         region_map: &region::ScopeTree,
1028         outlives_env: &OutlivesEnvironment<'tcx>,
1029         will_later_be_reported_by_nll: bool,
1030     ) {
1031         assert!(self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
1032                 "region_obligations not empty: {:#?}",
1033                 self.region_obligations.borrow());
1034
1035         let region_rels = &RegionRelations::new(self.tcx,
1036                                                 region_context,
1037                                                 region_map,
1038                                                 outlives_env.free_region_map());
1039         let (var_infos, data) = self.region_constraints.borrow_mut()
1040                                                          .take()
1041                                                          .expect("regions already resolved")
1042                                                          .into_infos_and_data();
1043         let (lexical_region_resolutions, errors) =
1044             lexical_region_resolve::resolve(region_rels, var_infos, data);
1045
1046         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
1047         assert!(old_value.is_none());
1048
1049         if !self.is_tainted_by_errors() {
1050             // As a heuristic, just skip reporting region errors
1051             // altogether if other errors have been reported while
1052             // this infcx was in use.  This is totally hokey but
1053             // otherwise we have a hard time separating legit region
1054             // errors from silly ones.
1055             self.report_region_errors(region_map, &errors, will_later_be_reported_by_nll);
1056         }
1057     }
1058
1059     /// Obtains (and clears) the current set of region
1060     /// constraints. The inference context is still usable: further
1061     /// unifications will simply add new constraints.
1062     ///
1063     /// This method is not meant to be used with normal lexical region
1064     /// resolution. Rather, it is used in the NLL mode as a kind of
1065     /// interim hack: basically we run normal type-check and generate
1066     /// region constraints as normal, but then we take them and
1067     /// translate them into the form that the NLL solver
1068     /// understands. See the NLL module for mode details.
1069     pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> {
1070         assert!(self.region_obligations.borrow().is_empty(),
1071                 "region_obligations not empty: {:#?}",
1072                 self.region_obligations.borrow());
1073
1074         self.borrow_region_constraints().take_and_reset_data()
1075     }
1076
1077     /// Gives temporary access to the region constraint data.
1078     #[allow(non_camel_case_types)] // bug with impl trait
1079     pub fn with_region_constraints<R>(
1080         &self,
1081         op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
1082     ) -> R {
1083         let region_constraints = self.borrow_region_constraints();
1084         op(region_constraints.data())
1085     }
1086
1087     /// Takes ownership of the list of variable regions. This implies
1088     /// that all the region constriants have already been taken, and
1089     /// hence that `resolve_regions_and_report_errors` can never be
1090     /// called. This is used only during NLL processing to "hand off" ownership
1091     /// of the set of region vairables into the NLL region context.
1092     pub fn take_region_var_origins(&self) -> VarInfos {
1093         let (var_infos, data) = self.region_constraints.borrow_mut()
1094                                                          .take()
1095                                                          .expect("regions already resolved")
1096                                                          .into_infos_and_data();
1097         assert!(data.is_empty());
1098         var_infos
1099     }
1100
1101     pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
1102         self.resolve_type_vars_if_possible(&t).to_string()
1103     }
1104
1105     pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
1106         let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
1107         format!("({})", tstrs.join(", "))
1108     }
1109
1110     pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
1111         self.resolve_type_vars_if_possible(t).to_string()
1112     }
1113
1114     pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1115         match typ.sty {
1116             ty::TyInfer(ty::TyVar(v)) => {
1117                 // Not entirely obvious: if `typ` is a type variable,
1118                 // it can be resolved to an int/float variable, which
1119                 // can then be recursively resolved, hence the
1120                 // recursion. Note though that we prevent type
1121                 // variables from unifyxing to other type variables
1122                 // directly (though they may be embedded
1123                 // structurally), and we prevent cycles in any case,
1124                 // so this recursion should always be of very limited
1125                 // depth.
1126                 self.type_variables.borrow_mut()
1127                                    .probe(v)
1128                                    .known()
1129                                    .map(|t| self.shallow_resolve(t))
1130                                    .unwrap_or(typ)
1131             }
1132
1133             ty::TyInfer(ty::IntVar(v)) => {
1134                 self.int_unification_table
1135                     .borrow_mut()
1136                     .probe_value(v)
1137                     .map(|v| v.to_type(self.tcx))
1138                     .unwrap_or(typ)
1139             }
1140
1141             ty::TyInfer(ty::FloatVar(v)) => {
1142                 self.float_unification_table
1143                     .borrow_mut()
1144                     .probe_value(v)
1145                     .map(|v| v.to_type(self.tcx))
1146                     .unwrap_or(typ)
1147             }
1148
1149             _ => {
1150                 typ
1151             }
1152         }
1153     }
1154
1155     pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
1156         where T: TypeFoldable<'tcx>
1157     {
1158         /*!
1159          * Where possible, replaces type/int/float variables in
1160          * `value` with their final value. Note that region variables
1161          * are unaffected. If a type variable has not been unified, it
1162          * is left as is.  This is an idempotent operation that does
1163          * not affect inference state in any way and so you can do it
1164          * at will.
1165          */
1166
1167         if !value.needs_infer() {
1168             return value.clone(); // avoid duplicated subst-folding
1169         }
1170         let mut r = resolve::OpportunisticTypeResolver::new(self);
1171         value.fold_with(&mut r)
1172     }
1173
1174     /// Returns true if `T` contains unresolved type variables. In the
1175     /// process of visiting `T`, this will resolve (where possible)
1176     /// type variables in `T`, but it never constructs the final,
1177     /// resolved type, so it's more efficient than
1178     /// `resolve_type_vars_if_possible()`.
1179     pub fn any_unresolved_type_vars<T>(&self, value: &T) -> bool
1180         where T: TypeFoldable<'tcx>
1181     {
1182         let mut r = resolve::UnresolvedTypeFinder::new(self);
1183         value.visit_with(&mut r)
1184     }
1185
1186     pub fn resolve_type_and_region_vars_if_possible<T>(&self, value: &T) -> T
1187         where T: TypeFoldable<'tcx>
1188     {
1189         let mut r = resolve::OpportunisticTypeAndRegionResolver::new(self);
1190         value.fold_with(&mut r)
1191     }
1192
1193     pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
1194         /*!
1195          * Attempts to resolve all type/region variables in
1196          * `value`. Region inference must have been run already (e.g.,
1197          * by calling `resolve_regions_and_report_errors`).  If some
1198          * variable was never unified, an `Err` results.
1199          *
1200          * This method is idempotent, but it not typically not invoked
1201          * except during the writeback phase.
1202          */
1203
1204         resolve::fully_resolve(self, value)
1205     }
1206
1207     // [Note-Type-error-reporting]
1208     // An invariant is that anytime the expected or actual type is TyError (the special
1209     // error type, meaning that an error occurred when typechecking this expression),
1210     // this is a derived error. The error cascaded from another error (that was already
1211     // reported), so it's not useful to display it to the user.
1212     // The following methods implement this logic.
1213     // They check if either the actual or expected type is TyError, and don't print the error
1214     // in this case. The typechecker should only ever report type errors involving mismatched
1215     // types using one of these methods, and should not call span_err directly for such
1216     // errors.
1217
1218     pub fn type_error_struct_with_diag<M>(&self,
1219                                           sp: Span,
1220                                           mk_diag: M,
1221                                           actual_ty: Ty<'tcx>)
1222                                           -> DiagnosticBuilder<'tcx>
1223         where M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
1224     {
1225         let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
1226         debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
1227
1228         // Don't report an error if actual type is TyError.
1229         if actual_ty.references_error() {
1230             return self.tcx.sess.diagnostic().struct_dummy();
1231         }
1232
1233         mk_diag(self.ty_to_string(actual_ty))
1234     }
1235
1236     pub fn report_mismatched_types(&self,
1237                                    cause: &ObligationCause<'tcx>,
1238                                    expected: Ty<'tcx>,
1239                                    actual: Ty<'tcx>,
1240                                    err: TypeError<'tcx>)
1241                                    -> DiagnosticBuilder<'tcx> {
1242         let trace = TypeTrace::types(cause, true, expected, actual);
1243         self.report_and_explain_type_error(trace, &err)
1244     }
1245
1246     pub fn replace_late_bound_regions_with_fresh_var<T>(
1247         &self,
1248         span: Span,
1249         lbrct: LateBoundRegionConversionTime,
1250         value: &ty::Binder<T>)
1251         -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
1252         where T : TypeFoldable<'tcx>
1253     {
1254         self.tcx.replace_late_bound_regions(
1255             value,
1256             |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1257     }
1258
1259     /// Given a higher-ranked projection predicate like:
1260     ///
1261     ///     for<'a> <T as Fn<&'a u32>>::Output = &'a u32
1262     ///
1263     /// and a target trait-ref like:
1264     ///
1265     ///     <T as Fn<&'x u32>>
1266     ///
1267     /// find a substitution `S` for the higher-ranked regions (here,
1268     /// `['a => 'x]`) such that the predicate matches the trait-ref,
1269     /// and then return the value (here, `&'a u32`) but with the
1270     /// substitution applied (hence, `&'x u32`).
1271     ///
1272     /// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
1273     /// details.
1274     pub fn match_poly_projection_predicate(&self,
1275                                            cause: ObligationCause<'tcx>,
1276                                            param_env: ty::ParamEnv<'tcx>,
1277                                            match_a: ty::PolyProjectionPredicate<'tcx>,
1278                                            match_b: ty::TraitRef<'tcx>)
1279                                            -> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
1280     {
1281         let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
1282         let trace = TypeTrace {
1283             cause,
1284             values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
1285         };
1286
1287         let mut combine = self.combine_fields(trace, param_env);
1288         let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
1289         Ok(InferOk { value: result, obligations: combine.obligations })
1290     }
1291
1292     /// See `verify_generic_bound` method in `region_constraints`
1293     pub fn verify_generic_bound(&self,
1294                                 origin: SubregionOrigin<'tcx>,
1295                                 kind: GenericKind<'tcx>,
1296                                 a: ty::Region<'tcx>,
1297                                 bound: VerifyBound<'tcx>) {
1298         debug!("verify_generic_bound({:?}, {:?} <: {:?})",
1299                kind,
1300                a,
1301                bound);
1302
1303         self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound);
1304     }
1305
1306     pub fn type_moves_by_default(&self,
1307                                  param_env: ty::ParamEnv<'tcx>,
1308                                  ty: Ty<'tcx>,
1309                                  span: Span)
1310                                  -> bool {
1311         let ty = self.resolve_type_vars_if_possible(&ty);
1312         // Even if the type may have no inference variables, during
1313         // type-checking closure types are in local tables only.
1314         if !self.in_progress_tables.is_some() || !ty.has_closure_types() {
1315             if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
1316                 return ty.moves_by_default(self.tcx.global_tcx(), param_env, span);
1317             }
1318         }
1319
1320         let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
1321
1322         // this can get called from typeck (by euv), and moves_by_default
1323         // rightly refuses to work with inference variables, but
1324         // moves_by_default has a cache, which we want to use in other
1325         // cases.
1326         !traits::type_known_to_meet_bound(self, param_env, ty, copy_def_id, span)
1327     }
1328
1329     /// Obtains the latest type of the given closure; this may be a
1330     /// closure in the current function, in which case its
1331     /// `ClosureKind` may not yet be known.
1332     pub fn closure_kind(&self,
1333                         closure_def_id: DefId,
1334                         closure_substs: ty::ClosureSubsts<'tcx>)
1335                         -> Option<ty::ClosureKind>
1336     {
1337         let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
1338         let closure_kind_ty = self.shallow_resolve(&closure_kind_ty);
1339         closure_kind_ty.to_opt_closure_kind()
1340     }
1341
1342     /// Obtain the signature of a closure.  For closures, unlike
1343     /// `tcx.fn_sig(def_id)`, this method will work during the
1344     /// type-checking of the enclosing function and return the closure
1345     /// signature in its partially inferred state.
1346     pub fn closure_sig(
1347         &self,
1348         def_id: DefId,
1349         substs: ty::ClosureSubsts<'tcx>
1350     ) -> ty::PolyFnSig<'tcx> {
1351         let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
1352         let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
1353         closure_sig_ty.fn_sig(self.tcx)
1354     }
1355
1356     /// Normalizes associated types in `value`, potentially returning
1357     /// new obligations that must further be processed.
1358     pub fn partially_normalize_associated_types_in<T>(&self,
1359                                                       span: Span,
1360                                                       body_id: ast::NodeId,
1361                                                       param_env: ty::ParamEnv<'tcx>,
1362                                                       value: &T)
1363                                                       -> InferOk<'tcx, T>
1364         where T : TypeFoldable<'tcx>
1365     {
1366         debug!("partially_normalize_associated_types_in(value={:?})", value);
1367         let mut selcx = traits::SelectionContext::new(self);
1368         let cause = ObligationCause::misc(span, body_id);
1369         let traits::Normalized { value, obligations } =
1370             traits::normalize(&mut selcx, param_env, cause, value);
1371         debug!("partially_normalize_associated_types_in: result={:?} predicates={:?}",
1372             value,
1373             obligations);
1374         InferOk { value, obligations }
1375     }
1376
1377     pub fn borrow_region_constraints(&self) -> RefMut<'_, RegionConstraintCollector<'tcx>> {
1378         RefMut::map(
1379             self.region_constraints.borrow_mut(),
1380             |c| c.as_mut().expect("region constraints already solved"))
1381     }
1382
1383     /// Clears the selection, evaluation, and projection cachesThis is useful when
1384     /// repeatedly attemping to select an Obligation while changing only
1385     /// its ParamEnv, since FulfillmentContext doesn't use 'probe'
1386     pub fn clear_caches(&self) {
1387         self.selection_cache.clear();
1388         self.evaluation_cache.clear();
1389         self.projection_cache.borrow_mut().clear();
1390     }
1391
1392     fn universe(&self) -> ty::UniverseIndex {
1393         self.universe.get()
1394     }
1395 }
1396
1397 impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
1398     pub fn span(&self) -> Span {
1399         self.cause.span
1400     }
1401
1402     pub fn types(cause: &ObligationCause<'tcx>,
1403                  a_is_expected: bool,
1404                  a: Ty<'tcx>,
1405                  b: Ty<'tcx>)
1406                  -> TypeTrace<'tcx> {
1407         TypeTrace {
1408             cause: cause.clone(),
1409             values: Types(ExpectedFound::new(a_is_expected, a, b))
1410         }
1411     }
1412
1413     pub fn dummy(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeTrace<'tcx> {
1414         TypeTrace {
1415             cause: ObligationCause::dummy(),
1416             values: Types(ExpectedFound {
1417                 expected: tcx.types.err,
1418                 found: tcx.types.err,
1419             })
1420         }
1421     }
1422 }
1423
1424 impl<'tcx> fmt::Debug for TypeTrace<'tcx> {
1425     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1426         write!(f, "TypeTrace({:?})", self.cause)
1427     }
1428 }
1429
1430 impl<'tcx> SubregionOrigin<'tcx> {
1431     pub fn span(&self) -> Span {
1432         match *self {
1433             Subtype(ref a) => a.span(),
1434             InfStackClosure(a) => a,
1435             InvokeClosure(a) => a,
1436             DerefPointer(a) => a,
1437             FreeVariable(a, _) => a,
1438             IndexSlice(a) => a,
1439             RelateObjectBound(a) => a,
1440             RelateParamBound(a, _) => a,
1441             RelateRegionParamBound(a) => a,
1442             RelateDefaultParamBound(a, _) => a,
1443             Reborrow(a) => a,
1444             ReborrowUpvar(a, _) => a,
1445             DataBorrowed(_, a) => a,
1446             ReferenceOutlivesReferent(_, a) => a,
1447             ParameterInScope(_, a) => a,
1448             ExprTypeIsNotInScope(_, a) => a,
1449             BindingTypeIsNotValidAtDecl(a) => a,
1450             CallRcvr(a) => a,
1451             CallArg(a) => a,
1452             CallReturn(a) => a,
1453             Operand(a) => a,
1454             AddrOf(a) => a,
1455             AutoBorrow(a) => a,
1456             SafeDestructor(a) => a,
1457             CompareImplMethodObligation { span, .. } => span,
1458         }
1459     }
1460
1461     pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>,
1462                                     default: F)
1463                                     -> Self
1464         where F: FnOnce() -> Self
1465     {
1466         match cause.code {
1467             traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) =>
1468                 SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span),
1469
1470             traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
1471                                                                        impl_item_def_id,
1472                                                                        trait_item_def_id, } =>
1473                 SubregionOrigin::CompareImplMethodObligation {
1474                     span: cause.span,
1475                     item_name,
1476                     impl_item_def_id,
1477                     trait_item_def_id,
1478                 },
1479
1480             _ => default(),
1481         }
1482     }
1483 }
1484
1485 impl RegionVariableOrigin {
1486     pub fn span(&self) -> Span {
1487         match *self {
1488             MiscVariable(a) => a,
1489             PatternRegion(a) => a,
1490             AddrOfRegion(a) => a,
1491             Autoref(a) => a,
1492             Coercion(a) => a,
1493             EarlyBoundRegion(a, ..) => a,
1494             LateBoundRegion(a, ..) => a,
1495             BoundRegionInCoherence(_) => syntax_pos::DUMMY_SP,
1496             UpvarRegion(_, a) => a,
1497             NLL(..) => bug!("NLL variable used with `span`"),
1498         }
1499     }
1500 }
1501
1502 EnumTypeFoldableImpl! {
1503     impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
1504         (ValuePairs::Types)(a),
1505         (ValuePairs::Regions)(a),
1506         (ValuePairs::TraitRefs)(a),
1507         (ValuePairs::PolyTraitRefs)(a),
1508     }
1509 }
1510
1511 impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
1512     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1513         write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
1514                self.sub_region,
1515                self.sup_type)
1516     }
1517 }