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