]> git.lizzy.rs Git - rust.git/blob - src/librustc/infer/mod.rs
Auto merge of #50710 - Zoxc:value_to_constvalue, r=oli-obk
[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};
31 use rustc_data_structures::lazy_btree_map::LazyBTreeMap;
32 use rustc_data_structures::unify as ut;
33 use std::cell::{Cell, RefCell, Ref, RefMut};
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> = LazyBTreeMap<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
490 impl<'tcx> InferOk<'tcx, ()> {
491     pub fn into_obligations(self) -> PredicateObligations<'tcx> {
492         self.obligations
493     }
494 }
495
496 #[must_use = "once you start a snapshot, you should always consume it"]
497 pub struct CombinedSnapshot<'a, 'tcx:'a> {
498     projection_cache_snapshot: traits::ProjectionCacheSnapshot,
499     type_snapshot: type_variable::Snapshot<'tcx>,
500     int_snapshot: ut::Snapshot<ut::InPlace<ty::IntVid>>,
501     float_snapshot: ut::Snapshot<ut::InPlace<ty::FloatVid>>,
502     region_constraints_snapshot: RegionSnapshot,
503     region_obligations_snapshot: usize,
504     universe: ty::UniverseIndex,
505     was_in_snapshot: bool,
506     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
507 }
508
509 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
510     pub fn is_in_snapshot(&self) -> bool {
511         self.in_snapshot.get()
512     }
513
514     pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
515         t.fold_with(&mut self.freshener())
516     }
517
518     pub fn type_var_diverges(&'a self, ty: Ty) -> bool {
519         match ty.sty {
520             ty::TyInfer(ty::TyVar(vid)) => self.type_variables.borrow().var_diverges(vid),
521             _ => false
522         }
523     }
524
525     pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'gcx, 'tcx> {
526         freshen::TypeFreshener::new(self)
527     }
528
529     pub fn type_is_unconstrained_numeric(&'a self, ty: Ty) -> UnconstrainedNumeric {
530         use ty::error::UnconstrainedNumeric::Neither;
531         use ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
532         match ty.sty {
533             ty::TyInfer(ty::IntVar(vid)) => {
534                 if self.int_unification_table.borrow_mut().probe_value(vid).is_some() {
535                     Neither
536                 } else {
537                     UnconstrainedInt
538                 }
539             },
540             ty::TyInfer(ty::FloatVar(vid)) => {
541                 if self.float_unification_table.borrow_mut().probe_value(vid).is_some() {
542                     Neither
543                 } else {
544                     UnconstrainedFloat
545                 }
546             },
547             _ => Neither,
548         }
549     }
550
551     pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
552         let mut variables = Vec::new();
553
554         {
555             let mut type_variables = self.type_variables.borrow_mut();
556             variables.extend(
557                 type_variables
558                     .unsolved_variables()
559                     .into_iter()
560                     .map(|t| self.tcx.mk_var(t)));
561         }
562
563         {
564             let mut int_unification_table = self.int_unification_table.borrow_mut();
565             variables.extend(
566                 (0..int_unification_table.len())
567                     .map(|i| ty::IntVid { index: i as u32 })
568                     .filter(|&vid| int_unification_table.probe_value(vid).is_none())
569                     .map(|v| self.tcx.mk_int_var(v)));
570         }
571
572         {
573             let mut float_unification_table = self.float_unification_table.borrow_mut();
574             variables.extend(
575                 (0..float_unification_table.len())
576                     .map(|i| ty::FloatVid { index: i as u32 })
577                     .filter(|&vid| float_unification_table.probe_value(vid).is_none())
578                     .map(|v| self.tcx.mk_float_var(v)));
579         }
580
581         return variables;
582     }
583
584     fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)
585                       -> CombineFields<'a, 'gcx, 'tcx> {
586         CombineFields {
587             infcx: self,
588             trace,
589             cause: None,
590             param_env,
591             obligations: PredicateObligations::new(),
592         }
593     }
594
595     // Clear the "currently in a snapshot" flag, invoke the closure,
596     // then restore the flag to its original value. This flag is a
597     // debugging measure designed to detect cases where we start a
598     // snapshot, create type variables, and register obligations
599     // which may involve those type variables in the fulfillment cx,
600     // potentially leaving "dangling type variables" behind.
601     // In such cases, an assertion will fail when attempting to
602     // register obligations, within a snapshot. Very useful, much
603     // better than grovelling through megabytes of RUST_LOG output.
604     //
605     // HOWEVER, in some cases the flag is unhelpful. In particular, we
606     // sometimes create a "mini-fulfilment-cx" in which we enroll
607     // obligations. As long as this fulfillment cx is fully drained
608     // before we return, this is not a problem, as there won't be any
609     // escaping obligations in the main cx. In those cases, you can
610     // use this function.
611     pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
612         where F: FnOnce(&Self) -> R
613     {
614         let flag = self.in_snapshot.get();
615         self.in_snapshot.set(false);
616         let result = func(self);
617         self.in_snapshot.set(flag);
618         result
619     }
620
621     fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> {
622         debug!("start_snapshot()");
623
624         let in_snapshot = self.in_snapshot.get();
625         self.in_snapshot.set(true);
626
627         CombinedSnapshot {
628             projection_cache_snapshot: self.projection_cache.borrow_mut().snapshot(),
629             type_snapshot: self.type_variables.borrow_mut().snapshot(),
630             int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
631             float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
632             region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
633             region_obligations_snapshot: self.region_obligations.borrow().len(),
634             universe: self.universe(),
635             was_in_snapshot: in_snapshot,
636             // Borrow tables "in progress" (i.e. during typeck)
637             // to ban writes from within a snapshot to them.
638             _in_progress_tables: self.in_progress_tables.map(|tables| {
639                 tables.borrow()
640             })
641         }
642     }
643
644     fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) {
645         debug!("rollback_to(cause={})", cause);
646         let CombinedSnapshot { projection_cache_snapshot,
647                                type_snapshot,
648                                int_snapshot,
649                                float_snapshot,
650                                region_constraints_snapshot,
651                                region_obligations_snapshot,
652                                universe,
653                                was_in_snapshot,
654                                _in_progress_tables } = snapshot;
655
656         self.in_snapshot.set(was_in_snapshot);
657         self.universe.set(universe);
658
659         self.projection_cache
660             .borrow_mut()
661             .rollback_to(projection_cache_snapshot);
662         self.type_variables
663             .borrow_mut()
664             .rollback_to(type_snapshot);
665         self.int_unification_table
666             .borrow_mut()
667             .rollback_to(int_snapshot);
668         self.float_unification_table
669             .borrow_mut()
670             .rollback_to(float_snapshot);
671         self.region_obligations
672             .borrow_mut()
673             .truncate(region_obligations_snapshot);
674         self.borrow_region_constraints()
675             .rollback_to(region_constraints_snapshot);
676     }
677
678     fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
679         debug!("commit_from()");
680         let CombinedSnapshot { projection_cache_snapshot,
681                                type_snapshot,
682                                int_snapshot,
683                                float_snapshot,
684                                region_constraints_snapshot,
685                                region_obligations_snapshot: _,
686                                universe: _,
687                                was_in_snapshot,
688                                _in_progress_tables } = snapshot;
689
690         self.in_snapshot.set(was_in_snapshot);
691
692         self.projection_cache
693             .borrow_mut()
694             .commit(projection_cache_snapshot);
695         self.type_variables
696             .borrow_mut()
697             .commit(type_snapshot);
698         self.int_unification_table
699             .borrow_mut()
700             .commit(int_snapshot);
701         self.float_unification_table
702             .borrow_mut()
703             .commit(float_snapshot);
704         self.borrow_region_constraints()
705             .commit(region_constraints_snapshot);
706     }
707
708     /// Execute `f` and commit the bindings
709     pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
710         F: FnOnce() -> R,
711     {
712         debug!("commit()");
713         let snapshot = self.start_snapshot();
714         let r = f();
715         self.commit_from(snapshot);
716         r
717     }
718
719     /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`
720     pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
721         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>
722     {
723         debug!("commit_if_ok()");
724         let snapshot = self.start_snapshot();
725         let r = f(&snapshot);
726         debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
727         match r {
728             Ok(_) => { self.commit_from(snapshot); }
729             Err(_) => { self.rollback_to("commit_if_ok -- error", snapshot); }
730         }
731         r
732     }
733
734     // Execute `f` in a snapshot, and commit the bindings it creates
735     pub fn in_snapshot<T, F>(&self, f: F) -> T where
736         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T
737     {
738         debug!("in_snapshot()");
739         let snapshot = self.start_snapshot();
740         let r = f(&snapshot);
741         self.commit_from(snapshot);
742         r
743     }
744
745     /// Execute `f` then unroll any bindings it creates
746     pub fn probe<R, F>(&self, f: F) -> R where
747         F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
748     {
749         debug!("probe()");
750         let snapshot = self.start_snapshot();
751         let r = f(&snapshot);
752         self.rollback_to("probe", snapshot);
753         r
754     }
755
756     pub fn add_given(&self,
757                      sub: ty::Region<'tcx>,
758                      sup: ty::RegionVid)
759     {
760         self.borrow_region_constraints().add_given(sub, sup);
761     }
762
763     pub fn can_sub<T>(&self,
764                       param_env: ty::ParamEnv<'tcx>,
765                       a: T,
766                       b: T)
767                       -> UnitResult<'tcx>
768         where T: at::ToTrace<'tcx>
769     {
770         let origin = &ObligationCause::dummy();
771         self.probe(|_| {
772             self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| {
773                 // Ignore obligations, since we are unrolling
774                 // everything anyway.
775             })
776         })
777     }
778
779     pub fn can_eq<T>(&self,
780                       param_env: ty::ParamEnv<'tcx>,
781                       a: T,
782                       b: T)
783                       -> UnitResult<'tcx>
784         where T: at::ToTrace<'tcx>
785     {
786         let origin = &ObligationCause::dummy();
787         self.probe(|_| {
788             self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| {
789                 // Ignore obligations, since we are unrolling
790                 // everything anyway.
791             })
792         })
793     }
794
795     pub fn sub_regions(&self,
796                        origin: SubregionOrigin<'tcx>,
797                        a: ty::Region<'tcx>,
798                        b: ty::Region<'tcx>) {
799         debug!("sub_regions({:?} <: {:?})", a, b);
800         self.borrow_region_constraints().make_subregion(origin, a, b);
801     }
802
803     pub fn subtype_predicate(&self,
804                              cause: &ObligationCause<'tcx>,
805                              param_env: ty::ParamEnv<'tcx>,
806                              predicate: &ty::PolySubtypePredicate<'tcx>)
807         -> Option<InferResult<'tcx, ()>>
808     {
809         // Subtle: it's ok to skip the binder here and resolve because
810         // `shallow_resolve` just ignores anything that is not a type
811         // variable, and because type variable's can't (at present, at
812         // least) capture any of the things bound by this binder.
813         //
814         // Really, there is no *particular* reason to do this
815         // `shallow_resolve` here except as a
816         // micro-optimization. Naturally I could not
817         // resist. -nmatsakis
818         let two_unbound_type_vars = {
819             let a = self.shallow_resolve(predicate.skip_binder().a);
820             let b = self.shallow_resolve(predicate.skip_binder().b);
821             a.is_ty_var() && b.is_ty_var()
822         };
823
824         if two_unbound_type_vars {
825             // Two unbound type variables? Can't make progress.
826             return None;
827         }
828
829         Some(self.commit_if_ok(|snapshot| {
830             let (ty::SubtypePredicate { a_is_expected, a, b}, skol_map) =
831                 self.skolemize_late_bound_regions(predicate);
832
833             let cause_span = cause.span;
834             let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
835             self.leak_check(false, cause_span, &skol_map, snapshot)?;
836             self.pop_skolemized(skol_map, snapshot);
837             Ok(ok.unit())
838         }))
839     }
840
841     pub fn region_outlives_predicate(&self,
842                                      cause: &traits::ObligationCause<'tcx>,
843                                      predicate: &ty::PolyRegionOutlivesPredicate<'tcx>)
844         -> UnitResult<'tcx>
845     {
846         self.commit_if_ok(|snapshot| {
847             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
848                 self.skolemize_late_bound_regions(predicate);
849             let origin =
850                 SubregionOrigin::from_obligation_cause(cause,
851                                                        || RelateRegionParamBound(cause.span));
852             self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
853             self.leak_check(false, cause.span, &skol_map, snapshot)?;
854             Ok(self.pop_skolemized(skol_map, snapshot))
855         })
856     }
857
858     pub fn next_ty_var_id(&self, diverging: bool, origin: TypeVariableOrigin) -> TyVid {
859         self.type_variables
860             .borrow_mut()
861             .new_var(self.universe(), diverging, origin)
862     }
863
864     pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
865         self.tcx.mk_var(self.next_ty_var_id(false, origin))
866     }
867
868     pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
869         self.tcx.mk_var(self.next_ty_var_id(true, origin))
870     }
871
872     pub fn next_int_var_id(&self) -> IntVid {
873         self.int_unification_table
874             .borrow_mut()
875             .new_key(None)
876     }
877
878     pub fn next_float_var_id(&self) -> FloatVid {
879         self.float_unification_table
880             .borrow_mut()
881             .new_key(None)
882     }
883
884     /// Create a fresh region variable with the next available index.
885     ///
886     /// # Parameters
887     ///
888     /// - `origin`: information about why we created this variable, for use
889     ///   during diagnostics / error-reporting.
890     pub fn next_region_var(&self, origin: RegionVariableOrigin)
891                            -> ty::Region<'tcx> {
892         let region_var = self.borrow_region_constraints()
893             .new_region_var(self.universe(), origin);
894         self.tcx.mk_region(ty::ReVar(region_var))
895     }
896
897     /// Number of region variables created so far.
898     pub fn num_region_vars(&self) -> usize {
899         self.borrow_region_constraints().num_region_vars()
900     }
901
902     /// Just a convenient wrapper of `next_region_var` for using during NLL.
903     pub fn next_nll_region_var(&self, origin: NLLRegionVariableOrigin)
904                                -> ty::Region<'tcx> {
905         self.next_region_var(RegionVariableOrigin::NLL(origin))
906     }
907
908     pub fn var_for_def(&self,
909                        span: Span,
910                        param: &ty::GenericParamDef)
911                        -> Kind<'tcx> {
912         match param.kind {
913             GenericParamDefKind::Lifetime => {
914                 // Create a region inference variable for the given
915                 // region parameter definition.
916                 self.next_region_var(EarlyBoundRegion(span, param.name)).into()
917             }
918             GenericParamDefKind::Type(_) => {
919                 // Create a type inference variable for the given
920                 // type parameter definition. The substitutions are
921                 // for actual parameters that may be referred to by
922                 // the default of this type parameter, if it exists.
923                 // E.g. `struct Foo<A, B, C = (A, B)>(...);` when
924                 // used in a path such as `Foo::<T, U>::new()` will
925                 // use an inference variable for `C` with `[T, U]`
926                 // as the substitutions for the default, `(T, U)`.
927                 let ty_var_id =
928                     self.type_variables
929                         .borrow_mut()
930                         .new_var(self.universe(),
931                                     false,
932                                     TypeVariableOrigin::TypeParameterDefinition(span, param.name));
933
934                 self.tcx.mk_var(ty_var_id).into()
935             }
936         }
937     }
938
939     /// Given a set of generics defined on a type or impl, returns a substitution mapping each
940     /// type/region parameter to a fresh inference variable.
941     pub fn fresh_substs_for_item(&self,
942                                  span: Span,
943                                  def_id: DefId)
944                                  -> &'tcx Substs<'tcx> {
945         Substs::for_item(self.tcx, def_id, |param, _| {
946             self.var_for_def(span, param)
947         })
948     }
949
950     /// True if errors have been reported since this infcx was
951     /// created.  This is sometimes used as a heuristic to skip
952     /// reporting errors that often occur as a result of earlier
953     /// errors, but where it's hard to be 100% sure (e.g., unresolved
954     /// inference variables, regionck errors).
955     pub fn is_tainted_by_errors(&self) -> bool {
956         debug!("is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
957                 tainted_by_errors_flag={})",
958                self.tcx.sess.err_count(),
959                self.err_count_on_creation,
960                self.tainted_by_errors_flag.get());
961
962         if self.tcx.sess.err_count() > self.err_count_on_creation {
963             return true; // errors reported since this infcx was made
964         }
965         self.tainted_by_errors_flag.get()
966     }
967
968     /// Set the "tainted by errors" flag to true. We call this when we
969     /// observe an error from a prior pass.
970     pub fn set_tainted_by_errors(&self) {
971         debug!("set_tainted_by_errors()");
972         self.tainted_by_errors_flag.set(true)
973     }
974
975     /// Process the region constraints and report any errors that
976     /// result. After this, no more unification operations should be
977     /// done -- or the compiler will panic -- but it is legal to use
978     /// `resolve_type_vars_if_possible` as well as `fully_resolve`.
979     pub fn resolve_regions_and_report_errors(
980         &self,
981         region_context: DefId,
982         region_map: &region::ScopeTree,
983         outlives_env: &OutlivesEnvironment<'tcx>,
984     ) {
985         self.resolve_regions_and_report_errors_inner(
986             region_context,
987             region_map,
988             outlives_env,
989             false,
990         )
991     }
992
993     /// Like `resolve_regions_and_report_errors`, but skips error
994     /// reporting if NLL is enabled.  This is used for fn bodies where
995     /// the same error may later be reported by the NLL-based
996     /// inference.
997     pub fn resolve_regions_and_report_errors_unless_nll(
998         &self,
999         region_context: DefId,
1000         region_map: &region::ScopeTree,
1001         outlives_env: &OutlivesEnvironment<'tcx>,
1002     ) {
1003         self.resolve_regions_and_report_errors_inner(
1004             region_context,
1005             region_map,
1006             outlives_env,
1007             true,
1008         )
1009     }
1010
1011     fn resolve_regions_and_report_errors_inner(
1012         &self,
1013         region_context: DefId,
1014         region_map: &region::ScopeTree,
1015         outlives_env: &OutlivesEnvironment<'tcx>,
1016         will_later_be_reported_by_nll: bool,
1017     ) {
1018         assert!(self.is_tainted_by_errors() || self.region_obligations.borrow().is_empty(),
1019                 "region_obligations not empty: {:#?}",
1020                 self.region_obligations.borrow());
1021
1022         let region_rels = &RegionRelations::new(self.tcx,
1023                                                 region_context,
1024                                                 region_map,
1025                                                 outlives_env.free_region_map());
1026         let (var_infos, data) = self.region_constraints.borrow_mut()
1027                                                          .take()
1028                                                          .expect("regions already resolved")
1029                                                          .into_infos_and_data();
1030         let (lexical_region_resolutions, errors) =
1031             lexical_region_resolve::resolve(region_rels, var_infos, data);
1032
1033         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
1034         assert!(old_value.is_none());
1035
1036         if !self.is_tainted_by_errors() {
1037             // As a heuristic, just skip reporting region errors
1038             // altogether if other errors have been reported while
1039             // this infcx was in use.  This is totally hokey but
1040             // otherwise we have a hard time separating legit region
1041             // errors from silly ones.
1042             self.report_region_errors(region_map, &errors, will_later_be_reported_by_nll);
1043         }
1044     }
1045
1046     /// Obtains (and clears) the current set of region
1047     /// constraints. The inference context is still usable: further
1048     /// unifications will simply add new constraints.
1049     ///
1050     /// This method is not meant to be used with normal lexical region
1051     /// resolution. Rather, it is used in the NLL mode as a kind of
1052     /// interim hack: basically we run normal type-check and generate
1053     /// region constraints as normal, but then we take them and
1054     /// translate them into the form that the NLL solver
1055     /// understands. See the NLL module for mode details.
1056     pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> {
1057         assert!(self.region_obligations.borrow().is_empty(),
1058                 "region_obligations not empty: {:#?}",
1059                 self.region_obligations.borrow());
1060
1061         self.borrow_region_constraints().take_and_reset_data()
1062     }
1063
1064     /// Gives temporary access to the region constraint data.
1065     #[allow(non_camel_case_types)] // bug with impl trait
1066     pub fn with_region_constraints<R>(
1067         &self,
1068         op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
1069     ) -> R {
1070         let region_constraints = self.borrow_region_constraints();
1071         op(region_constraints.data())
1072     }
1073
1074     /// Takes ownership of the list of variable regions. This implies
1075     /// that all the region constriants have already been taken, and
1076     /// hence that `resolve_regions_and_report_errors` can never be
1077     /// called. This is used only during NLL processing to "hand off" ownership
1078     /// of the set of region vairables into the NLL region context.
1079     pub fn take_region_var_origins(&self) -> VarInfos {
1080         let (var_infos, data) = self.region_constraints.borrow_mut()
1081                                                          .take()
1082                                                          .expect("regions already resolved")
1083                                                          .into_infos_and_data();
1084         assert!(data.is_empty());
1085         var_infos
1086     }
1087
1088     pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
1089         self.resolve_type_vars_if_possible(&t).to_string()
1090     }
1091
1092     pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
1093         let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
1094         format!("({})", tstrs.join(", "))
1095     }
1096
1097     pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
1098         self.resolve_type_vars_if_possible(t).to_string()
1099     }
1100
1101     pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
1102         match typ.sty {
1103             ty::TyInfer(ty::TyVar(v)) => {
1104                 // Not entirely obvious: if `typ` is a type variable,
1105                 // it can be resolved to an int/float variable, which
1106                 // can then be recursively resolved, hence the
1107                 // recursion. Note though that we prevent type
1108                 // variables from unifyxing to other type variables
1109                 // directly (though they may be embedded
1110                 // structurally), and we prevent cycles in any case,
1111                 // so this recursion should always be of very limited
1112                 // depth.
1113                 self.type_variables.borrow_mut()
1114                                    .probe(v)
1115                                    .known()
1116                                    .map(|t| self.shallow_resolve(t))
1117                                    .unwrap_or(typ)
1118             }
1119
1120             ty::TyInfer(ty::IntVar(v)) => {
1121                 self.int_unification_table
1122                     .borrow_mut()
1123                     .probe_value(v)
1124                     .map(|v| v.to_type(self.tcx))
1125                     .unwrap_or(typ)
1126             }
1127
1128             ty::TyInfer(ty::FloatVar(v)) => {
1129                 self.float_unification_table
1130                     .borrow_mut()
1131                     .probe_value(v)
1132                     .map(|v| v.to_type(self.tcx))
1133                     .unwrap_or(typ)
1134             }
1135
1136             _ => {
1137                 typ
1138             }
1139         }
1140     }
1141
1142     pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
1143         where T: TypeFoldable<'tcx>
1144     {
1145         /*!
1146          * Where possible, replaces type/int/float variables in
1147          * `value` with their final value. Note that region variables
1148          * are unaffected. If a type variable has not been unified, it
1149          * is left as is.  This is an idempotent operation that does
1150          * not affect inference state in any way and so you can do it
1151          * at will.
1152          */
1153
1154         if !value.needs_infer() {
1155             return value.clone(); // avoid duplicated subst-folding
1156         }
1157         let mut r = resolve::OpportunisticTypeResolver::new(self);
1158         value.fold_with(&mut r)
1159     }
1160
1161     /// Returns true if `T` contains unresolved type variables. In the
1162     /// process of visiting `T`, this will resolve (where possible)
1163     /// type variables in `T`, but it never constructs the final,
1164     /// resolved type, so it's more efficient than
1165     /// `resolve_type_vars_if_possible()`.
1166     pub fn any_unresolved_type_vars<T>(&self, value: &T) -> bool
1167         where T: TypeFoldable<'tcx>
1168     {
1169         let mut r = resolve::UnresolvedTypeFinder::new(self);
1170         value.visit_with(&mut r)
1171     }
1172
1173     pub fn resolve_type_and_region_vars_if_possible<T>(&self, value: &T) -> T
1174         where T: TypeFoldable<'tcx>
1175     {
1176         let mut r = resolve::OpportunisticTypeAndRegionResolver::new(self);
1177         value.fold_with(&mut r)
1178     }
1179
1180     pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
1181         /*!
1182          * Attempts to resolve all type/region variables in
1183          * `value`. Region inference must have been run already (e.g.,
1184          * by calling `resolve_regions_and_report_errors`).  If some
1185          * variable was never unified, an `Err` results.
1186          *
1187          * This method is idempotent, but it not typically not invoked
1188          * except during the writeback phase.
1189          */
1190
1191         resolve::fully_resolve(self, value)
1192     }
1193
1194     // [Note-Type-error-reporting]
1195     // An invariant is that anytime the expected or actual type is TyError (the special
1196     // error type, meaning that an error occurred when typechecking this expression),
1197     // this is a derived error. The error cascaded from another error (that was already
1198     // reported), so it's not useful to display it to the user.
1199     // The following methods implement this logic.
1200     // They check if either the actual or expected type is TyError, and don't print the error
1201     // in this case. The typechecker should only ever report type errors involving mismatched
1202     // types using one of these methods, and should not call span_err directly for such
1203     // errors.
1204
1205     pub fn type_error_struct_with_diag<M>(&self,
1206                                           sp: Span,
1207                                           mk_diag: M,
1208                                           actual_ty: Ty<'tcx>)
1209                                           -> DiagnosticBuilder<'tcx>
1210         where M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
1211     {
1212         let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
1213         debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
1214
1215         // Don't report an error if actual type is TyError.
1216         if actual_ty.references_error() {
1217             return self.tcx.sess.diagnostic().struct_dummy();
1218         }
1219
1220         mk_diag(self.ty_to_string(actual_ty))
1221     }
1222
1223     pub fn report_mismatched_types(&self,
1224                                    cause: &ObligationCause<'tcx>,
1225                                    expected: Ty<'tcx>,
1226                                    actual: Ty<'tcx>,
1227                                    err: TypeError<'tcx>)
1228                                    -> DiagnosticBuilder<'tcx> {
1229         let trace = TypeTrace::types(cause, true, expected, actual);
1230         self.report_and_explain_type_error(trace, &err)
1231     }
1232
1233     pub fn replace_late_bound_regions_with_fresh_var<T>(
1234         &self,
1235         span: Span,
1236         lbrct: LateBoundRegionConversionTime,
1237         value: &ty::Binder<T>)
1238         -> (T, LazyBTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
1239         where T : TypeFoldable<'tcx>
1240     {
1241         self.tcx.replace_late_bound_regions(
1242             value,
1243             |br| self.next_region_var(LateBoundRegion(span, br, lbrct)))
1244     }
1245
1246     /// Given a higher-ranked projection predicate like:
1247     ///
1248     ///     for<'a> <T as Fn<&'a u32>>::Output = &'a u32
1249     ///
1250     /// and a target trait-ref like:
1251     ///
1252     ///     <T as Fn<&'x u32>>
1253     ///
1254     /// find a substitution `S` for the higher-ranked regions (here,
1255     /// `['a => 'x]`) such that the predicate matches the trait-ref,
1256     /// and then return the value (here, `&'a u32`) but with the
1257     /// substitution applied (hence, `&'x u32`).
1258     ///
1259     /// See `higher_ranked_match` in `higher_ranked/mod.rs` for more
1260     /// details.
1261     pub fn match_poly_projection_predicate(&self,
1262                                            cause: ObligationCause<'tcx>,
1263                                            param_env: ty::ParamEnv<'tcx>,
1264                                            match_a: ty::PolyProjectionPredicate<'tcx>,
1265                                            match_b: ty::TraitRef<'tcx>)
1266                                            -> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
1267     {
1268         let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
1269         let trace = TypeTrace {
1270             cause,
1271             values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
1272         };
1273
1274         let mut combine = self.combine_fields(trace, param_env);
1275         let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
1276         Ok(InferOk { value: result, obligations: combine.obligations })
1277     }
1278
1279     /// See `verify_generic_bound` method in `region_constraints`
1280     pub fn verify_generic_bound(&self,
1281                                 origin: SubregionOrigin<'tcx>,
1282                                 kind: GenericKind<'tcx>,
1283                                 a: ty::Region<'tcx>,
1284                                 bound: VerifyBound<'tcx>) {
1285         debug!("verify_generic_bound({:?}, {:?} <: {:?})",
1286                kind,
1287                a,
1288                bound);
1289
1290         self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound);
1291     }
1292
1293     pub fn type_moves_by_default(&self,
1294                                  param_env: ty::ParamEnv<'tcx>,
1295                                  ty: Ty<'tcx>,
1296                                  span: Span)
1297                                  -> bool {
1298         let ty = self.resolve_type_vars_if_possible(&ty);
1299         // Even if the type may have no inference variables, during
1300         // type-checking closure types are in local tables only.
1301         if !self.in_progress_tables.is_some() || !ty.has_closure_types() {
1302             if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
1303                 return ty.moves_by_default(self.tcx.global_tcx(), param_env, span);
1304             }
1305         }
1306
1307         let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
1308
1309         // this can get called from typeck (by euv), and moves_by_default
1310         // rightly refuses to work with inference variables, but
1311         // moves_by_default has a cache, which we want to use in other
1312         // cases.
1313         !traits::type_known_to_meet_bound(self, param_env, ty, copy_def_id, span)
1314     }
1315
1316     /// Obtains the latest type of the given closure; this may be a
1317     /// closure in the current function, in which case its
1318     /// `ClosureKind` may not yet be known.
1319     pub fn closure_kind(&self,
1320                         closure_def_id: DefId,
1321                         closure_substs: ty::ClosureSubsts<'tcx>)
1322                         -> Option<ty::ClosureKind>
1323     {
1324         let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
1325         let closure_kind_ty = self.shallow_resolve(&closure_kind_ty);
1326         closure_kind_ty.to_opt_closure_kind()
1327     }
1328
1329     /// Obtain the signature of a closure.  For closures, unlike
1330     /// `tcx.fn_sig(def_id)`, this method will work during the
1331     /// type-checking of the enclosing function and return the closure
1332     /// signature in its partially inferred state.
1333     pub fn closure_sig(
1334         &self,
1335         def_id: DefId,
1336         substs: ty::ClosureSubsts<'tcx>
1337     ) -> ty::PolyFnSig<'tcx> {
1338         let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
1339         let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
1340         closure_sig_ty.fn_sig(self.tcx)
1341     }
1342
1343     /// Normalizes associated types in `value`, potentially returning
1344     /// new obligations that must further be processed.
1345     pub fn partially_normalize_associated_types_in<T>(&self,
1346                                                       span: Span,
1347                                                       body_id: ast::NodeId,
1348                                                       param_env: ty::ParamEnv<'tcx>,
1349                                                       value: &T)
1350                                                       -> InferOk<'tcx, T>
1351         where T : TypeFoldable<'tcx>
1352     {
1353         debug!("partially_normalize_associated_types_in(value={:?})", value);
1354         let mut selcx = traits::SelectionContext::new(self);
1355         let cause = ObligationCause::misc(span, body_id);
1356         let traits::Normalized { value, obligations } =
1357             traits::normalize(&mut selcx, param_env, cause, value);
1358         debug!("partially_normalize_associated_types_in: result={:?} predicates={:?}",
1359             value,
1360             obligations);
1361         InferOk { value, obligations }
1362     }
1363
1364     pub fn borrow_region_constraints(&self) -> RefMut<'_, RegionConstraintCollector<'tcx>> {
1365         RefMut::map(
1366             self.region_constraints.borrow_mut(),
1367             |c| c.as_mut().expect("region constraints already solved"))
1368     }
1369
1370     /// Clears the selection, evaluation, and projection cachesThis is useful when
1371     /// repeatedly attemping to select an Obligation while changing only
1372     /// its ParamEnv, since FulfillmentContext doesn't use 'probe'
1373     pub fn clear_caches(&self) {
1374         self.selection_cache.clear();
1375         self.evaluation_cache.clear();
1376         self.projection_cache.borrow_mut().clear();
1377     }
1378
1379     fn universe(&self) -> ty::UniverseIndex {
1380         self.universe.get()
1381     }
1382 }
1383
1384 impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {
1385     pub fn span(&self) -> Span {
1386         self.cause.span
1387     }
1388
1389     pub fn types(cause: &ObligationCause<'tcx>,
1390                  a_is_expected: bool,
1391                  a: Ty<'tcx>,
1392                  b: Ty<'tcx>)
1393                  -> TypeTrace<'tcx> {
1394         TypeTrace {
1395             cause: cause.clone(),
1396             values: Types(ExpectedFound::new(a_is_expected, a, b))
1397         }
1398     }
1399
1400     pub fn dummy(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> TypeTrace<'tcx> {
1401         TypeTrace {
1402             cause: ObligationCause::dummy(),
1403             values: Types(ExpectedFound {
1404                 expected: tcx.types.err,
1405                 found: tcx.types.err,
1406             })
1407         }
1408     }
1409 }
1410
1411 impl<'tcx> fmt::Debug for TypeTrace<'tcx> {
1412     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1413         write!(f, "TypeTrace({:?})", self.cause)
1414     }
1415 }
1416
1417 impl<'tcx> SubregionOrigin<'tcx> {
1418     pub fn span(&self) -> Span {
1419         match *self {
1420             Subtype(ref a) => a.span(),
1421             InfStackClosure(a) => a,
1422             InvokeClosure(a) => a,
1423             DerefPointer(a) => a,
1424             FreeVariable(a, _) => a,
1425             IndexSlice(a) => a,
1426             RelateObjectBound(a) => a,
1427             RelateParamBound(a, _) => a,
1428             RelateRegionParamBound(a) => a,
1429             RelateDefaultParamBound(a, _) => a,
1430             Reborrow(a) => a,
1431             ReborrowUpvar(a, _) => a,
1432             DataBorrowed(_, a) => a,
1433             ReferenceOutlivesReferent(_, a) => a,
1434             ParameterInScope(_, a) => a,
1435             ExprTypeIsNotInScope(_, a) => a,
1436             BindingTypeIsNotValidAtDecl(a) => a,
1437             CallRcvr(a) => a,
1438             CallArg(a) => a,
1439             CallReturn(a) => a,
1440             Operand(a) => a,
1441             AddrOf(a) => a,
1442             AutoBorrow(a) => a,
1443             SafeDestructor(a) => a,
1444             CompareImplMethodObligation { span, .. } => span,
1445         }
1446     }
1447
1448     pub fn from_obligation_cause<F>(cause: &traits::ObligationCause<'tcx>,
1449                                     default: F)
1450                                     -> Self
1451         where F: FnOnce() -> Self
1452     {
1453         match cause.code {
1454             traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) =>
1455                 SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span),
1456
1457             traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
1458                                                                        impl_item_def_id,
1459                                                                        trait_item_def_id, } =>
1460                 SubregionOrigin::CompareImplMethodObligation {
1461                     span: cause.span,
1462                     item_name,
1463                     impl_item_def_id,
1464                     trait_item_def_id,
1465                 },
1466
1467             _ => default(),
1468         }
1469     }
1470 }
1471
1472 impl RegionVariableOrigin {
1473     pub fn span(&self) -> Span {
1474         match *self {
1475             MiscVariable(a) => a,
1476             PatternRegion(a) => a,
1477             AddrOfRegion(a) => a,
1478             Autoref(a) => a,
1479             Coercion(a) => a,
1480             EarlyBoundRegion(a, ..) => a,
1481             LateBoundRegion(a, ..) => a,
1482             BoundRegionInCoherence(_) => syntax_pos::DUMMY_SP,
1483             UpvarRegion(_, a) => a,
1484             NLL(..) => bug!("NLL variable used with `span`"),
1485         }
1486     }
1487 }
1488
1489 EnumTypeFoldableImpl! {
1490     impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
1491         (ValuePairs::Types)(a),
1492         (ValuePairs::Regions)(a),
1493         (ValuePairs::TraitRefs)(a),
1494         (ValuePairs::PolyTraitRefs)(a),
1495     }
1496 }
1497
1498 impl<'tcx> fmt::Debug for RegionObligation<'tcx> {
1499     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1500         write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})",
1501                self.sub_region,
1502                self.sup_type)
1503     }
1504 }